Вопрос:

Получить все элементы блока DOM для выделенных текстов

javascript html dom selection range

6997 просмотра

4 ответа

95 Репутация автора

При выборе текстов в документах HTML можно начинать с одного элемента DOM до другого элемента, возможно, пропуская несколько других элементов в пути. Используя DOM API, можно получить диапазон выделения, выделенные тексты и даже родительский элемент всех этих выбранных элементов DOM (используя commonAncestorContainer или parentElement () в зависимости от используемого браузера). Однако я не знаю, каким образом можно перечислить все те, которые содержат элементы выделенных текстов, кроме как получить один родительский элемент, который содержит их все. Использование родительского узла и обход дочерних узлов этого не сделают, так как могут быть другие братья и сестры, которые не выбраны внутри этого родителя.

Итак, есть ли способ, которым я могу получить все эти элементы, которые содержат выбранные тексты. Я в основном заинтересован в получении элементов блока (p, h1, h2, h3, ... и т. Д.), Но я верю, что если есть способ получить все элементы, я могу просмотреть их и отфильтровать, чтобы получить то, что я хочу. Я приветствую любые идеи и предложения.

Спасибо.

Автор: cria Источник Размещён: 18.11.2010 10:54

Ответы (4)


1 плюс

1135 Репутация автора

Похоже, вы можете использовать Traversing из jQuery API .

Возможно .contents ()

Надеюсь, это поможет!

Автор: jasonflaherty Размещён: 18.11.2010 11:01

10 плюса

257116 Репутация автора

Вы можете использовать мою библиотеку Rangy, чтобы сделать это. Он обеспечивает реализацию объектов DOM Range и Selection для всех браузеров, включая IE, и имеет дополнительные методы Range. Одним из них является getNodes():

function isBlockElement(el) {
    // You may want to add a more complete list of block level element
    // names on the next line
    return /h[1-6]|div|p/i.test(el.tagName);
}

var sel = rangy.getSelection();
if (sel.rangeCount) {
    var range = sel.getRangeAt(0);
    var blockElements = range.getNodes([1], isBlockElement);
    console.log(blockElements);
}
Автор: Tim Down Размещён: 18.11.2010 11:48

19 плюса

69841 Репутация автора

Решение

Ключ window.getSelection().getRangeAt(0) https://developer.mozilla.org/en/DOM/range

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

var selection = window.getSelection();
var range = selection.getRangeAt(0);
var allWithinRangeParent = range.commonAncestorContainer.getElementsByTagName("*");

var allSelected = [];
for (var i=0, el; el = allWithinRangeParent[i]; i++) {
  // The second parameter says to include the element 
  // even if it's not fully selected
  if (selection.containsNode(el, true) ) {
    allSelected.push(el);
  }
}


console.log('All selected =', allSelected);

Это не самый эффективный способ, вы можете пройти DOM самостоятельно, используя startContainer / endContainer, а также nextSibling / previousSibling и childNodes.

Автор: Juan Mendes Размещён: 18.11.2010 11:49

0 плюса

1 Репутация автора

Вот подход es6, основанный на ответе @Juan Mendes:

const selection = window.getSelection();
const range = selection.getRangeAt(0);
const elementsFromAncestorSelections = range.commonAncestorContainer.getElementsByTagName("*");

const allSelectedElements = Array.from(elementsFromAncestorSelections).reduce(
  (elements, element) =>
    selection.containsNode(element, true)
      ? [...elements, element]
      : elements,
  [],
);
Автор: user3295081 Размещён: 13.06.2019 03:55
Вопросы из категории :
32x32