循环更多querySelectorAll匹配

时间:2016-08-20 00:53:10

标签: javascript google-tag-manager

我试图从两个不同的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;
    }
}

非常感谢你的帮助!

祝你好运, 托尼

2 个答案:

答案 0 :(得分:2)

您在使用querySelectorAll返回的第一个元素之外的任何元素之前,从您的函数中return。此外,replace不会修改字符串,而是返回新副本。因此,您返回的计数是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更改为textContent。我假设您只想计算文本的单词(即不是HTML代码,脚本等)。我还将变量名称wordCountTemp更改为nodeList,因为它更具描述性(它实际上是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返回的元素都不是返回的其他元素的子元素。如果是,你将两次计算同一文本。

答案 1 :(得分:0)

试试这个:

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)