3

My task is to convert all jquery code to es6 compatible code.

Example:

  • Jquery

    $('.class1 .class2').on('click', function(e) {
         // logic here
    }
    
  • ES6 Compatible

    const test = document.querySelector('.class1 .class2');
    test.addEventListener('click', (e) => {
    //logic here
    });
    

This works fine, but I am unable to convert dom click events which are registered later.

Example:

  • Jquery

    $(document).on('click', '.class1 .pagination a', 
        function(e) {
         //logic here
    })
    

What I am trying to do :

var classname = document.querySelectorAll(".class1 .pagination a");

Array.from(classname).forEach(function(element) {
  element.addEventListener('click', (e)=>{
    e.preventDefault();
    alert(e);
  });
});

Here class .class1 .pagination a is registered later so classname is getting empty . But using jquery $(document).on('click', '.class1 .pagination a') it is working correctly.

Any pointer on how to convert $(document).on('click', '.class1 .pagination a') like events to es6 ?

Zakaria Acharki
  • 63,488
  • 15
  • 64
  • 88
Aditya
  • 401
  • 1
  • 7
  • 17
  • 2
    So the short question you are asking, and could google for on google or on stackoverflow, is "how to make a delegate event binding in javascript" – Taplar Oct 04 '18 at 14:36
  • I don't know why you are using array. – Negi Rox Oct 04 '18 at 14:45
  • 1
    Possible duplicate of [What is DOM Event delegation?](https://stackoverflow.com/questions/1687296/what-is-dom-event-delegation) – Taplar Oct 04 '18 at 14:45
  • Specifically answer https://stackoverflow.com/a/33015903/1586174 shows some snippets of delegate logic – Taplar Oct 04 '18 at 14:46

2 Answers2

3

You can use event delegation by checking the event target using Element.matches():

const delegate = (container, evtType, targets, cb) => {
  const cont = (container === document || container instanceof HTMLElement) ?
    container : document.querySelector(container);

  if (!container) throw new Error('Event container not found');

  document.addEventListener(evtType, e => {
    if (!e.target.matches(targets)) return;

    cb(e);
  });
}

delegate(document, 'click', 'span, .class, #id, .container .inner a', (e) => console.log(e.target.innerText));
<div class="class">A class</div>
<div id="id">An id</div>
<span>An element</span>
<div class="container">
  <div class="inner"> <a href="#">Nested Selectors</a></div>
</div>

<div>Not delegated</div>
Ori Drori
  • 145,770
  • 24
  • 170
  • 162
2

You could attach the event to the document and filter by your selector using matches() function like:

document.addEventListener('click', clickEvent)

function clickEvent() {
  if (!event.target.matches('.class1 .pagination a')) return
  console.log(event.target)
}

//--JUST FOR DEMO START
setTimeout(function() {
  $('ul').append("<li class='class1'><div class='pagination'> <a href='#'>Coffe</a></div></li>");
}, 1000);
//--JUST FOR DEMO END

document.addEventListener('click', clickEvent)

function clickEvent() {
  if (!event.target.matches('.class1 .pagination a')) return
  console.log(event.target)
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>

<ul class=”characters”>
  <li class='class1'>
    <div class='pagination'> <a href="#">Milk</a></div>
  </li>
  <li class='class2'>
    <div class='pagination'> <a href="#">Tea</a></div>
  </li>
</ul>
Zakaria Acharki
  • 63,488
  • 15
  • 64
  • 88