I am experiencing some issues when attaching event listener to a grandchild.

Both parent click and child click works as expected, only grandchildren clicks won't fire.

Here is my current code:

/* Parent */
$('body').on('click', 'div.left-menu-item', function (e) {
    e.preventDefault();

    console.log('parent'); // <-- this works
});

/* Child */
$('body').on('click', 'div.left-menu-item div.dropdown', function(e){
    e.stopPropagation();
    e.stopImmediatePropagation();

    console.log('child'); // <-- this works
});

/* Grandchild */
$('body').on('click', 'div.left-menu-item div.dropdown-menu.show a.edit', function(e){
    e.stopPropagation();
    e.stopImmediatePropagation();

    console.log('grandchild'); // <-- this does NOT work
});

Markup for the button were the issue is:

<a class="btn edit" data-unsp-sanitized="clean">
    <i class="fas fa-fw fa-pen"></i> <span>Edit</span>
</a>

I've also tried setting the grandchild eventlistener to:

$('body').on('click', 'a.edit', function(e){
    console.log('grandchild'); <-- this doesnt work either
});

New update.

I added a click listener with wildcard so I can listen to all clicks:

$('body').on('click', '*', function(e){
    console.log('clicked');
});

A total of 20 clicks are triggered, but when I click on .edit no clicks are detected still.

If I trigger click manually $('.edit').trigger('click'); it works..

2 Answers

0
Andrew Larsen On Best Solutions

Problem solved.

Inside $(document).ready I created an actual object named document (stupid, right?) which made everything crazy.

So I just renamed var document = ....; to var documentObj = ....; and everything worked as expected.

I am still somewhat confused about why some of the eventlisteners worked. I understand that overriding document is something that shouldn't happen and maybe overriding document caused $('body').on('...', '... to not work as expected since body is a child of document? But that doesn't explain why so many eventlisteners worked and only one did not trigger a click event.

-1
Alfredo Alonso On

You could also tale advantage of event bubbling by attaching the listener only to the parent, and checking who emitted the event (through classes or node name/type).

$('div.left-menu-item').on('click', function(e){

  if( $(e.target).hasClass('dropdown') ) {
    // child logic
  } else if ( $(e.target).hasClass('edit') ) {
    // grandchild logic
  }
});