【问题标题】:Select spans accross multiple divs issue选择跨多个 div 问题
【发布时间】:2025-12-16 08:25:01
【问题描述】:

我遇到了以下问题 - 我正在尝试选择跨多个 div 的跨度内的文本。举个例子

<div>asd<span>fgh</span></div>
<div><span>qwerty</span></div>
<div><span>uio</span>asd</div>

现在在这种情况下,如果用户单击单词qwerty 内的某个位置,我想选择文本'fghqwertuio' --> 所有相邻的跨度。我正在使用以下代码来执行此操作:

    var range = document.caretRangeFromPoint(lastTappedX, lastTappedY);
    range.selectNodeContents(range.startContainer);
    window.getSelection().addRange(range);

    var containerNodes = document.body.children[0].children;
    var whichChild = -1;

    for ( var i = 0; i < containerNodes.length; ++i) {
        if (containerNodes[i] === range.startContainer.parentNode.parentNode) {
            whichChild = i;
            break;
        }
    }

    if (whichChild === -1) {
        console.log("couldn't find the highlighted div");
    }

    // go right the dom tree
    for ( var i = whichChild + 1; i < containerNodes.length; ++i) {
        var containerChildren = containerNodes[i].children;
        if (containerChildren[0]
                && containerChildren[0].style['background-color']) {
            var newRange = document.createRange();
            newRange.selectNodeContents(containerChildren[0]);
            window.getSelection().addRange(newRange);
        }

        if (containerChildren.length > 1) {
            break;
        }
    }

    // go left the down tree
    for ( var i = whichChild - 1; i >= 0; --i) {
        var containerChildren = containerNodes[i].children;
        if (containerChildren[containerChildren.length - 1].style['background-color']) {
            var newRange = document.createRange();
            newRange
                    .selectNodeContents(containerChildren[containerChildren.length - 1]);
            window.getSelection().addRange(newRange);
        }

        if (containerChildren.length > 1) {
            break;
        }
    }

当我记录发生的情况时 - 我正确地创建了包含我想选择的文本的范围,但将它们添加到选择对象似乎不起作用。当前选择只是第一个添加的范围。任何有关如何解决此问题的帮助将不胜感激。

【问题讨论】:

  • @Simon: jQuery 无法处理范围和选择,也无助于解决这里的基本问题。
  • 对不起,我真的不明白你的问题。我创建了一个简短的小提琴,也许您可​​以根据小提琴解释您的问题:jsfiddle.net/6rvE7/1
  • @TimDown 10 倍的答案。我只是在刷新页面时查看它并看到它已被删除。可以转发吗?
  • 我发布了一些代码,但意识到我对跨度彼此相邻的假设做出了错误的假设,因此将其删除。我已经发布了一个没有代码的精简答案。对于它的价值,这里有一个 jsFiddle 我要发布的内容:jsfiddle.net/timdown/P62kZ/2
  • 您找到解决方案了吗?我也有这个问题。我有突出显示搜索结果的代码,但很失望它只能在 Firefox 上运行。

标签: javascript selection range html


【解决方案1】:

在主要浏览器中,只有 Firefox 允许每次选择多个范围。在所有其他浏览器中,您仅限于一个范围。

您需要调整代码以创建一个范围并使用该范围的setStart()setEnd() 方法。此外,元素的style 属性的属性使用驼峰式大小写而不是连字符(即.backgroundColor 而不是['background-color'])。

【讨论】:

  • 有没有办法在 chrome 或 IE 中做到这一点?我想知道为什么该方法被称为 addRange 而只能选择一个范围?
  • @AshrafSabry:不,除了 Mozilla 浏览器之外,没有其他方法可以做到这一点。 Mozilla 组成了选择 API,其他人都复制了它,除了多范围支持,因此 addRange()removeAllRanges()
  • 嘿!你是Rangy的作者!这是一个很好的巧合。在确定这些浏览器不支持多个范围之前,我尝试使用您的库。当我看到 chrome 中的“查找和替换”功能以及它突出显示搜索匹配的方式时,我想知道为什么他们在已经实现它的时候没有公开这个突出显示功能。感谢您的出色工作。
  • @AshrafSabry:如果 Chrome 确实以某种未记录的方式公开突出显示功能,我不会感到惊讶。