#javascript #html #getelementsbyclassname #outerhtml
#javascript #HTML #getelementsbyclassname #outerhtml
Вопрос:
У меня возникли проблемы с извлечением определенного фрагмента текста из атрибута класса. Текст имеет как имя, так и идентификатор. Оба важны для меня, но мне нужно, чтобы они были разделены и помещены в отдельные массивы.
<span class="locDescription"><b>Name1</b><br> ID1</span>
<span class="locDescription"><b>Name2</b><br>ID2</span>
<span class="locDescription"><b>Name3</b><br> ID3</span>
Моей первой мыслью было удалить последний элемент в каждом элементе (преобразовать в строку или список, разделить символом » » и удалить последний элемент). Но я понял, что между именем и идентификатором не всегда есть пробел, поэтому это не работает.
Моей второй мыслью было использовать outerHTML и захватить все до <br>
, а затем сделать то же самое с идентификатором после <br>
.
Однако именно так выглядит возвращаемый текст, который использует outerHTML:
"amp;<span class=amp;quot;locDescriptionamp;quot;amp;>amp;<bamp;>Name1amp;</bamp;>amp;<bramp;>ID1amp;</spanamp;>"
Я не мог найти способ просто захватить перед <br>
… это казалось бы чем-то, что можно было бы сделать легко… может быть, я что-то упускаю.
Вместо этого я попытался использовать индексацию для захвата текста:
var product_name = []
var elements = document.getElementsByClassName('locDescription');
for(var i=0; i<elements.length; i ) product_name.push(elements[i].outerHTML)
test1 = product_name[0].indexOf('amp;>amp;<bamp;>')
console.log(test1)
Это вернулось как -1, поэтому оно не интерпретирует искажения в этом тексте. Есть идеи, как я могу это сделать? Я думаю, что в данный момент я спускаюсь в кроличью нору.
Комментарии:
1.
const bs = document.querySelectorAll('.locDescription>b'); for(let b of bs){ console.log(b.textContent); }
2. Похоже, вы забыли ‘R’ из «br» в вашем
.indexOf()
:'amp;>amp;<bamp;>'
Ответ №1:
Селектор запросов и дочерние узлы
const spans = [...document.querySelectorAll(".locDescription")];
const details = spans.map(span => {
const name = span.querySelector("b").textContent;
const id = span.childNodes[2].nodeValue;
return { name, id };
});
console.log(details);
<span class="locDescription"><b>Name1</b><br> ID1</span>
<span class="locDescription"><b>Name2</b><br>ID2</span>
<span class="locDescription"><b>Name3</b><br> ID3</span>
const spans = Array.from(document.querySelectorAll(".locDescription"));
const details = spans.map(function(span){
const name = span.querySelector("b").textContent;
const id = span.childNodes[2].nodeValue;
return { name: name, id: id };
});
console.log(details);
<span class="locDescription"><b>Name1</b><br> ID1</span>
<span class="locDescription"><b>Name2</b><br>ID2</span>
<span class="locDescription"><b>Name3</b><br> ID3</span>
Комментарии:
1. Это работает отлично! К сожалению, GTM не позволяет использовать функции Spread или arrow? Возможно ли добиться того же с помощью другого метода?
Ответ №2:
Вы можете использовать свойства .previousSibling
и .nextSibling
узла, эти свойства включают в себя и другие узлы, то есть текстовые узлы.
Обратите внимание, что вам может потребоваться trim()
.textContent
указать другие нужные вам узлы, поскольку .textContent
возвращает текст в том виде, в каком он написан в вашем HTML после экранирования кодов HTML-имен, что означает включение пробелов и разрывов строк, если таковые имеются.
Вот краткий пример:
- Запрос для
<br>
- Использование
.previousSibling
/.nextSibling
- Получить их
.textContent
- (Необязательно)
trim()
возвращаемый текст
var brElement = document.querySelector('br');
console.log(brElement.previousSibling.textContent.trim());
console.log(brElement.nextSibling.textContent.trim());
<p><b>First text</b><br>
Second text</p>
Ответ №3:
Вы можете использовать регулярное выражение, чтобы найти две стороны:
var element = document.getElementsByClassName("locDescription")[0];
var array = [];
array[0] = element.innerHTML.match(/.*(?=<br>)/)[0];
array[1] = element.innerHTML.match(/(?<=<br>).*/)[0];
console.log(array)
<span class="locDescription"><b>Name1</b><br> ID1</span>
Если вы хотите исключить <b>
теги:
var element = document.getElementsByClassName("locDescription")[0];
var array = [];
array[0] = element.innerHTML.match(/(?<=<b>).*(?=</b>)/)[0]
array[1] = element.innerHTML.match(/(?<=<br>).*/)[0];
console.log(array)
<span class="locDescription"><b>Name1</b><br> ID1</span>