如何获取突出显示的所有元素

时间:2009-09-27 05:05:42

标签: javascript dom

我希望获得用户突出显示区域中的所有元素。问题是当元素位于树的不同部分时,我不知道如何遍历DOM的不同部分。到目前为止,我的代码只能从选择范围的startContainer中获取元素。我需要某种递归吗?这是我的代码:

    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);
    }
},

1 个答案:

答案 0 :(得分:16)

您可以使用TreeWalker document.createTreeWalker。一个例子如下。它列出了部分或全部选中的所有元素。您可以通过修改传递给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">