Javascript: перебирать массив и изменять элементы внутри массива - PullRequest
2 голосов
/ 15 мая 2019

Я пытаюсь настроить функцию на своей странице, которая будет перебирать серию заголовков новостей и зачеркивать заголовок, если он содержит определенный маркер.

Заголовки извлекаются из базы данных постов 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 не определен»

Ответы [ 2 ]

0 голосов
/ 15 мая 2019

Следуйте из моего комментария.
то есть. «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>
0 голосов
/ 15 мая 2019

Мне кажется, я понимаю, что вы пытаетесь сделать, и у вас есть решение. Есть несколько вещей, которые необходимо обновить, чтобы скрипт работал так, как вы описали:

  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 должна использоваться для сброса значения элемента.

Ниже приведен фрагмент кода с некоторыми изменениями.

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>
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...