Эмуляция для на любой технологии HTML/CSS/JS? [РЕШЕНО]
Пытаюсь сэмулировать заполнитель <input placeholder="..."> для <div contenteditable>.
Первое что приходит в голову: добавить ::before и после фокуса на редактируемом элементе <div ...> удалить содержащий его класс.
Проблема: Попробуйте запустить код и кликнуть на текст "Отредактируйте поле ...", как это делается с обычным <input type=text> - С фокусом все нормально, но текстовый курсор теряется. Предполагаю потому что клик был на ::before. Если же кликнуть в свободном месте(правее), все работает как ожидается - placeholder пропадает и курсор оказывается в поле, после чего можно сразу печатать.
Вопрос: Как достичь желаемого эффекта? Конечно без всяких дополнительных слоев. Может есть какой JS/API/CSS, позволяющий делать элемент ::before не перекрывающим своего родителя?
РЕШЕНО: Первым же комментарием от @Grundy CSS pointer-events: none;
const { createApp, ref } = Vue
const comp = {
setup() {
const showPh = ref(true)
return {
showPh
}
},
template: `
<div
v-bind:class="['edit', {['edit-ph']: showPh}]"
contenteditable="true"
@focus="() => {showPh = false}"
@blur="({target}) => {target.textContent = '';showPh = true}"
></div>
<p>Для сброса надо кликнуть в любом месте.</p>`
}
createApp(comp).mount('#app')
body {
font-family: 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif;
font-size: 24px;
}
.edit {
border: solid 1px rgb(182, 182, 182);
padding: 0.2em;
}
.edit-ph::before {
position: relative;
content: 'Отредактируйте поле ...';
color: rgb(182, 182, 182);
cursor: text;
/* РЕШЕНИЕ */
pointer-events: none;
}
<script src="https://unpkg.com/vue@next"></script>
<div id="app"></div>
Ответы (1 шт):
Автор решения: Grundy
можно выставить pointer-events: none у псевдо элемента, тогда клик по нему будет проигнорирован
const { createApp, ref } = Vue
const comp = {
setup() {
const showPh = ref(true)
return {
showPh
}
},
template: `
<div
v-bind:class="['edit', {['edit-ph']: showPh}]"
contenteditable="true"
@focus="() => {showPh = false}"
@blur="({target}) => {target.textContent = '';showPh = true}"
></div>
<p>Для сброса надо кликнуть в любом месте.</p>`
}
createApp(comp).mount('#app')
body {
font-family: 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif;
font-size: 24px;
}
.edit {
border: solid 1px rgb(182, 182, 182);
padding: 0.2em;
}
.edit-ph::before {
pointer-events: none;
position: relative;
content: 'Отредактируйте поле ...';
color: rgb(182, 182, 182);
cursor: text;
}
<script src="https://unpkg.com/vue@next"></script>
<div id="app"></div>
→ Ссылка
Пытаюсь сэмулировать заполнитель <input placeholder="..."> для <div contenteditable>.
Первое что приходит в голову: добавить ::before и после фокуса на редактируемом элементе <div ...> удалить содержащий его класс.
Проблема: Попробуйте запустить код и кликнуть на текст "Отредактируйте поле ...", как это делается с обычным <input type=text> - С фокусом все нормально, но текстовый курсор теряется. Предполагаю потому что клик был на ::before. Если же кликнуть в свободном месте(правее), все работает как ожидается - placeholder пропадает и курсор оказывается в поле, после чего можно сразу печатать.
Вопрос: Как достичь желаемого эффекта? Конечно без всяких дополнительных слоев. Может есть какой JS/API/CSS, позволяющий делать элемент ::before не перекрывающим своего родителя?
РЕШЕНО: Первым же комментарием от @Grundy CSS pointer-events: none;
const { createApp, ref } = Vue
const comp = {
setup() {
const showPh = ref(true)
return {
showPh
}
},
template: `
<div
v-bind:class="['edit', {['edit-ph']: showPh}]"
contenteditable="true"
@focus="() => {showPh = false}"
@blur="({target}) => {target.textContent = '';showPh = true}"
></div>
<p>Для сброса надо кликнуть в любом месте.</p>`
}
createApp(comp).mount('#app')
body {
font-family: 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif;
font-size: 24px;
}
.edit {
border: solid 1px rgb(182, 182, 182);
padding: 0.2em;
}
.edit-ph::before {
position: relative;
content: 'Отредактируйте поле ...';
color: rgb(182, 182, 182);
cursor: text;
/* РЕШЕНИЕ */
pointer-events: none;
}
<script src="https://unpkg.com/vue@next"></script>
<div id="app"></div>
Ответы (1 шт):
можно выставить pointer-events: none у псевдо элемента, тогда клик по нему будет проигнорирован
const { createApp, ref } = Vue
const comp = {
setup() {
const showPh = ref(true)
return {
showPh
}
},
template: `
<div
v-bind:class="['edit', {['edit-ph']: showPh}]"
contenteditable="true"
@focus="() => {showPh = false}"
@blur="({target}) => {target.textContent = '';showPh = true}"
></div>
<p>Для сброса надо кликнуть в любом месте.</p>`
}
createApp(comp).mount('#app')
body {
font-family: 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif;
font-size: 24px;
}
.edit {
border: solid 1px rgb(182, 182, 182);
padding: 0.2em;
}
.edit-ph::before {
pointer-events: none;
position: relative;
content: 'Отредактируйте поле ...';
color: rgb(182, 182, 182);
cursor: text;
}
<script src="https://unpkg.com/vue@next"></script>
<div id="app"></div>