0

I am trying to implement a simple mobile menu, but using Nice Menus as my base. So to get things the way the snippet's CSS is set up, I'm using JQuery to dynamically add a <button> element that can be clicked.

Problem is, nothing happens when I click the button. I've checked that my code works fine when the user clicks a <p> element. And I have also confirmed with code that the element to which I'm attaching the click function exists. (But it wasn't working with a $(document) scope either.)

Doesn't work:

$('.nice-menu-main-menu').before('<button class="nav-button">Toggle Navigation</button>');

if ( $('.nav-button').length > 0 ) {
    console.log("nav-button element exists"); // console shows this message
    $('.nav-button').click( function() {
        console.log("menu button clicked"); // never see this message
    });
}

Doesn't work:

$( document ).delegate('.nav-button', 'click', function() {
    console.log("button clicked"); // never see this message
});

Does work:

$( document ).delegate('p', 'click', function() {
    console.log("button clicked"); // console shows this, no problem
});

What magic am I missing? I figure the issue must be with the dynamic aspect of the element, but everything I'm finding in the documentation of JQuery and similar code online suggests this should be working.

1

Drupal.behaviors ensures that the JavaScript code is executed again whenever there are any changes in DOM Elements.

Most JavaScript works by manipulating elements in the HTML DOM. As Such, JavaScript code generally does some extra work to ensure that DOM is fully loaded and elements we want to interact with are available.

The most common way to do this in jQuery is using the $(document).ready() syntax. Placing our code inside this statement will ensure that it is not executed until the DOM has finished loading.

Drupal takes this a step further by using Drupal.behaviors. Along with ensuring that code is not executed until the dom has finished loading, It also ensures that the code is executed again whenever there are any changes in DOM Elements.

So, the Drupal way of handling the click event of a newly added element with a class of nav-button looks like this:

Drupal.behaviors.exampleBehavior = {
  attach: function (context, settings) {
    $('.nav-button',context).click(function(){
      console.log("button clicked");
    });
  }
}
  • Thank you for a fine explanation. Using that lead, I found this article: lullabot.com/articles/… -- which people should visit to understand better Drupals behaviors and binding (and get a great laugh!) This didn't work, however. And the article suggests that regular javascript should be handled no problem. So I'm wondering if perhaps something is grabbing the event before it bubbles to my element. I'm going to mark your answer as the solution, since it appears Drupal is NOT doing anything to block my code. – senortim Apr 25 '18 at 18:54

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.