【问题标题】:Get all chars from strings of a CSS class with Vanilla Javascript使用 Vanilla Javascript 从 CSS 类的字符串中获取所有字符
【发布时间】:2021-05-09 23:42:01
【问题描述】:

我编写了一些代码,从类中字符串的所有字符中提取计数。

有没有一种使用 Vanilla JavaScript 的简单方法来获取字符串的所有字符而不调用类的每个元素?

let allNews = "";
    allNews = allNews + document.getElementsByClassName("news-link")[0].innerHTML;
    allNews = allNews + document.getElementsByClassName("news-link")[1].innerHTML;
    allNews = allNews + document.getElementsByClassName("news-link")[2].innerHTML;
    allNews = allNews + document.getElementsByClassName("news-link")[3].innerHTML;
    allNews = allNews + document.getElementsByClassName("news-link")[4].innerHTML;
    allNews = allNews + document.getElementsByClassName("news-link")[5].innerHTML;
    allNews = allNews + document.getElementsByClassName("news-link")[6].innerHTML;
const allChars = allNews.length;
console.log(allChars)
<div class="ticker">
    <div class="news">
        <span><a href="#" class="news-link">OTHER NEWS</a></span>
        <span><a href="#" class="news-link">OTHER NEWS</a></span>
        <span><a href="#" class="news-link">OTHER NEWS</a></span>
        <span><a href="#" class="news-link">OTHER NEWS</a></span>
        <span><a href="#" class="news-link">OTHER NEWS</a></span>
        <span><a href="#" class="news-link">OTHER NEWS</a></span>
        <span><a href="#" class="news-link">OTHER NEWS</a></span>
    </div>
</div>

【问题讨论】:

    标签: javascript character getelementsbyclassname


    【解决方案1】:

    是的:使用循环,计算你真正想要的东西 (allChars)。这还具有更健壮的优势——它可以处理更少的行或更多的行。

    const elements = document.getElementsByClassName("news-link");
    let allChars = 0;
    for (const {innerHTML} of Array.from(elements)) {
        allChars += innerHTML.length;
    }
    console.log(allChars)
    <div class="ticker">
        <div class="news">
            <span><a href="#" class="news-link">OTHER NEWS</a></span>
            <span><a href="#" class="news-link">OTHER NEWS</a></span>
            <span><a href="#" class="news-link">OTHER NEWS</a></span>
            <span><a href="#" class="news-link">OTHER NEWS</a></span>
            <span><a href="#" class="news-link">OTHER NEWS</a></span>
            <span><a href="#" class="news-link">OTHER NEWS</a></span>
            <span><a href="#" class="news-link">OTHER NEWS</a></span>
        </div>
    </div>

    我建议在一般情况下使用textContent 而不是innerHTML,但这取决于你在做什么。

    【讨论】:

    • 谢谢!我可以问你循环的一部分吗?我不知道这部分是如何工作的“const {innerHTML}”
    • @ScottMarcus - 如果您愿意,可以使用 getElementsByClassName。它不会去任何地方,不需要浏览器解析 CSS 选择器,并且浏览器很可能已经有列表可以提供给您。 几乎从不这样做,因为我通常想要快照而不是实时列表,但是...
    • @PlatoRG - 它被称为 destructuring,基本上它从对象中挑选出该属性。所以const {b} = a; 实际上与const b = a.b; 相同。详细信息on MDN(以及我的书的第 7 章 ;-))。
    【解决方案2】:

    先做两件事:

    .getElementsByClassName() 返回一个“实时”节点列表(每次访问它时所有匹配元素都会保持更新的列表),因此具有比“静态”节点列表更高的性能开销(a在您执行搜索时找到匹配元素的列表),因此当您不需要时不要使用活动节点列表。此外,由于活动节点列表的工作方式,从循环中访问一个节点确实会损害性能。相反,使用.querySelectorAll(),它返回一个静态节点列表,您可以立即使用.forEach() 循环其结果。

    另外,.getElementsByClassName()(与许多其他方法一样)返回一个集合,它当然可以被索引,但如果这是您的目标,只需执行一次搜索并获取与变量引用一起存储的集合,然后您就可以连续索引该收藏集随心所欲,无需一遍又一遍地创建收藏集。

    接下来,尽可能避免使用.innerHTML,因为使用它会影响安全性和性能。在您的情况下,您想要查看的字符串中甚至没有任何 HTML,因此无需在此处调用 HTML 解析器。而是使用.textContent 来获取字符串数据。

    将所有这些东西放在一起并使用现代代码,它实际上比您所做的要简单得多:

    let allNews = "";
    // Locate all the elements that use the news-link class and 
    // loop over the collection of them
    document.querySelectorAll(".news-link").forEach(function(link){
      allNews += link.textContent; // Add the character count to the total
    });
    
    console.log(allNews.length);
    <div class="ticker">
        <div class="news">
            <span><a href="#" class="news-link">OTHER NEWS</a></span>
            <span><a href="#" class="news-link">OTHER NEWS</a></span>
            <span><a href="#" class="news-link">OTHER NEWS</a></span>
            <span><a href="#" class="news-link">OTHER NEWS</a></span>
            <span><a href="#" class="news-link">OTHER NEWS</a></span>
            <span><a href="#" class="news-link">OTHER NEWS</a></span>
            <span><a href="#" class="news-link">OTHER NEWS</a></span>
        </div>
    </div>

    【讨论】:

    • "...无需一遍又一遍地创建集合..." 第二次调用 getElementsByClassName 将返回相同的集合.它不会创建一个新的。 document.getElementsByClassName("foo") === document.getElementsByClassName("foo") 是真的。就个人而言,我认为这是一种糟糕的风格,:-) 但它不会每次都创建一个新系列。
    • @T.J.Crowder 这简直让我脑残!一定是因为集合的实时性,因为使用静态节点列表返回false。尽管如此,我认为这是一个很好的建议,即使这里实际上并非如此,因为您仍然必须一遍又一遍地检查活动节点列表,然后在循环中引用它会增加混乱。
    • 非常感谢!这很有启发性。
    • @ScottMarcus - 我第一次学习它的时候也让我大吃一惊。 :-) 是的,querySelectorAll 每次都必须构建一个新的NodeList,因为它是一个快照,但是getElementsBy... 函数会重用现有的实时集合(可能已经存在浏览器自己的目的)。这种重用不是规范要求(它只是说它“may”是同一个集合)但据我所知它是通用的......可能是因为早期的浏览器实现了getElementsByTagName这种方式,人们依赖它。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2013-11-07
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-01-08
    • 2011-02-25
    相关资源
    最近更新 更多