Принудительный элемент IE contentEditable для создания разрывов строк по клавише Enter без прерывания отмены - PullRequest
29 голосов
/ 08 февраля 2010

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

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

Как заставить элемент contentEditable создавать разрывы строк при вводе, не прерывая отмену?

Ответы [ 7 ]

17 голосов
/ 16 февраля 2010

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

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

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

5 голосов
/ 16 февраля 2010

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

<div contenteditable="true">
    <p>If you are typing here</p>
<div>
4 голосов
/ 27 июля 2011

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

Используйте его при событии нажатия клавиши:

if (e.keyCode == 13) {
 var range = document.selection.createRange();
 range.pasteHTML("<br> ");
 range.moveStart("character", 0);
 range.moveEnd("character", -1);
 range.select();
 return false;
}
4 голосов
/ 16 февраля 2010

Предположительно, вы собираетесь публиковать редактируемый контент обратно на сервер. Поэтому вам не должно быть важно, есть ли у вас теги абзаца или разрыва, когда пользователь редактирует, потому что вы можете анализировать HTML перед отправкой (или, если хотите, на сервере) и заменять экземпляры абзацев на разрывы. Это сохраняет очередь UNDO в действии для пользователя, но позволяет вам иметь ваш HTML настолько чистым, насколько вы этого хотите.

Далее я предполагаю, что вы точно будете знать, какие элементы DIV будут contentEditable. Перед отправкой формы вы можете запустить каждый div contentEditable с помощью такой функции:

function cleanContentEditableDiv(div) {
  var htmlString = div.innerHTML;
  htmlString     = htmlString.replace(/<\/p>/gim,"<br/>");
  htmlString     = htmlString.replace(/<p>/gim,"");
  return htmlString;
}

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

2 голосов
/ 15 февраля 2010

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

p { margin: 0; }

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

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

1 голос
/ 26 марта 2012

IE связывает текстовый узел с тегом <p> на Ввод нажатие клавиши. Для достижения перевода строки Shift + Введите . Firefox добавляет тег <br> к Enter нажатию клавиши. Чтобы сделать поведение общим для обоих браузеров, вы можете сделать следующее:

Предположим следующую разметку:

<div id="editableDiv" contentEditable="true"></div>

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);
         }
     })
 })();

Примечание: этот сценарий предшествует jQuery <1.9 для использования устаревшего <code>$.browser

0 голосов
/ 13 декабря 2011

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

...