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

Объединение текстовых узлов вместе после вставки пробела

У меня есть расширение, где я храню/извлекаю раздел структуры DOM (всегда выбор текста на экране), который выбрал пользователь. Когда я сохраняю выбор, я заключу раздел в теге SPAN и выделяю текст желтым цветом. Это заставляет структуру DOM вокруг выделенного текста разбиваться на различные текстовые узлы. Это вызывает проблему для меня, так как когда я пытаюсь восстановить этот выбор (без обновления страницы), это вызывает проблемы по мере изменения структуры DOM.

Мой вопрос заключается в том, как предотвратить разделение структуры DOM после вставки SPAN? Если этого не может быть достигнуто, как мне собрать структуру DOM после удаления тега SPAN в исходное состояние?

//Insert the span
var sel = restoreSelection(mootsOnPage[i].startXPath);
var range = sel.getRangeAt(0).cloneRange();
var newNode = document.createElement('span');
newNode.className = 'highlightYellow';
range.surroundContents(newNode); 


//Original DOM structure
<p>Hello there, how are you today</p>


//What the DOM looks like after insertion of SPAN
<p>
  "Hello there, "
  <span class="highlightYellow">how</span
  " are you today"
</p>
4b9b3361

Ответ 1

Вы можете использовать это, чтобы развернуть свой контент.

$(".highlightYellow").contents().unwrap(); 

Демо: http://jsfiddle.net/R4hfa/

Ответ 2

Используйте element.normalize().

После удаления введенного вами диапазона вы можете использовать метод element.normalize() для объединения дополнительных текстовых узлов, которые были созданы как результат вставки/удаления пролета. Метод normalize() помещает указанный элемент и все его поддерева в "нормализованную" форму (т.е. Текстовые узлы в поддереве не являются пустыми и отсутствуют смежные текстовые узлы). Найдено, благодаря комментарию @tcovo.

Текстовые узлы внутри элемента разбиваются, если вы вставляете узлы и затем удаляете их. К сожалению, они не будут автоматически повторно объединены после удаления дополнительного node. Чтобы ответить на вопросы людей о том, "почему" это имеет значение, обычно это вызывает проблемы при работе с подсветкой текста в пользовательском интерфейсе.

Ответ 3

Сам акт вставки тега <span> изменит DOM. Это, по определению, то, что вы делаете, когда вызываете surroundContents(). Вы не можете добавить тег span без изменения DOM, который включает разделение текстовых узлов и добавление новых элементов для диапазона.

Кроме того, если выделенный текст не содержит только целые текстовые узлы, и выбор никогда не запускается/останавливается в середине текста node, вам придется разделить текстовые узлы, чтобы поместить диапазон в нужное место. Когда вы позже удалите теги span, у вас будут дополнительные текстовые узлы. Это ни на что не важно, но если вы действительно думаете, что вам нужно вернуть узлы с разделенным текстом так, как они были, я могу представить несколько вариантов:

1) Сохраните исходный родительский указатель до того, как он будет вставлен в него. Клонируйте его, добавьте свой диапазон к клону, замените оригинальный node на клоун и сохраните оригинал. Когда вы хотите восстановить, верните оригинал и удалите клонированный файл.

2) Когда вы удаляете span, запускайте функцию, которая ищет соседние текстовые узлы и объединяет их.

3) Выясните, почему важно, чтобы после этого появилось больше текстовых узлов, чем раньше, потому что это не имеет значения для какого-либо кода или отображения.

Ответ 4

При использовании normalize() обратите внимание! Он удалит узлы, например <br/>, и изменит текст и его визуализацию.

normalize() хорош, но имеет свои недостатки.

Итак, <p>"this is an "<br/>"example"</p> превратится в <p>this is an example</p>

Есть ли способ использовать normalize(), но сохраняя <br/> s?