[英]Get all DOM block elements for selected texts
在HTML文檔中選擇文本時,可以從一個DOM元素開始到另一個元素,可能在途中傳遞其他幾個元素。 使用DOM API,可以獲取所有選定DOM元素的選擇范圍,選定文本甚至父元素(使用基於使用的瀏覽器的commonAncestorContainer或parentElement())。 但是,我無法知道除了獲取包含所有文本的單個父元素之外,還可以列出包含所選文本元素的所有元素。 使用父節點並遍歷子節點將不會這樣做,因為可能有其他兄弟節點未在此父節點內選擇。
那么,是否有一種方法可以獲得包含所選文本的所有這些元素。 我主要感興趣的是獲取塊元素(p,h1,h2,h3,...等),但我相信如果有辦法獲取所有元素,那么我可以通過它們並過濾它們來得到我想。 我歡迎任何想法和建議。
謝謝。
鍵是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);
這不是最有效的方法,您可以使用Range的startContainer / endContainer以及nextSibling / previousSibling和childNodes自行遍歷DOM。
您可以使用我的Rangy庫來執行此操作。 它為所有瀏覽器(包括IE)提供DOM Range和Selection對象的實現,並具有額外的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);
}
這是基於@Juan Mendes響應的es6方法:
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,
[],
);
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.