Ответ 1
Не точное решение, а другое обходное решение. Если вы используете разметку:
<div contenteditable="true">
<div>
content
</div>
<div>
Затем нажатие enter создаст новые теги div
вместо тегов p
.
В Internet Explorer, contentEditable DIV создает новый абзац (<p></p>
) каждый раз, когда вы нажимаете Enter, тогда как Firefox создает тег <br/>
.
Как обсуждалось здесь, можно использовать JavaScript для перехвата Enter keyPress и использования диапазона. pasteHTML для создания <br/>
. Но это нарушает меню Отменить; как только вы нажмете Enter, вы больше не сможете отменить эту точку.
Как заставить элемент contentEditable создавать отдельные разрывы строк на Enter без нарушения Undo?
Не точное решение, а другое обходное решение. Если вы используете разметку:
<div contenteditable="true">
<div>
content
</div>
<div>
Затем нажатие enter создаст новые теги div
вместо тегов p
.
Удерживайте нажатой клавишу, когда вы нажимаете Enter для перерывов, не удерживайте ее нажатой для полных абзацев. В Firefox это поведение по умолчанию одно и то же, учитывая область контента, содержащую абзац: i.e.
<div contenteditable="true">
<p>If you are typing here</p>
<div>
Предположительно вы опубликуете редактируемый контент на сервере. Поэтому вам не все равно, есть ли у вас теги абзаца или разрыва во время редактирования, потому что вы можете проанализировать HTML перед отправкой (или на сервере, если хотите) и заменить экземпляры абзацев на разрывы. Это приводит к тому, что очередь UNDO работает для пользователя, но позволяет вам иметь ваш HTML как чистый, как вы этого хотите.
Далее я предполагаю, что вы точно узнаете, какие элементы DIV будут contentEditable. Перед отправкой формы вы можете запустить каждый contentEditable div с помощью следующей функции:
function cleanContentEditableDiv(div) {
var htmlString = div.innerHTML;
htmlString = htmlString.replace(/<\/p>/gim,"<br/>");
htmlString = htmlString.replace(/<p>/gim,"");
return htmlString;
}
И вы вызываете это в цикле (который итерации через все contentEditable DIVs, используя массив, который я буду называть ceDivs), например:
ceDivs[i].contentEditable = false; // to make sure IE doesn't try to coerce the contents again
а затем:
ceDivs[i].innerHTML = cleanContentEditableDiv(ceDivs[i]);
Улучшение этого (особенно, если вы не хотите делать это правильно в момент отправки), может состоять в том, чтобы очищать содержимое каждого такого div в любое другое время, которое вам нравится (onblur, что угодно), и назначать содержимое каждого из них ceDiv - свой собственный элемент невидимой формы для последующего представления. Используемый в сочетании с вашим собственным предложением CSS выше, это может сработать для вас. Он не сохраняет ваши буквальные требования к письму (т.е. Он не дает Javascript, чтобы заставить IE вести себя иначе, чем он был закодирован под обложками, чтобы вести себя), но для всех практических целей эффект один и тот же. Пользователи получают то, что хотят, и получают то, что вы хотите.
Пока вы на нем, вы также можете очистить строки пространства в IE. Если пользователь вводит несколько пробелов (как некоторые еще делают после периодов), то, что вставлено IE, не является [пробел] [пробел], а [пробел] & nbsp;, начальный пробельный символ (String.fromCharCode(32)) плюс как многие поскольку они остаются в пробеге.
Используйте <BR>
вместо <P>
(проверено в IE9. Возможно, nbsp;
требуется в более старых версиях после <BR>
(pasteHTML("<br> "))
)
Используйте его при событии keydown:
if (e.keyCode == 13) {
var range = document.selection.createRange();
range.pasteHTML("<br> ");
range.moveStart("character", 0);
range.moveEnd("character", -1);
range.select();
return false;
}
Возможно, это невозможно. Тем не менее, можно сделать теги <p>
похожими на отдельные разрывы строк, удалив встроенный маркер вокруг тегов абзаца, используя CSS:
p { margin: 0; }
Существует недостаток этого подхода: если пользователю необходимо скопировать/вставить текст в элементе contentEditable, текст может отображаться как однораздельный внутри элемента, но с двойным интервалом вне элемента.
Хуже того, по крайней мере в некоторых случаях IE автоматически обнаруживает разрывы двух строк во время вставки, заменяя их тегами <p>
; это испортит форматирование вставленного текста.
IE связывает текст node с тегом
при нажатии клавиши. Для достижения разрыва строки+. Firefox добавляет тег
при нажатии клавиши. Чтобы сделать поведение распространенным в обоих браузерах, вы можете сделать следующее:
Предположим следующую разметку:
Javascript [предположим, что приведенный ниже код находится в закрытии функции, чтобы вы не раздували страницу с помощью глобальных символов]:
(function () {
//Initialize _shiftKeyPressed to false
var _shiftKeyPressed = false;
$('#editableDiv').live('keydown', function (e) {
if (e.keyCode == 16) {
// SHIFT key is pressed
_shiftKeyPressed = true;
}
}).live('keyup', function (e) {
if (e.keyCode == 16) {
// SHIFT key is release
_shiftKeyPressed = false;
}
}).live('keypress', function (e) {
if (e.keyCode == 13 && !_shiftKeyPressed && !jQuery.browser.msie) {
// Insert a PARAGRAPH in Firefox instead of a BR
// Ignores SHIFT + ENTER
document.execCommand("insertParagraph", false, true);
}
})
})();
Примечание: этот script предшествует jQuery < 1.9 для использования устаревшего $.browser
Рассмотрите возможность использования <span contenteditable="true"></span>
при использовании Internet Explorer. Возможно, вы не захотите делать это с помощью Chrome, потому что фокус выглядит забавным. Вероятно, вы захотите реализовать свой собственный код onfocus
и onblur
.