Замена contenteditable текста на лету

Я хочу добавить немного HTML, поскольку пользователи вводят что-то в contenteditable. Например,

$('body')
  .delegate('div[contenteditable=true]', 'blur keyup paste',
    function(){
      var html = this.innerHTML;
      html.replace( "a", "b" );
      this.innerHTML = html;
    });

Ну, во-первых, это ничего не заменяет. Во-вторых, у меня возникла странная проблема, из-за которой я больше не могу вводить текст в contenteditable div. Я проверил события, запущенные в div, событие «размытие» не происходит. Кажется, я выделил div, но мне нужно снова щелкнуть по div, чтобы что-то напечатать. Что мне здесь не хватает?


person Drew    schedule 13.11.2010    source источник


Ответы (3)


Если вы хотите, чтобы пользователь мог выбирать элементы и выделять их полужирным/курсивным шрифтом (или вставлять блок HTML там, где находится маркер точки вставки пользователя), вы хотите использовать document.execCommand. На веб-сайте Mozilla есть документация по этому вопросу.

person PleaseStand    schedule 13.11.2010

В первой части проблема заключается в том, что метод строки replace() в JavaScript возвращает новую строку и не влияет на исходную строку. Что вам нужно:

html = html.replace("a", "b");

Что касается второй проблемы, проблема, вероятно, заключается в том, что установка свойства innerHTML элемента уничтожает и воссоздает все дерево DOM внутри элемента, и, поскольку выделение или курсор содержались в этом дереве DOM, которого больше не существует, браузер сделать что-то, чтобы выздороветь. Я предполагаю, что браузер, в котором вы тестируете, просто очищает выбор.

person Tim Down    schedule 13.11.2010
comment
Да, я уже думал, что replace используется таким образом, спасибо, что указали на это. Что-то происходит с деревом DOM, когда вызывается innerHTML, не знаю что, но ясно, что они не собираются использовать его так, как я. - person Drew; 13.11.2010

Борьба с аналогичной проблемой: мне нужно выделить некоторые специальные символы в contenteditable. Например, выделить & NBSP; с красным фоном. Итак, я делаю что-то вроде

elem.innerHTML = elem.innerHTML.replace('&nbsp;', '<span class="highlight">&nbsp;</span>');

Конечно, браузер воссоздаст элемент (чтобы перерисовать его), и элемент потеряет фокус и положение каретки. Если вы напечатаете elem.innerHTML в событии keyup/input в FireFox, вы увидите, что он вставляет специальный ‹ br > в качестве маркера. Я пытаюсь использовать ту же технику: я вставляю маркер в позицию курсора, используя объект Range, затем заменяю & nbsp; (в этот момент я теряю фокус), а затем я получаю маркер, чтобы выбрать его и удалить.

См. документацию Range API https://developer.mozilla.org/en-US/docs/Web/API/range

person Freebin    schedule 27.08.2013