javascript - 如何使用javascript获取位于范围内的节点?

标签 javascript dom range traversal

我正在尝试获取范围对象内的所有 DOM 节点,执行此操作的最佳方法是什么?

var selection = window.getSelection(); //what the user has selected
var range = selection.getRangeAt(0); //the first range of the selection
var startNode = range.startContainer;
var endNode = range.endContainer;
var allNodes = /*insert magic*/;

最近几个小时我一直在想办法,想到了这个:

var getNextNode = function(node, skipChildren){
    //if there are child nodes and we didn't come from a child node
    if (node.firstChild && !skipChildren) {
        return node.firstChild;
    }
    if (!node.parentNode){
        return null;
    }
    return node.nextSibling 
        || getNextNode(node.parentNode, true);
};

var getNodesInRange = function(range){
    var startNode = range.startContainer.childNodes[range.startOffset]
            || range.startContainer;//it's a text node
    var endNode = range.endContainer.childNodes[range.endOffset]
            || range.endContainer;

    if (startNode == endNode && startNode.childNodes.length === 0) {
        return [startNode];
    };

    var nodes = [];
    do {
        nodes.push(startNode);
    }
    while ((startNode = getNextNode(startNode)) 
            && (startNode != endNode));
    return nodes;
};

然而,当结束节点是起始节点的父节点时,它会返回页面上的所有内容。我确定我忽略了一些明显的东西?或者可能以完全错误的方式进行。

MDC/DOM/range

最佳答案

这是我想出的一个实现来解决这个问题:

function getNextNode(node)
{
    if (node.firstChild)
        return node.firstChild;
    while (node)
    {
        if (node.nextSibling)
            return node.nextSibling;
        node = node.parentNode;
    }
}

function getNodesInRange(range)
{
    var start = range.startContainer;
    var end = range.endContainer;
    var commonAncestor = range.commonAncestorContainer;
    var nodes = [];
    var node;

    // walk parent nodes from start to common ancestor
    for (node = start.parentNode; node; node = node.parentNode)
    {
        nodes.push(node);
        if (node == commonAncestor)
            break;
    }
    nodes.reverse();

    // walk children and siblings from start until end is found
    for (node = start; node; node = getNextNode(node))
    {
        nodes.push(node);
        if (node == end)
            break;
    }

    return nodes;
}

关于javascript - 如何使用javascript获取位于范围内的节点?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/667951/

相关文章:

javascript - 如何在reactjs中添加多个对象?

javascript - Highcharts 工具提示图片

javascript - 按下 ESC 时切换 Javascript 全屏按钮

javascript - 在 Vanilla JS 中使用 ReplaceWith 将一个元素替换为 DOMstring 或多个元素

javascript - 文档.exec命令

javascript - jQuery 代码冲突

javascript - react 保存使用重新渲染组件选择文本的可能性

javascript - 浏览器如何重构无效的html结构,有什么规则或方法吗?

axapta - 手动添加过滤器时如何保留表单数据源的范围?

scala - Scala 中是否有范围数据结构?