Объединение текстовых узлов вместе после вставки диапазона - PullRequest
27 голосов
/ 24 марта 2012

У меня есть расширение, в котором я сохраняю / извлекаю раздел структуры 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>

Ответы [ 4 ]

76 голосов
/ 07 октября 2013

Использовать element.normalize () .

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

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

5 голосов
/ 24 марта 2012

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

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

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

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

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

3 голосов
/ 17 января 2018

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

normalize() это хорошо, но у него есть свои недостатки.1009 *

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

0 голосов
/ 24 марта 2012

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

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

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

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...