69

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.

pimvdb
  • 151,816
  • 78
  • 307
  • 352
Duck in Custard
  • 1,043
  • 2
  • 10
  • 17

7 Answers7

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

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

Diodeus - James MacFarlane
  • 112,730
  • 33
  • 157
  • 176
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;
    };
}
Shaheen Ghiassy
  • 7,397
  • 3
  • 40
  • 40
Kevin Bowersox
  • 93,289
  • 19
  • 159
  • 189
19

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);
}
JaredPar
  • 733,204
  • 149
  • 1,241
  • 1,454
  • 2
    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. – Peter Olson Sep 26 '11 at 14:34
  • @PeterOlson mainly I was trying to replicate the style of the original question. I'll update it to be more correct in this sense – JaredPar Sep 26 '11 at 14:34
  • Should probably be noted that IE8 and lower don't support `addEventListener`. – user113716 Sep 26 '11 at 14:48
  • 1
    @Ӫ_._Ӫ what is the alternative for IE8? – JaredPar Sep 26 '11 at 14:51
  • 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. – user113716 Sep 26 '11 at 14:52
  • ...of course there's the `onclick` property too if you're only assigning a single handler per element/event. – user113716 Sep 26 '11 at 14:56
  • @Ӫ_._Ӫ updated with a basic `onclick` solution for IE8 usage. Not a perfect substitute but should get the job done for most scenarios. – JaredPar Sep 26 '11 at 15:03
  • +1 but `clickhandler();` should be `clickhandler.apply( this, arguments );` just like you did with the `saved` invocation above it. – user113716 Sep 26 '11 at 15:29
  • @Ӫ_._Ӫ you're right. I was being lazy because the my definition of `clickHandler` didn't use them so I didn't bother passing them. But it's much better to do so. – JaredPar Sep 26 '11 at 15:31
18
document.getElementById('elementID').onclick = function(){
      //click me function!
}
Naftali
  • 144,921
  • 39
  • 244
  • 303
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...

Šime Vidas
  • 182,163
  • 62
  • 281
  • 385
  • 2
    Do you have a reason for not using `[].forEach.call(...)`? – pimvdb Sep 26 '11 at 14:27
  • @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... – Šime Vidas Sep 26 '11 at 14:37
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.

Thomas Psik
  • 81
  • 1
  • 4
  • 1
    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](https://stackoverflow.com/a/43032526/10633285) – Nathan Champion Sep 10 '20 at 19:21
  • 1
    You are right! I was distracted by some reading I did. The slicker solution is using a for of loop. (edited my solution), – Thomas Psik Sep 14 '20 at 13:03
  • 1
    this is cool, but i noticed it will overwrite any existing onclick handler – Raul Nohea Goodness Oct 12 '20 at 06:58
  • You are right. This will set the onclick event handler instead of adding another one. I updated my solution – Thomas Psik Jan 31 '22 at 13:07
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.

Peter Olson
  • 139,199
  • 49
  • 202
  • 242