Javascript INDEX_SIZE_ERR:范围的 DOM 异常 1 错误

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/3937678/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-10-25 02:44:50  来源:igfitidea点击:

Javascript INDEX_SIZE_ERR: DOM Exception 1 Error for ranges

javascriptdomrange

提问by joshholat

Using the following code, I get a INDEX_SIZE_ERR: DOM Exception 1 error on the thisRange.setStart line. The code is meant to go through a whole page, find instances of the searchString, and then add a link in front of that search string. For example, if it finds 5 instances of the string, right now it will add the link in front of the first one but then error on the second and stop, leaving four words without the link. Any ideas?

使用以下代码,我在 thisRange.setStart 行上得到一个 INDEX_SIZE_ERR: DOM Exception 1 错误。该代码旨在遍历整个页面,找到 searchString 的实例,然后在该搜索字符串前面添加一个链接。例如,如果它找到字符串的 5 个实例,现在它会在第一个实例前面添加链接,但在第二个实例上出错并停止,留下四个没有链接的单词。有任何想法吗?

    if(searchString.length > 0) { // make sure the string isn't empty, or it'll crash.
    // Search all text nodes
    for(var i = 0; i < textNodes.length; i++) {
        // Create a regular expression object to do the searching
        var reSearch = new RegExp(searchString,'gmi'); // Set it to 'g' - global (finds all instances), 'm' - multiline (searches more than one line), 'i' - case insensitive
        var stringToSearch = textNodes[i].textContent;

        while(reSearch(stringToSearch)) { // While there are occurrences of the searchString
            // Add the new selection range
            var thisRange = document.createRange();

            //alert((reSearch.lastIndex - searchString.length) + " <-> " + reSearch.lastIndex);

            thisRange.setStart(textNodes[i], reSearch.lastIndex - searchString.length); // Start node and index of the selection range
            thisRange.setEnd(textNodes[i], reSearch.lastIndex); //  End node and index of the selection

            var myLink = document.createElement('a'); 
            var href = document.createAttribute('href'); 
            myLink.setAttribute('href','http://www.google.com'); 
            myLink.innerText ="GO";
            thisRange.insertNode(myLink);

            //theSelection.addRange(thisRange); // Add the node to the document's current selection
            //thisRange.deleteContents();
        }
    }
}

采纳答案by gilly3

Once you've added a link, the document has changed. When you next call thisRange.setStart, it's using the index from the original string, but setting it in the now changed document.

添加链接后,文档已更改。当您下次调用 时thisRange.setStart,它使用原始字符串中的索引,但将其设置在现在更改的文档中。

You need to add them in reverse order. Try storing the match indexes in an array, and then walk your array of indexes backwards to inject your links.

您需要以相反的顺序添加它们。尝试将匹配索引存储在一个数组中,然后向后遍历索引数组以注入链接。

回答by joshholat

I figured it out. Here's how:

我想到了。就是这样:

    for (var i = rangeArray.length - 1; i >= 0; i--) {
    var myLink = document.createElement('a'); 
    var href = document.createAttribute('href'); 
    myLink.setAttribute('href','http://www.google.com'); 
    myLink.innerText ="GO";
    rangeArray[i].insertNode(myLink);
}

Instead of adding it to the range in the above loop, I added it to and array and then went through that array backwards.

我没有将它添加到上述循环中的范围,而是将它添加到和数组,然后向后遍历该数组。