В contenteditable как добавить абзац после blockquote при нажатии клавиши Enter?
у меня следующая проблема. Как только я добавлю blockquote
на contenteditable
, нажав клавишу Enter, он перемещается в новую строку и добавляет другую blockquote
элемент. Он продолжается вечно, и я не могу избежать форматирования. Желаемой функциональностью будет функциональность неупорядоченного списка. При нажатии клавиши Enter добавляется новый пустой <li>
элемент, но если вы снова нажмете Enter, он избегает форматирования, удаляет ранее созданный <li>
и добавляет <p>
.
проверить демо: http://jsfiddle.net/wa9pM/
один хак я нашел, чтобы создать пустой <p>
под blockquote
перед созданием blockquote
. Но есть ли способ сломать это поведение форматирования с помощью JavaScript? Не знаю, как я бы проверил: если где курсор, это конец строки, и если это blockquote и при нажатии клавиши Enter, Не добавляйте новый blockquote
.
я использую этот код для создания blockquote
в JS:
document.execCommand('formatBlock', false, 'blockquote');
3 ответов
при создании текстового редактора для приложения iOS я столкнулся с той же проблемой. Каждый раз, когда я вставил <blockquote>
тег в моем текстовом поле и нажмите Enter, невозможно было избавиться от блок-цитаты.
после изучения немного, я нашел рабочее решение.
поиск внутренних тегов HTML:
function whichTag(tagName){
var sel, containerNode;
var tagFound = false;
tagName = tagName.toUpperCase();
if (window.getSelection) {
sel = window.getSelection();
if (sel.rangeCount > 0) {
containerNode = sel.getRangeAt(0).commonAncestorContainer;
}
}else if( (sel = document.selection) && sel.type != "Control" ) {
containerNode = sel.createRange().parentElement();
}
while (containerNode) {
if (containerNode.nodeType == 1 && containerNode.tagName == tagName) {
tagFound = true;
containerNode = null;
}else{
containerNode = containerNode.parentNode;
}
}
return tagFound;
}
проверка вхождений блок-цитаты тег:
function checkBlockquote(){
var input = document.getElementById('text_field_id');
input.onkeydown = function() {
var key = event.keyCode || event.charCode;
if( key == 13){
if (whichTag("blockquote")){
document.execCommand('InsertParagraph');
document.execCommand('Outdent');
}
}
};
}
запуск ключевых события:
<body onLoad="checkBlockquote();">
<!-- stuff... -->
</body>
Я считаю, что код выше можно легко настроить в соответствии с вашими потребностями. Если вам нужна дальнейшая помощь, обращайтесь.
что-то вроде этого сделало работу для меня (по крайней мере, на Chrome и Safari).
демо на http://jsfiddle.net/XLPrw/
$("[contenteditable]").on("keypress", function(e) {
var range = window.getSelection().getRangeAt();
var element = range.commonAncestorContainer;
if(element.nodeName == "BLOCKQUOTE") {
element.parentElement.removeChild(element);
}
});
не сделал никакого обширного теста, но похоже, что range.commonAncestorElement
возвращает текущий textnode, если blockquote содержит текст, или сам элемент blockquote, если он не содержит textnode (в Chrome, a <br>
добавляется и каретка располагается после него). В этом случае вы можете удалить вновь созданный blockquote. Во всяком случае, после удаления элемента каретка выглядит так, как будто она находится где-то на contenteditable, хотя ввод подтверждает, что это сразу после исходного blackquote.
Надеюсь, это укажет вам на более убедительное решение.
супер поздний ответ, но это было гораздо более простое решение для меня. Надеюсь, это поможет кому-то еще искать. Совместимость браузера может отличаться.
YOUR_EDITABLE_ELEMENT.addEventListener('keyup', e => {
if (e.which || e.keyCode === 13) {
if (document.queryCommandValue('formatBlock') === 'blockquote') {
exec('formatBlock', '<P>')
}
}
})