Я пытаюсь добавить класс CSS к каждому div
на странице, содержащей строку Subject:
Я пытался
var elList = document.querySelectorAll("div");
elList.forEach(function(el) {
if (el.innerHTML.indexOf("Subject") !== -1) {
console.info(el);
el.setAttribute('class', "newClass");
}
});
но он не вернул никаких узлов. А также
var headings = document.evaluate("//*[contains(normalize-space(text()), 'Subject:')]", document, null, XPathResult.ANY_TYPE, null );
while(thisHeading = headings.iterateNext()){
thisHeading.setAttribute('class', "newClass");
console.info(thisHeading);
}
который вернул XPathResult
, у которого, похоже, не было никаких узлов как части объекта.
Так выглядит HTML, хотя он глубоко вложен в тело документа.
<div class = "note-stream-header">Subject: Please Reply to This</div>
Как я могу выбрать все узлы, содержащие строку, и добавить к ним класс с помощью JS?
Я только что залил блок HTML
.
Просто попробовал ваш код, отлично работает. jsfiddle.net/c12ya4nq/1
Хм. Интересно, выполняется ли он до того, как узлы завершат загрузку на странице. Я пытаюсь использовать его как часть расширения Chrome.
Ваш подход хорош, но поскольку вас интересует содержимое элемента, используйте .textContent
вместо innerHTML
.
Смотрите дополнительные комментарии в строке.
// .forEach is not supported in all browsers on node lists
// Convert them to arrays first to be safe:
var elList = Array.prototype.slice.call(
document.querySelectorAll("div"));
elList.forEach(function(el) {
// Use .textContent when you aren't interested in HTML
if (el.textContent.indexOf("Subject") > -1) {
console.info(el);
el.classList.add("newClass"); // Use the .classList API (easier)
}
});
.newClass { background-color:#ff0; }
<div>The subject of this discussion is JavaScript</div>
<div>The topic of this discussion is JavaScript</div>
<div>The queen's royal subjects weren't amused.</div>
<div>Subject: textContent DOM property</div>
Также неплохо использовать classList вместо setAttribute. :-) Но я думаю, что Array.from было бы лучше, чем использовать кусочек. Какова вероятность того, что NodeList не имеет для каждого? Если это проблема, почему бы не Array.prototype.forEach.call(NodeList, ...)
.
@RobG Array.from
- это ECMA 6 и не поддерживается браузерами, которые не поддерживают .forEach
в списках узлов (включая любую версию IE). Вы можете использовать .call()
, но тогда вам придется иметь дело с привязкой this
, в то время как .slice
возвращает массив, который вы можете кэшировать и продолжать использовать после этого одного оператора.
Я не думаю, что это является проблемой, он не определен, если он не передан в обратный вызов. Но если есть необходимость повторно использовать NodeList как массив, кусочек имеет смысл.
Ваш исходный код выглядит так, как будто он находится на правильном пути. Можете ли вы опубликовать полный фрагмент кода с образцом HTML-документа?