Javascript 如何获取高亮显示的所有元素
我希望获得用户突出显示区域中的所有元素。问题是,当元素位于树的不同部分时,我不知道如何遍历DOM的不同部分。到目前为止,我的代码只能从选择范围的startContainer中获取元素。我需要某种递归吗?这是我的密码:Javascript 如何获取高亮显示的所有元素,javascript,dom,Javascript,Dom,我希望获得用户突出显示区域中的所有元素。问题是,当元素位于树的不同部分时,我不知道如何遍历DOM的不同部分。到目前为止,我的代码只能从选择范围的startContainer中获取元素。我需要某种递归吗?这是我的密码: getSelectedElementTags:function() { var range, sel, container; sel = content.window.getSelection(); if (sel.getRangeAt)
getSelectedElementTags:function()
{
var range, sel, container;
sel = content.window.getSelection();
if (sel.getRangeAt)
{
if (sel.rangeCount > 0)
{
range = sel.getRangeAt(0);
}
}
else
{
range = content.window.createRange();
range.setStart(sel.anchorNode, sel.anchorOffset);
range.setEnd(sel.focusNode, sel.focusOffset);
alert("range created");
}
if (range)
{
container = range["startContainer"];
var elms = container.parentNode.getElementsByTagName("*");
elmlist = "parent: "+container.parentNode.tagName + " (" + elms.length + ")\n";
for (i in elms)
{
if (elms[i].tagName != null)
{
elmlist += elms[i].tagName+"\n";
}
}
alert(elmlist);
}
},
你可以用一把旧的。下面是一个例子。它列出了部分或全部选定的所有图元。通过修改传递给document.createTreeWalker
的参数,可以轻松更改行为
请注意,在Firefox中,您不需要检查选择的getRangeAt
方法是否存在。此检查仅适用于旧版本的WebKit。此外,IE<9不支持TreeWalker或Range,因此以下内容在这些浏览器中不起作用
编辑根据下面的评论进行修复
function rangeIntersectsNode(range, node) {
var nodeRange;
if (range.intersectsNode) {
return range.intersectsNode(node);
} else {
nodeRange = node.ownerDocument.createRange();
try {
nodeRange.selectNode(node);
} catch (e) {
nodeRange.selectNodeContents(node);
}
return range.compareBoundaryPoints(Range.END_TO_START, nodeRange) == -1 &&
range.compareBoundaryPoints(Range.START_TO_END, nodeRange) == 1;
}
}
function getSelectedElementTags(win) {
var range, sel, elmlist, treeWalker, containerElement;
sel = win.getSelection();
if (sel.rangeCount > 0) {
range = sel.getRangeAt(0);
}
if (range) {
containerElement = range.commonAncestorContainer;
if (containerElement.nodeType != 1) {
containerElement = containerElement.parentNode;
}
treeWalker = win.document.createTreeWalker(
containerElement,
NodeFilter.SHOW_ELEMENT,
function(node) { return rangeIntersectsNode(range, node) ? NodeFilter.FILTER_ACCEPT : NodeFilter.FILTER_REJECT; },
false
);
elmlist = [treeWalker.currentNode];
while (treeWalker.nextNode()) {
elmlist.push(treeWalker.currentNode);
}
console.log(elmlist);
}
}
<input type="button" onclick="getSelectedElementTags(window)" value="Get selected elements">
函数范围交叉节点(范围、节点){
无变异;
if(范围交叉节点){
返回范围.intersectsNode(节点);
}否则{
nodeRange=node.ownerDocument.createRange();
试一试{
nodeRange.选择node(节点);
}捕获(e){
nodeRange。选择NodeContents(节点);
}
返回范围。比较基本点(range.END\u到\u START,nodeRange)=-1&&
range.compareBoundaryPoints(range.START\u至\u END,节点范围)==1;
}
}
函数getSelectedElementTags(win){
变量范围、sel、elmlist、treeWalker、containerElement;
sel=win.getSelection();
如果(选择范围计数>0){
范围=选择范围(0);
}
如果(范围){
containerElement=range.commonAncestorContainer;
if(containerElement.nodeType!=1){
containerElement=containerElement.parentNode;
}
treeWalker=win.document.createTreeWalker(
集装箱运输,
NodeFilter.SHOW_元素,
函数(节点){返回范围相交节点(范围,节点)→NodeFilter.FILTER\u接受:NodeFilter.FILTER\u拒绝;},
假的
);
elmlist=[treeWalker.currentNode];
while(treeWalker.nextNode()){
elmlist.push(treeWalker.currentNode);
}
console.log(elmlist);
}
}
您可以使用jQuery吗?这必须适用于哪些浏览器(请不要全部说明,因为我怀疑Netscape 4是否会得到支持)。只适用于Firefox,因为这是一个扩展。非常感谢Tim,它工作得很好。只是一个小问题。。。当选择一个元素时,列表为空。不确定这是否是最好的方法,但我通过测试范围的startContainer和endContainer是否相同来解决这个问题。如果它们是一样的,我就不用做树行者,只需要得到startContainer的父节点。你说得对。有两个问题:第一,我忘了在列表中包含TreeWalker中的第一个节点,第二,如果整个选择包含在单个文本节点中,则不会返回任何元素。这两个问题现在都在答案中解决了。这在IE中也适用吗?我发现射程可能有问题object@Thariama:不,这对IE<9不起作用,但问题下方有评论说OP只关心Firefox。不管怎样,我会在答案上写一个注释。