Работа с линией Разрывы на contentEditable DIV

У меня проблема с разрывами строк contenteditable на SAFARI/CHROME. Когда я нажимаю "return" на contentEditable <div>, вместо создания <br> (например, Firefox), они создают новый <div>:

<div>Something</div>
<div>Something</div>

Это выглядит как (на contentEditable DIV):

Something
Something

Но после дезинфекции (удаление <div>) я получаю следующее:

SomethingSomething

В Firefox contenteditable:

Something
<br>
Something

И что после санитазы выглядит одинаково:

Something
Something

Есть ли какое-либо решение "нормализовать" это в браузерах?

Я нашел этот код на Сделать a <br> вместо <div> </div> нажав Enter на доступном для контента

$(function(){

  $("#editable")

  // make sure br is always the lastChild of contenteditable
  .live("keyup mouseup", function(){
    if (!this.lastChild || this.lastChild.nodeName.toLowerCase() != "br") {
      this.appendChild(document.createChild("br"));
     }
  })

  // use br instead of div div
  .live("keypress", function(e){
    if (e.which == 13) {
      if (window.getSelection) {
        var selection = window.getSelection(),
          range = selection.getRangeAt(0),
          br = document.createElement("br");
        range.deleteContents();
        range.insertNode(br);
        range.setStartAfter(br);
        range.setEndAfter(br);
        range.collapse(false);
        selection.removeAllRanges();
        selection.addRange(range);
        return false;
      }
    }
  });
});

Это работает, но (в SAFARI и CHROME) Я должен нажать два раза клавишу "возврат", чтобы получить новую строку...

Любая идея?

Изменить: с кодом, который я нашел (в нижней части этого вопроса) работает отлично, кроме функции, которая "гарантирует, что элемент <br> всегда является lastChild... Любая идея о как это исправить?

Изменить 2: Я получаю эту ошибку на консоли: Uncaught TypeError: Object #<HTMLDocument> has no method 'createChild'

Изменить 3: Хорошо, я изменил document.createChild("br"); на document.createElement("br");, и я думаю, что получил его в FF/Safari/Chrome... Все возвращают <br> для новых строк...

Проблема в том, что когда я попадаю в упорядоченный или неупорядоченный список, мне нужно получить новую строку без <br>...

Изменить 4: Если кто-то заинтересован в решении последнего редактирования: Избегите функции createElement, если она находится внутри символа <LI> element (contentEditable)

Ответ 1

Этот метод, как представляется, позволяет избежать ошибки Chrome, которая показывает BR в первый раз (с кодом, который вы указали, вам нужно нажать два раза клавишу Enter).

Это не идеальный взлом, но он работает: он добавляет пробел после вашего БР, чтобы он отображался правильно. Тем не менее, вы увидите, что добавление только пробела "" ничего не изменит, оно работает с другими буквами. Браузер не отобразит его, возможно, потому, что он похож на пустое пространство внутри html-страницы, это ничего не значит. Чтобы избавиться от этой ошибки, я создал div с jQuery, который включает тег &nbsp;, и я беру свойство text(), чтобы поместить его в текстовый индекс, иначе он не будет работать.

$editables = $('[contenteditable=true]');

$editables.filter("p,span").on('keypress',function(e){
 if(e.keyCode==13){ //enter && shift

  e.preventDefault(); //Prevent default browser behavior
  if (window.getSelection) {
      var selection = window.getSelection(),
          range = selection.getRangeAt(0),
          br = document.createElement("br"),
          textNode = document.createTextNode("\u00a0"); //Passing " " directly will not end up being shown correctly
      range.deleteContents();//required or not?
      range.insertNode(br);
      range.collapse(false);
      range.insertNode(textNode);
      range.selectNodeContents(textNode);

      selection.removeAllRanges();
      selection.addRange(range);
      return false;
  }

   }
});

Ответ 2

Прослушивание нажатий клавиш кажется большой работой. Было бы просто так, как это было бы возможно:

var html = $('.content').html().replace(/<div>/gi,'<br>').replace(/<\/div>/gi,'');

JSFiddle demo здесь.

Кроме того, он выглядит как sanitize.js позволяет настраивать конфигурацию. Вы пытались добавить div в качестве разрешенного элемента?

Разрешение HTML/CSS опасно, поэтому убедитесь, что вы осторожны.

РЕДАКТИРОВАТЬ: Удалены комментарии на стороне сервера. Санитация происходит во время использования - если клиент хочет обходить это локально, это может быть сделано на свой страх и риск. Спасибо Винсент Макнабб за это.

Ответ 3

Вы можете просто использовать следующую команду document.execCommand('insertHTML',false,'<br>');

Эта команда предотвратит поведение по умолчанию и добавит тег, который вы хотите. Это все, 1 строка кода

И еще более простой подход.

ТОЛЬКО для CSS.

К вам contenteditable element применяется правило display:inline-block и это добавит только br s

Ответ 4

Webkits не будут отображать один br, если он является последним (непустым) дочерним элементом контейнера. Для Safari нативное нажатие клавиши для вставки разрыва строки - Ctrl + Return. Если вы посмотрите внимательно, вы заметите, что Safari фактически вставляет два br, а только рендеринг; однако он будет вставлять один br, если есть какой-то завершающий текст, или будет избавлен от двойного br после того, как вы введете его (если бы были удвоены).

По-видимому, решение Webkits похоже на вставку double br, как и они сами, и пусть они справятся с остальными.

Ответ 5

Возможно, вы захотите проверить свойство css white-space. Установка стиля на white-space: pre-wrap позволяет вам избавиться от всего этого javascript, поскольку он изменяет поведение пробелов для отображения вместо краха.

И посмотрите этот ответ: HTML - Новая строка char в DIV-содержимом редактируемая?

Ответ 7

Ты можешь использовать:

document.execCommand("defaultParagraphSeparator", false, "br");

Полная ссылка здесь