遍历更多 querySelectorAll 匹配项

Loop through more querySelectorAll matches

我正在尝试从两个不同的 ID 中获取 innerHTML 来计算单词数。因此,我将 querySelectorAll 与两个 id 匹配项一起使用。我只得到第一场比赛。这种方法甚至可能吗?

function() {
    var wordCounts;
    var wordCountTemp = document.querySelectorAll("#text-block-10, #text-block-12");
    var i;
    for(i = 0; i < wordCountTemp.length; i++){
    wordCounts = wordCountTemp[i].innerHTML;
    wordCounts.replace(/(^\s*)|(\s*$)/gi,"");
    wordCounts.replace(/[ ]{2,}/gi," ");
    wordCounts.replace(/\n /,"\n");
    return wordCounts.split(" ").length;
    }
}

非常感谢您的帮助!

此致, 托尼

试试这个:

Array.from(document.querySelectorAll("#text-block-10, #text-block-12"))
  .map(x => x.innerHTML
    .replace(/(^\s*)|(\s*$)/gi,"")
    .replace(/[ ]{2,}/gi," ")
    .replace(/\n /,"\n")
    .split(" ")
    .length)
  .reduce((a, b) => a + b)

return 在对从 querySelectorAll. In addition, replace 返回的第一个元素以外的任何元素执行任何操作之前,您从函数中 return 不会修改字符串,它 returns 一个新副本。因此,您返回的计数是 wordCountTemp[i].innerHTML.split(" ").length.

您的原代码:(带注释)

function() {
    var wordCounts;
    var wordCountTemp = document.querySelectorAll("#text-block-10, #text-block-12");
    var i;
    for(i = 0; i < wordCountTemp.length; i++){
        wordCounts = wordCountTemp[i].innerHTML;
        wordCounts.replace(/(^\s*)|(\s*$)/gi,"");  //Has no effect
        wordCounts.replace(/[ ]{2,}/gi," ");       //Has no effect
        wordCounts.replace(/\n /,"\n");            //Has no effect

        //This next line returns your result in the first pass through the loop.
        //  Only the first element returned by querySelectorAll is acted upon.
        //  No other element is processed other than the first one.
        return wordCounts.split(" ").length; 
    }
}

注意:我正在更改innerHTML to textContent. I'm assuming that you only want to count the words which are text (i.e. not HTML code, scripts, etc.). I also changed the variable name wordCountTemp to nodeList as that is more descriptive of what it is (it is, in fact, a NodeList)

要使用与您正在使用的类似的结构:

function countWords() {
    var wordCounts;
    var totalWordCount=0;
    var nodeList = document.querySelectorAll("#text-block-10, #text-block-12");
    for(var i = 0; i < nodeList.length; i++){
        wordCounts = nodeList[i].textContent;
        wordCounts = wordCounts.replace(/(^\s*)|(\s*$)/gi,"");
        wordCounts = wordCounts.replace(/[ ]{2,}/gi," ");
        wordCounts = wordCounts.replace(/\n /,"\n");
        totalWordCount += wordCounts.split(" ").length;
    }
    return totalWordCount; //return the total count after all passes through loop
}

与其一遍又一遍地将每个 replace 的结果分配给 wordCounts 以逐步修改它,不如直接对 replace 返回的新字符串进行操作:

function countWords() {
    var totalWordCount=0;
    var nodeList = document.querySelectorAll("#text-block-10, #text-block-12");
    for(var i = 0; i < nodeList.length; i++){
        totalWordCount += nodeList[i].textContent
                                     .replace(/(^\s*)|(\s*$)/gi,"")
                                     .replace(/[ ]{2,}/gi," ")
                                     .replace(/\n /,"\n")
                                     .split(" ").length;
    }
    return totalWordCount; //return the total count after all passes through loop
}

相对来说,使用正则表达式是昂贵的。不是那么多,但在这种情况下没有理由不优化。与其对每个元素执行所有 replace 函数,不如在循环内连接 textContent 返回的字符串更有效。然后,在您拥有一个包含所有元素的所有文本的大长字符串之后,您可以执行一次 replacesplit 操作。

function countWords() {
    var allText='';
    var nodeList = document.querySelectorAll("#text-block-10, #text-block-12");
    for(var i = 0; i < nodeList.length; i++){
        allText += ' ' + nodeList[i].textContent;
    }
    //return the total count after getting the textContent from all elements
    return allText.replace(/(^\s*)|(\s*$)/gi,"")
                  .replace(/[ ]{2,}/gi," ")
                  .replace(/\n /,"\n")
                  .split(" ").length;
}

注意:以上所有假设 querySelectorAll 返回的元素中的 none 是返回的其他元素的子元素。如果是,您将计算相同的文本两次。