1

I am in the process of converting a large script from jQuery to JavaScript. This was code that I didn't write myself but that I forked from a project on GitHub.

I've consulted W3Schools, the official documentation and this website as a reference.

http://youmightnotneedjquery.com/

One of the parts I'm trying to convert into JavaScript is the following.

$('body').on('click','.vb',function(){
    exportVB(this.value);
});

According to the aforementioned link,

$(document).on(eventName, elementSelector, handler);

converts to this

document.addEventListener(eventName, function(e) {
    // loop parent nodes from the target to the delegation node
    for (var target = e.target; target && target != this; target = target.parentNode) {
        if (target.matches(elementSelector)) {
            handler.call(target, e);
            break;
        }
    }
}, false);

My attempt is as follows

/*document.addEventListener('click',function(e) {
    for (var target = e.target; target && target != this; target = target.parentNode) {
        if (target.matches('.vb')) {
            exportVB.call(target,e);
            break;
        }
    }
}, false);*/

That evidently didn't work so I did a Google search that brought me to this StackOverflow solution

Attach event to dynamic elements in javascript

document.addEventListener('click',function(e){
    if(e.target && e.target.id== 'brnPrepend'){
          //do something
     }
 });

//$(document).on('click','#btnPrepend',function(){//do something})

Testing that gave me this idea. I commented it out because that apparently didn't work either.

/*document.addEventListener('click',function(e) {
    if (e.target && e.target.className == 'vb') {
        exportVB(this.value);
    }
});*/

Just for reference, the original jQuery function works well.

2 Answers2

1

I solved it.

document.body.addEventListener('click',function(e) {
    for (var target = e.target; target && target != this; target = target.parentNode) {
        if (target.matches('.vb')) {
            exportVB(target.value);
            break;
        }
    }
});

I can't explain how it worked because I didn't write the original code in the first place. But there were two things I change.

  • exportVB.call(target.e) to exportVB(target.value)
  • Removing the false as the last argument.
1

Rather than iterating over each parent element manually, consider using .closest instead, which will return the ancestor element (or the current element) which matches a selector:

document.querySelector('button').addEventListener('click', () => {
  document.body.insertAdjacentHTML('beforeend', '<span class="vb">some span </span>');
});

document.body.addEventListener('click', (e) => {
  if (e.target.closest('.vb')) {
    console.log('vb clicked');
  }
});
<button>add span</button>
CertainPerformance
  • 356,069
  • 52
  • 309
  • 320