If the structure at all times is this, with the paragraphs inside the tags a
, then you don’t need to build two arrays to then make one loop in both.
Just search for tags only p
and access the a
through property parentNode
. And to specifically search by class name, you can use getElementsByClassName
(it’s not that it’s "better," it’s just to show an alternative to querySelectorAll
).
And to do the loop by elements, no need to create an array with slice
. If you will not need this array later and will only use it in loop, just use for..of
:
let people = [];
for (const p of document.getElementsByClassName("h6")) {
people.push({ name: p.innerHTML, url: p.parentNode.href });
}
console.log(people);
<a class="link" href="url1.html"><p class="h6">Teste 1</p></a>
<a class="link" href="url2.html"><p class="h6">Teste 2</p></a>
<a class="link" href="url3.html"><p class="h6">Teste 3</p></a>
<a class="link" href="url4.html"><p class="h6">Teste 4</p></a>
<a class="link" href="url5.html"><p class="h6">Teste 5</p></a>
This solution works if each p
is the immediate son of tag a
.
Or, you can do the opposite: search by tags a
and from them seek by the paragraph:
let people = [];
for (const a of document.getElementsByClassName("link")) {
// busca pelo parágrafo a partir da tag "a"
let p = a.querySelector('p[class="h6"]');
people.push({ name: p.innerHTML, url: a.href });
}
console.log(people);
<a class="link" href="url1.html"><p class="h6">Teste 1</p></a>
<a class="link" href="url2.html"><p class="h6">Teste 2</p></a>
<a class="link" href="url3.html"><p class="h6">Teste 3</p></a>
<a class="link" href="url4.html"><p class="h6">Teste 4</p></a>
<a class="link" href="url5.html"><p class="h6">Teste 5</p></a>
Notice that a.querySelector('p[class="h6"]')
search from the tag a
(and not of document
), so I guarantee I’ll only get by the tag p
whose class is "H6" that is within this tag.
This solution is more general because the p
does not necessarily need to be an immediate child of a
: it can be on any level below. Ex:
let people = [];
for (const a of document.getElementsByClassName("link")) {
// busca pelo parágrafo a partir da tag "a"
let p = a.querySelector('p[class="h6"]');
people.push({ name: p.innerHTML, url: a.href });
}
console.log(people);
<a class="link" href="url1.html">
<div>bla
<div>bla
<p class="h6">Teste 1</p>
</div>
</div>
</a>
If you really want to use arrays
I already said in the comments that I would not need to create the arrays, but if the idea is to use them, there are some considerations to be made.
According to the documentation, the use of for..in
nay is recommended to go through arrays. This is because the for..in
does not guarantee the order of the elements, in addition to other problems cited here.
Of course some browsers can return the elements in order, but this is not guaranteed (and even so, it is worth paying attention to the link already quoted). Obviously if the order is not important and the problems of the link already mentioned do not happen, there would be no problem in using for..in
. But if you want to ensure order, an alternative is to iterate the arrays indexes directly, using the for
"traditional".
In the code below I also show 2 different ways to get the arrays: with Array.from
and with spread syntax (I don’t think they’re better or worse than slice
, is just to show other ways to do).
// alternativas à slice
var p = Array.from(document.querySelectorAll("[class='h6']")).map(function(x) { return x.innerHTML });
var a = [...document.querySelectorAll("[class='link']")].map(function(y) { return y.href });
let people = [];
let tamanho = Math.min(a.length, p.length); // pega o tamanho do menor array
for (let i = 0; i < tamanho; i++) {
people.push({ name: p[i], url: a[i] });
}
console.log(people);
<a class="link" href="url1.html"><p class="h6">Teste 1</p></a>
<a class="link" href="url2.html"><p class="h6">Teste 2</p></a>
<a class="link" href="url3.html"><p class="h6">Teste 3</p></a>
<a class="link" href="url4.html"><p class="h6">Teste 4</p></a>
<a class="link" href="url5.html"><p class="h6">Teste 5</p></a>
I also did a treatment in case the arrays are different sizes, in which case the for
only goes until the smallest of arrays is finished. So you don’t need to use hasOwnProperty
, because I am accessing indexes that surely exist in both (and are only the numerical indexes, there is no risk to bring other properties, as can occur with for..in
).
Of course in your case they have equal sizes, because the structure of HTML ensures this (each a
has its respective p
) - but if the structure already guarantees this, I insist again that the arrays would not be necessary and the solutions proposed above are simpler and straightforward (unless, of course, you need to use the arrays to do other things later, then it would make sense to create them).
Important you [Dit] your question and explain objectively and punctually the difficulty found, accompanied by a [mcve] of the problem and attempt to solve. To better enjoy the site, understand and avoid closures and negativities worth reading the Stack Overflow Survival Guide in English.
– Bacco