Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

document.getElementsByTagName("a") misses a link

Edit: it's been ages since I've ran into this "issue" back then, and by now it's even simpler

for (const link of links) { }

I was working on a script for Greasemonkey (FX7) trying to remove certain links and found out that for some reason one that was present in the source, not hidden or constructed by JS, didn't show up in the array that that function returns.

If that one would have been constructed via JS upon running that page it wouldn't wonder me but it's sitting right behind another link that gets found.

So has anyone an idea why this is happening and how I could work around it?

var links = document.getElementsByTagName("a");
for (var l in links){
  if (links[l].href == "blah"){ ... }
}

Thats how I was trying to work with them, a bit cut down as I had some more checks to not run into nulls and such.

On a sidenote: I was wondering why that function also returns null entries at all.

Edit: I passed this problem long since I asked for help and found a nice way to do it:

for (var i = 0, l; l = links[i]; i++) { }

This keeps setting l to the current link until there aren't any left. Works nice.

like image 565
BloodyRain2k Avatar asked Nov 07 '25 15:11

BloodyRain2k


2 Answers

The for...in statement loops through the properties of an object. In this particular case you are iterating over Array object properties. Try to use this script instead:

var links = document.getElementsByTagName("a");
for (var l = 0; l < links.length; l++){
  if (links[l].href == "blah"){ ... }
}
like image 109
Yuriy Rozhovetskiy Avatar answered Nov 10 '25 04:11

Yuriy Rozhovetskiy


for … in statements loop through the properties of an object, not only its values, just like @Yuriy said. You'll need to learn some Javascript to understand this (sorry, couldn't find any direct pointer to this part after a few minutes of Googling).

Basically, you need to understand that objects in JS also include “methods”. When you're using a for … in loop, you find an object's values but also its “methods” and other properties.

So, either use @Yuriy's indexed loop… or better, use the hasOwnProperty() method (MDN doc), that allows to avoid the very important caveat @Kolink mentioned.

Your loop should look like:

var links = document.getElementsByTagName('a');
for (var l in links) {
    if (! links.hasOwnProperty(l))
        continue; // this goes straight to the next property

    if (links[l].href == "blah") { ... }
}
like image 44
MattiSG Avatar answered Nov 10 '25 04:11

MattiSG



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!