Reputation: 27
I'm trying to target all of the links in the document. When any link is clicked I want the modal to show. The modal is currently set to display: none. I'm not getting any error messages in console but it still doesn't work. The script link is at the bottom of the html document also. What am I missing?
var a = document.getElementsByTagName('a');
for (i = 0; i < a.length; i++) {
var links = a[i];
}
At this point, var links should equal all links, correct?
links.addEventListener('click', openmodal);
function openmodal(){
modal.style.display = "block";
}
The code below did work but only for the very first link
var links = document.getElementsByTagName('a')[0];
Upvotes: 0
Views: 932
Reputation: 65855
You have a few things to correct. First:
var a = document.getElementsByTagName('a');
for (i = 0; i < a.length; i++) {
var links = a[i];
}
Because you are using var links
inside the loop, you are re-declaring it upon each loop iteration and therefore losing any previous value it might have been storing. The correct thing to do would be to declare it outside of the loop and just use it (without var
) inside the loop:
var a = document.getElementsByTagName('a');
var links;
for (i = 0; i < a.length; i++) {
links = a[i];
}
But, even then, because you are assigning it a value with =
, you are still overwriting the last value stored in the variable with a new one upon each loop iteration. Now, with the code snippet above, it's not entirely clear what you were intending to do.
So, to accomplish your goal of setting each link up to activate the modal, we only need to gather up all the links, iterate over them and while doing so, set up an event handler:
var links = document.getElementsByTagName('a'); // Get all the links
for (i = 0; i < a.length; i++) { // Loop over them
links[i].addEventListener('click', openmodal); // Assign handler to each
}
But, be aware of a few things:
getElementsByTagName()
returns a "live node list" and will
always refer to the most up-to-date set of matching nodes. It works
this way by re-querying the document every time you reference the
node list. If you had 20 links in your document and ran the code
above, it would wind up querying the DOM for all a
elements 21
times!!! Live node lists are only beneficial when you are dynamically
adding/removing elements from a document and always need the most
up-to-date set of matching elements. But, as I've pointed out, you
pay a performance penalty for using them. For that reason, and the
fact that there are better ways to get the same result that don't
incur that hit, live nodes lists should generally be avoided.The best approach is to use event delegation, which entails you setting up an event handler on a higher level element (like document
) and because of event bubbling (which is a process that is going to happen by default anyway, so no additional performance is required), we can handle the event at that higher level. We then just test what the actual element was that triggered the event and act accordingly. This way, we don't have to loop and set up all kinds of event handlers on many elements (which requires resources).
// Set up one event listener at a high level that click events will bubble up to
document.addEventListener("click", testTarget);
function testTarget(event){
// Test to see if the event was triggered by a click to an <a> element
if(event.target.nodeName === "A"){
// It was an <a> element that was clicked, show the modal
showModal();
}
}
Upvotes: 3
Reputation: 89412
You need to add the event listener to each anchor element separately inside the loop or you can use Array.prototype.forEach.
//normal for loop
var a = document.getElementsByTagName('a');
for (i = 0; i < a.length; i++) {
var link = a[i];
link.addEventListener("click", openmodal);
}
//forEach
[].forEach.call(document.querySelectorAll('a'), function(anchor, index){
anchor.addEventListener("click", openmodal);
});
Upvotes: 1
Reputation: 706
You have to add the event listener to each link separately:
var a = document.getElementsByTagName('a');
for (i = 0; i < a.length; i++) {
var links = a[i].addEventListener('click', openmodal);
}
But note that if new links arrive in your document after that, this won't affect the new links so a more resilient version is:
document.addEventListener('click', function(event) {
if (event.target.matches('a[href], a[href] *')) {
event.preventDefault();
openmodal();
}
}, false);
Upvotes: 1
Reputation: 81096
You need to add the event listener in the loop.
function openmodal(){
modal.style.display = "block";
}
var links = document.getElementsByTagName('a');
for (i = 0; i < links.length; i++) {
links[i].addEventListener('click', openmodal);
}
Upvotes: 3