【问题标题】:Javascript: Iterate through array and modify items inside the arrayJavascript:遍历数组并修改数组内的项目
【发布时间】:2019-05-15 18:00:49
【问题描述】:

我正在尝试在我的页面上设置一个函数,该函数将遍历一系列新闻标题,如果标题包含特定标记,则会删除标题。

标题从 WordPress 帖子数据库中提取并显示在 <div>ID="news" 中。每个特定标题都是<a>class="title" 的链接。 我首先将所有标题收集到一个数组中,以便可以遍历它们,但由于某种原因,它无法正常工作。

我的代码是:

<script type="text/javascript">
//first I create the array
var test_DOM = document.getElementById("news").getElementsByClassName("title");
//then I set the marker
var marker = "[X]"
//then I wirte the function to iterate through the array://
function checkX() {
for(i in test_DOM){
if (i.includes(marker)) {
i = "<del>", i, "</del>";
console.log(test_DOM[i], "changed")
}
console.log(test_DOM[i].innerHTML)
}
};
//and I call the function
checkX()

预期的结果是看到要更改的新闻列表

[x] News 1
[EG] News 2

[x] News 1 <- struck through
[EG] News 2 <- still the same

但是,什么也没有发生。我知道 getElementsByClassName 给我一个对象数组,我应该使用 .innerHTML 和一些点,但是在函数中使用它,比如

function checkX() {
for(i in test_DOM){
if (i.innerHTML.includes(marker)) {
i.innerHTML = "<del>", i, "</del>";
console.log(test_DOM[i], "changed")
}
console.log(test_DOM[i].innerHTML)
}
};

给出“TypeError: i.innerHTML is undefined”的错误

【问题讨论】:

  • i = "&lt;del&gt;", i, "&lt;/del&gt;"; 不组合字符串,它使用comma operator 并仅返回最后一项。 i 也不是 test_DOM 的每个 value 而是来自 test_DOM 的每个 key
  • 您是否检查了浏览器控制台中的错误?此外,getElementsByClassName() 返回一个“NodeList”对象,而不是预期的数组,因此在其上运行 for in 循环将运行所有属性,而不仅仅是项目索引。 NodeList 对象确实包含一个与索引长度相对应的长度属性,因此像这样的正常 for 循环应该可以工作。 for (i = 0; i &lt; test_DOM.length; i++)
  • @Kik4s 嘿,只是一个友好的提醒,如果它回答了您的问题,请将其标记为“已接受”。如果下面的 2 个现有答案不能完全回答您的问题,您可以发表评论以获得更多说明。谢谢!

标签: javascript arrays loops


【解决方案1】:

我想我了解您想要做什么,并为您提供了解决方案。有一些事情需要更新才能使脚本按照您的描述工作:

  1. 您的 DOM 查询可以使用 document.querySelectorAll 缩短。
  2. 使用String.includes() 时,区分大小写。这意味着[x] 不等于[X],因此请务必检查正确的版本以进行测试。
  3. 正如@2pha 在他们的评论中提到的,test_DOM 将返回一个NodeList,这是一个类似数组的结构,但不完全是一个数组。要将其转换为可以按您的意愿循环的数组,您可以使用[].slice.call(test_DOM)
  4. 正如@VLAZ 在他们的评论中提到的,逗号运算符不会组合字符串。您应该使用'string' + 'string' 语法来组合字符串。
  5. 正如@VLAZ 所提到的,for...in 循环更适用于对象,其中它将输出对象的键,而不是值,因此这不适合您的用例。您可以改用Array.forEach()
  6. 正如您所提到的,Array.includes() 检查应使用innerHTML 进行检查,然后应使用innerHTML 重置元素的值。

我在下面添加了一个带有一些修改的 sn-p。

var test_DOM = document.querySelectorAll('#news .title');
var marker = '[x]';

function checkX() {
  [].slice.call(test_DOM).forEach(function(elem, i) {
    if(elem.innerHTML.includes(marker)) {
      elem.innerHTML = '<del>' + elem.innerHTML + '</del>';
    }
  });
}

checkX()
<div id="news">
  <h1 class="title">[x] News 1</h1>
  <h1 class="title">[EG] News 2</h1>
</div>

【讨论】:

    【解决方案2】:

    继续我的评论。
    IE。 “getElementsByClassName() 返回一个“NodeList”对象,而不是预期的数组”。但确实有一个长度属性。
    对代码进行最小的更改即可使其正常工作。

    //first I create the array
    var test_DOM = document.getElementById("news").getElementsByClassName("title");
    //then I set the marker
    var marker = "[X]"
    //console.log(test_DOM);
    //then I wirte the function to iterate through the array://
    function checkX() {
      for(i = 0; i < test_DOM.length; i++){
        if (test_DOM[i].innerHTML.includes(marker)) {
          test_DOM[i].innerHTML = "<del>" + test_DOM[i].innerHTML + "</del>";
          //console.log(test_DOM[i], "changed")
        }
        //console.log(test_DOM[i].innerHTML)
      }
    };
    //and I call the function
    checkX();
    <div id="news">
    <h2 class="title">title 1</h2>
    <h2 class="title">[X]title 2</h2>
    <h2 class="title">title 3</h2>
    </div>

    【讨论】:

    • jackrugile 的答案比我的更深入(可能应该是公认的答案),但我的答案应该可以让您轻松理解为什么您的特定代码不起作用。
    猜你喜欢
    • 2015-02-23
    • 1970-01-01
    • 2014-10-23
    • 1970-01-01
    • 2012-01-07
    • 2013-06-11
    • 2020-12-23
    • 2015-07-25
    相关资源
    最近更新 更多