0

I'm writing a function to gather all anchor elements and write listeners for them. If I refresh the browser (latest versions of Chrome and Firefox on Mac), sometimes the collection of elements is displayed differently and causes my call to Array.prototype.slice to return an empty array.

function toArray(arr) { return Array.prototype.slice.call(arr); }

let anchors = toArray(document.getElementsByTagName('a'));
for (var i = 0; i < anchors.length; i++) 
{ 
    anchors[i].addEventListener('click', clicked, false); 
}
console.log(document.getElementsByTagName('a'));
console.log(anchors);

When working properly (the listeners are added), the console looks like this: correct console output

But when I refresh the browser, much of the time it comes back looking like this: incorrect console output

If I expand the array output, it looks like this: enter image description here enter image description here

Why are they sometimes different? Is there a way to always get the correct result?

2 Answers2

1

Your script should wait for the page to finish loading before any call to getElementsByTagName. Otherwise, many a elements may not have been loaded yet, and getElementsByTagName will not retrieve them.

So, wrap your code in an onload event handler, e.g.:

onload = function() {
    let anchors = toArray(document.getElementsByTagName('a'));
    for (var i = 0; i < anchors.length; i++) 
    { 
        anchors[i].addEventListener('click', clicked, false); 
    }
    console.log(document.getElementsByTagName('a'));
    console.log(anchors);
}
Anis R.
  • 5,631
  • 2
  • 8
  • 31
0

Per the feedback from Anis, I wrapped the code in a function called writeListeners() and tried calling it two different ways:

  1. Adding an onload attribute for the script itself in the header and <script onload="writeListeners();" src="file"></script> Didn't work because the script was loading before DOM completed.

  2. Part of an existing DOMContentLoaded function at the end of the file. document.addEventListener('DOMContentLoaded', () => {writeListeners();}); At first this failed because writeListeners was not yet defined. This was happening because the script that contains the function was tagged with async and loading after DOMContentLoaded. I removed the async tag to ensure the script loads earlier and now it works.