Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Vanilla JS version of jQuery document on click for links?

Is there a pure JS version of this?

$(document).on('click', 'a[href]', function(event) {
  event.preventDefault();
  here.change(this);
});

The specific feature I'm looking for is adding event listeners for any link that's created later via JS (AJAX for example).

like image 450
dougoftheabaci Avatar asked Dec 05 '22 14:12

dougoftheabaci


1 Answers

Modern browsers support matches which makes this a lot easier

document.addEventListener('click', function(event) {
  if (event.target.matches('a[href], a[href] *')) {
    event.preventDefault();
    console.log('works fine')
  }
}, false);

document.body.innerHTML = '<a href="#"><span>Click Me!</span></a><br /><div>not me!</div>';

You could make this more convenient with a simple function

function addEvent(parent, evt, selector, handler) {
    parent.addEventListener(evt, function(event) {
    if (event.target.matches(selector + ', ' + selector + ' *')) {
        handler.apply(event.target.closest(selector), arguments);
    }
  }, false);    
}

Note that closest() is only supported in the latest browsers, there's a polyfill on MDN

This replicates the jQuery behaviour a lot more, and is easier to use, it also sets the value of this correctly

function addEvent(parent, evt, selector, handler) {
  parent.addEventListener(evt, function(event) {
    if (event.target.matches(selector + ', ' + selector + ' *')) {
      handler.apply(event.target.closest(selector), arguments);
    }
  }, false);
}

/* To be used as */

addEvent(document, 'click', 'a[href]', function(e) {
  console.log(this)
});

/* Add a dynamic element */

document.body.innerHTML = '<a href="#"><span>Click Me!</span></a><br /><div>not me!</div>';
like image 127
adeneo Avatar answered Dec 18 '22 06:12

adeneo