73

So maybe I'm just not looking in the right places but I can't find a good explanation of how to do the equivalent of jQuery's

$('a').click(function(){
    // code here
});

in plain old JavaScript?

Basically I want to run a function every time an a tag is clicked but I don't have the ability to load jQuery into the page to do it in the way above so I need to know how to do it using plain JavaScript.

7 Answers 7

76
element.addEventListener('click', function() { ... }, false);

You have to locate the elements and make a loop to hook up each one.

Sign up to request clarification or add additional context in comments.

Comments

68

Working Example: http://jsfiddle.net/6ZNws/

Html

<a href="something">CLick Here</a>
<a href="something">CLick Here</a>
<a href="something">CLick Here</a>

Javascript:

var anchors = document.getElementsByTagName('a');
for(var z = 0; z < anchors.length; z++) {
    var elem = anchors[z];   
    elem.onclick = function() {
        alert("hello");
        return false;
    };
}

1 Comment

I disagree. IMHO you may destroy the previous bound function. To use "addEventListener" is far better I think.
21
document.getElementById('elementID').onclick = function(){
      //click me function!
}

1 Comment

Ah... should have pointed out I wont know the 'a' tags or ids upfront so need to just say "For ANY a tag clicked....."
20

Try the following

var clickHandler = function() { 
  // Your click handler
};

var anchors = document.getElementsByTagName("a");
for (var i = 0; i < anchors.length; i++) {
  var current = anchors[i];
  current.addEventListener('click', clickHandler, false);
}

Note: As Ӫ_._Ӫ pointed out this will not work on IE8 and lower as it doesn't support addEventListener.

On IE8 you could use the following to subscribe to onclick. It's not a perfect substitute as it requires everyone to be cooperative but it may be able to help you out

var subscribeToOnClick = function(element) {
  if (element.onclick === undefined) {
    element.onclick = clickHandler;
  } else {
    var saved = element.onclick;
    element.onclick = function() {
      saved.apply(this, arguments);
      clickHandler.apply(this, arguments);
    }
  }
}

for (var i = 0; i < anchors.length; i++) {
  var current = anchors[i];
  subscribeToOnClick(current);
}

9 Comments

Don't create functions inside of a loop. It's better to create the function outside of the loop and reference the function inside the loop.
@PeterOlson mainly I was trying to replicate the style of the original question. I'll update it to be more correct in this sense
Should probably be noted that IE8 and lower don't support addEventListener.
@Ӫ_._Ӫ what is the alternative for IE8?
Well, there isn't an exact alternative. They do have attachEvent, but it doesn't accept the 3rd argument to set bubbling/capturing (bubbling is default), and it doesn't set this as the element that invoked the handler, but there are workarounds for that using closures.
|
13

Here you go:

[].forEach.call( document.querySelectorAll( 'a' ), function ( a ) {
    a.addEventListener( 'click', function () {
        // code here
    }, false );
});

Live demo: http://jsfiddle.net/8Lvzc/3/

(doesn't work in IE8)

Also, I recommend event delegation...

2 Comments

Do you have a reason for not using [].forEach.call(...)?
@pimvdb Well, call isn't suitable since a function has to be passed into forEach. One would have to use apply, so: [].forEach.apply( ..., [ function () {} ] );. The [ function () {} ] notation is a bit to strange for my taste...
6

I just stumbled upon this old question.

For new browsers (find support here: https://caniuse.com/?search=querySelectorAll)

My solution would be:

function clickFunction(event) {
  // code here
}

for (let elm of document.querySelectorAll("a")) {
  elm.addEventListener('click', clickFunction);
}

This is optimized to not create a new function for each element. This will add an "click" eventListener to each element, so if you do this more than once, several eventListeners for each element will be called.

To replace/set the "click" eventListener use the following code:

for (let elm of document.querySelectorAll("a")) {
  elm.onclick = clickFunction;
}

Will work on IE9 and up.

4 Comments

It's easier to read but it's not optimized in any way. You're still effectively looping through the array of a elements. For loops are faster than forEach
You are right! I was distracted by some reading I did. The slicker solution is using a for of loop. (edited my solution),
this is cool, but i noticed it will overwrite any existing onclick handler
You are right. This will set the onclick event handler instead of adding another one. I updated my solution
3

This will assign an onclick function to every a element.

var links = document.getElementsByTagName("a");
var linkClick = function() {
  //code here
};

for(var i = 0; i < links.length; i++){
  links[i].onclick = linkClick;
}

You can see it in action here.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.