Восстановление диапазона с помощью узла, startOffset и endOffset
Я пытаюсь восстановить Range()
объект в браузере клиентов с помощью websockets.
https://jsfiddle.net/k36goyec/
сначала я получаю объект диапазона в своем браузере и узел что диапазон начинается в:
var range = window.getSelection().getRangeAt(0);
var node = range.startContainer
Я передаю три параметра через websockets функции Range builder в браузере клиентов.
var text = node.parentNode.textContent;
var startOffset = range.startOffset
var endOffset = range.endOffset
эти данные передаются в мой buildRange функция:
/**
*
*/
buildRange: function(text, startOffset, endOffset){
var node = this.getNodeByText(text); // get the Node by its contents
var range = document.createRange();
range.setStart(node, startOffset);
range.setEnd(node, endOffset);
span = document.createElement('span');
span.style.backgroundColor = this.color;
$(span).addClass('hl');
range.surroundContents(span);
},
как вы можете видеть ниже, я получаю узел в браузере клиентов перебрав все элементы на странице, и сравнение его содержания с текстом:
/**
*
*/
getNodeByText: function(text){
var all = document.getElementsByTagName("*");
for (var i = 0; i < all.length; i++) {
if (all[i].textContent === text) {
return all[i];
}
}
},
Я использую setStart () и setEnd (), чтобы установить диапазон моего выбора на узле.
проблемы!
на
2 ответов
другие уже указали, что непосредственная проблема, с которой вы столкнулись, заключается в том, что при сохранении данных диапазона вы получаете смещение в текстовый узел, но при попытке воссоздать диапазон вы используете смещение в качестве индекса в элемент, и она падает. Если вы исправите это, вы исправите свою непосредственную проблему.
ваш общий подход, однако, хрупкий.
рассмотрим документ с этого:
<p>Farmer John has a thousand <b>goats</b></p>
<p>and his <b>goats</b> ate all his oats.</p>
некоторые проблемы, с моей головы:
Если вы выберете 2-й "козел", ваш алгоритм воссоздаст диапазон на первых" козах", потому что он ищет только элемент, который имеет тот же текст, что и исходный диапазон.
-
Если вы выбираете диапазон, который начинается с "и "во 2-й строке и заканчивается на" ate", смещения, которые вы получаете из своего исходного диапазона, индексируются в два разных текстовых узлов: один текстовый узел, содержащий текст
and his
и второй текстовый узел, содержащий текстate all his oats.
ваш алгоритм предполагает, что есть только одна заметка для восстановления в месте назначения. Их может быть несколько.та же проблема возникает, если у вас есть выбор, который начинается с одного из выделенных жирным шрифтом слов и заканчивается снаружи.
чтобы иметь что-то надежное, вам нужно выполнить сериализацию диапазона в источнике, который записывает достаточно информации, чтобы обеспечить точную десериализацию в назначение.
есть много способов сделать это. Одним из способов может быть обеспечение того, чтобы одна и та же структура DOM присутствовала в месте происхождения и назначения, и использовать модуль сериализации библиотеки Rangy для выполнения сериализации и десериализации. Если вы можете обеспечить одинаковую структуру DOM на обоих концах, это то, что я бы использовал.
Если вы не можете обеспечить такую же структуру DOM на обоих концах, то вы должны свернуть свой собственный. Вы должны определить ссылку точки, которые одинаковы на обоих концах и идентифицируют начальный узел/смещение и конечный узел/смещение диапазона относительно этих контрольных точек.
решение проблемы:
Я просто не могу надежно получить текстовый узел, я могу получить только сам узел элемента...
чтобы получить фактический текстовый узел ,вы можете использовать.свойство childnodes элемента. Если у вас есть более одного, вы можете проверить nodeType, чтобы определить, какие текстовые узлы. Чтобы узнать, что находится в любом текстовом узле, проверьте свойство nodeValue.