Заполнитель в проблеме события contenteditable-focus
Я пытался спросить это раньше, без каких-либо успехов в объяснении/доказательстве рабочего примера, где происходит ошибка. Итак, вот еще одна попытка:
Я пытаюсь воспроизвести эффект заполнителя на contenteditable DIV. Основная концепция проста:
<div contenteditable><em>Edit me</em></div>
<script>
$('div').focus(function() {
$(this).empty();
});
</script>
это может работать, но если заполнитель содержит HTML или если выполняется какая-либо другая обработка, текстовый курсор редактируемого DIV удаляется, и пользователь должен повторно щелкнуть редактируемый DIV чтобы начать печатать (даже если он все еще в фокусе):
пример:http://jsfiddle.net/hHLXr/6/
Я не могу использовать триггер фокуса в обработчике, так как он создаст цикл событий. Поэтому мне нужен способ переустановить курсор курсора в редактируемом DIV или каким-то другим способом перефокусировать.
10 ответов
возможно, Вам потребуется вручную обновить выделение. В IE событие фокуса слишком поздно, поэтому я бы предложил использовать событие. Вот некоторый код, который выполняет эту работу во всех основных браузерах, включая IE
Live demo:http://jsfiddle.net/hHLXr/12/
код:
$('div').on('activate', function() {
$(this).empty();
var range, sel;
if ( (sel = document.selection) && document.body.createTextRange) {
range = document.body.createTextRange();
range.moveToElementText(this);
range.select();
}
});
$('div').focus(function() {
if (this.hasChildNodes() && document.createRange && window.getSelection) {
$(this).empty();
var range = document.createRange();
range.selectNodeContents(this);
var sel = window.getSelection();
sel.removeAllRanges();
sel.addRange(range);
}
});
вот решение только CSS, дополняющее некоторые другие ответы: -
<div contentEditable=true data-ph="My Placeholder String"></div>
<style>
[contentEditable=true]:empty:not(:focus)::before{
content:attr(data-ph)
}
</style>
EDIT: вот мой фрагмент на codepen ->http://codepen.io/mrmoje/pen/lkLez
EDIT2: имейте в виду, этот метод не работает 100% для многострочных приложений из-за остаточного <br>
элементы, присутствующие в div после выполнения select-all-cut
или select-all-delete
по всем линиям. Кредиты: - @vsync
Backspace работает нормально (по крайней мере, на webkit/blink)
Я опубликован плагин для этого.
Он использует комбинацию CSS3 и JavaScript для отображения заполнителя без добавления к содержимому div
:
HTML-код:
<div contenteditable='true' data-placeholder='Enter some text'></div>
CSS:
div[data-placeholder]:not(:focus):not([data-div-placeholder-content]):before {
content: attr(data-placeholder);
float: left;
margin-left: 5px;
color: gray;
}
JS:
(function ($) {
$('div[data-placeholder]').on('keydown keypress input', function() {
if (this.textContent) {
this.dataset.divPlaceholderContent = 'true';
}
else {
delete(this.dataset.divPlaceholderContent);
}
});
})(jQuery);
и это все.
Я нашел, что лучший способ сделать это-использовать placeholder
атрибут, как обычно, и добавьте несколько строк CSS.
HTML-код
<div contenteditable placeholder="I am a placeholder"></div>
в CSS
[contenteditable][placeholder]:empty:before {
content: attr(placeholder);
color: #bababa;
}
Примечание: CSS :empty
селектор работает только в том случае, если между тегом открытия и закрытия буквально ничего нет. Это включает в себя новые строки, вкладки, пустое пространство и т. д.
все, что вам нужно, это небольшое решение
[contenteditable=true]:empty:before{
content: attr(placeholder);
display: block; /* For Firefox */
}
вот мой путь:
Он использует комбинацию jQuery и CSS3. работает точно так же, как атрибут заполнителя html5!.
- скрывается сразу же, когда вы вводите первую букву
- показывает себя снова, когда вы удаляете то, что вы вводите в него
HTML:
<div class="placeholder" contenteditable="true"></div>
CSS3 код:
.placeholder:after {
content: "Your placeholder"; /* this is where you assign the place holder */
position: absolute;
top: 10px;
color: #a9a9a9;
}
jQuery:
$('.placeholder').on('input', function(){
if ($(this).text().length > 0) {
$(this).removeClass('placeholder');
} else {
$(this).addClass('placeholder');
}
});
вот исправление, которое я использовал.
<div contenteditable><em>Edit me</em></div>
<script>
$('div').focus(function() {
var target = $(this);
window.setTimeout(function() { target.empty(); }, 10);
});
</script>
Я разработал плагин jQuery для этого. Взгляните https://github.com/phitha/editableDiv
var curText = 'Edit me';
$('div').focusin(function() {
if ($(this).text().toLowerCase() == curText.toLowerCase() || !$(this).text().length) {
$(this).empty();
}
}).focusout(function() {
if ($(this).text().toLowerCase() == curText.toLowerCase() || !$(this).text().length) {
$(this).html('<em>' + curText + '</em>');
}
});
Это не точное решение вашей проблемы ..
в summernote опции set
airMode: true
заполнитель работает таким образом.