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) {

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

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

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

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

    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>

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){

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

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.

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