Is Drupal doing something to JQuery delegate or click() that causes the binding to fail? 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 &lt;button&gt; 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 &lt;p&gt; 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('&lt;button class="nav-button"&gt;Toggle Navigation&lt;/button&gt;');

if ( $('.nav-button').length &gt; 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.
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");
    });
  }
}