Подтвердить что ты не робот

Force IE contentEditable элемент для создания разрывов строк на клавише Enter, без нарушения Undo

В Internet Explorer, contentEditable DIV создает новый абзац (<p></p>) каждый раз, когда вы нажимаете Enter, тогда как Firefox создает тег <br/>.

Как обсуждалось здесь, можно использовать JavaScript для перехвата Enter keyPress и использования диапазона. pasteHTML для создания <br/>. Но это нарушает меню Отменить; как только вы нажмете Enter, вы больше не сможете отменить эту точку.

Как заставить элемент contentEditable создавать отдельные разрывы строк на Enter без нарушения Undo?

4b9b3361

Ответ 1

Не точное решение, а другое обходное решение. Если вы используете разметку:

<div contenteditable="true">
<div>
content
</div>
<div>

Затем нажатие enter создаст новые теги div вместо тегов p.

Ответ 2

Удерживайте нажатой клавишу, когда вы нажимаете Enter для перерывов, не удерживайте ее нажатой для полных абзацев. В Firefox это поведение по умолчанию одно и то же, учитывая область контента, содержащую абзац: i.e.

<div contenteditable="true">
    <p>If you are typing here</p>
<div>

Ответ 3

Предположительно вы опубликуете редактируемый контент на сервере. Поэтому вам не все равно, есть ли у вас теги абзаца или разрыва во время редактирования, потому что вы можете проанализировать 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)) плюс как многие поскольку они остаются в пробеге.

Ответ 4

Используйте <BR> вместо <P> (проверено в IE9. Возможно, nbsp; требуется в более старых версиях после <BR> (pasteHTML("<br>&nbsp;")))

Используйте его при событии 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;
}

Ответ 5

Возможно, это невозможно. Тем не менее, можно сделать теги <p> похожими на отдельные разрывы строк, удалив встроенный маркер вокруг тегов абзаца, используя CSS:

p { margin: 0; }

Существует недостаток этого подхода: если пользователю необходимо скопировать/вставить текст в элементе contentEditable, текст может отображаться как однораздельный внутри элемента, но с двойным интервалом вне элемента.

Хуже того, по крайней мере в некоторых случаях IE автоматически обнаруживает разрывы двух строк во время вставки, заменяя их тегами <p>; это испортит форматирование вставленного текста.

Ответ 6

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

Ответ 7

Рассмотрите возможность использования <span contenteditable="true"></span> при использовании Internet Explorer. Возможно, вы не захотите делать это с помощью Chrome, потому что фокус выглядит забавным. Вероятно, вы захотите реализовать свой собственный код onfocus и onblur.