Работа с разрывами строки в contentEditable DIV - PullRequest
52 голосов
/ 17 мая 2011

У меня проблема с 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

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

Я нашел этот код на Создайте
вместо

, нажав клавишу Enter для contenteditable

$(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, если она находится внутри элемента (contentEditable)

Ответы [ 6 ]

28 голосов
/ 18 октября 2012

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

Это не идеальный хак, но он работает: он добавляет пробел после вашего BR, чтобы он показывался правильно. Тем не менее, вы увидите, что добавление только пробела "" ничего не изменит, оно работает с другими буквами. Браузер не будет показывать это, вероятно, потому что это похоже на пустое пространство внутри 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;
  }

   }
});
13 голосов
/ 05 августа 2012

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

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

JSFiddle демо здесь .

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

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

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

9 голосов
/ 06 декабря 2017

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

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

И еще более легкий подход.

ТОЛЬКО CSS.

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

2 голосов
/ 13 марта 2013

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

По-видимому, решение для Webkits состоит в том, чтобы вставить двойные br s, как они сами, и позволить им обрабатывать все остальное.

1 голос
/ 13 августа 2014

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

И посмотрите на этот ответ: HTML - символ новой строки в DIVсодержание редактируемое?

0 голосов
/ 11 октября 2012
...