How to set a jquery on() function only if it doesn't already existis?

2.8k Views Asked by At

I'm calling via ajax additional content where I add a jquery on() function for a click event. Each time I renew the content the event is also set again so at the end it get executed several times. How can I avoid this behavior?

How do I test if the click event is already set on the document?

<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>
<a href="#" class="open-alert">Click</a>
<script>
    // first ajax load
    $(document).on('click', '.open-alert', function () {
        alert('hello world!');
    });

    // second ajax load
    $(document).on('click', '.open-alert', function () {
        alert('hello world!');
    });
</script>

I already try to just the jQuery.isFunction(), but I don't anderstand how to apply it in this case.

5

There are 5 best solutions below

3
Mokkun On

Using

$(document).on('click', '#element_id', function() {
    //your code
});

Will check the DOM for matching elements every time you click (usually used for dynamically created elements with ajax)

But using

$('#element_id').on('click', function() {
    //your code
});

Will only bind to existing elements.

If you use the 1st example, you only need to call it once, you can even call it before your ajax call since it will recheck for matching elements on each click.

<script>
    $(document).on('click', '.open-alert', function () {
        alert('hello world!');
    });

    // first ajax load
    // second ajax load
    ...
</script>
4
Saeed Ahmadian On

jQuery check if event exists on element : $._data( $(yourSelector)[0], 'events' )

this return all of element events such : click , blur , focus,....

Important Note: $._data when worked that at least an event bind to element.

so now:

1.in your main script or first ajax script bind click event on element

<script>
   $(document).on('click', '.open-alert', function () {
      alert('hello world!');
   });
</script>

2. in secound ajax:

var _data =  $._data( $('.open-alert')[0], 'events' );
if(typeof _data != "undefined"){
    var eventClick = $._data( $('.open-alert')[0], 'events' ).click
    var hasEventClick = eventClick != null && typeof eventClick != "undefined";
    if(!hasEventClick){
         $(document).on('click', '.open-alert', function () {
             alert('hello world!');
         });
    }
}
2
a.barbieri On

In case you cannot bind the event to the specific DOM element (which might happen if you use Turbolinks for example) you can use a variable to check whether you set the event or not.

Local scope

var clickIsSet = false;

// any ajax load
$(document).on('click', '.open-alert', function () {
    if ( clickIsSet ) {
        alert('hello world!');
        clickIsSet = true;
    }
});

Global scope

I don't recommend to make clickIsSet global, but in case you are importing/exporting modules you can do that:

// main.js
window.clickIsSet = false;

// any-other-module.js
$(document).on('click', '.open-alert', function () {
    if ( window.clickIsSet ) {
        alert('hello world!');
        window.clickIsSet = true;
    }
});
0
Asav Vora On

I get Confuse about your question but as far as understand your question I have three suggestions:

  1. Use Id element (as @Mokun write the answer)
  2. Use Common Function for call functionality instead use through the click event.(Make Sure of function does not overwrite your content by calling).
  3. Use of flag variable (or global variable for your tracking event) in jquery and identify your function call for particular execution.
0
Asif Raza On

You can Unbind the click event , if you getting more than one time exectuated.

$(document).unbind('click').on("click", ".open-alert", function () {
  //do stuff here
 });

Or you can also use it

$(document).off("click", ".open-alert").on("click", ".open-alert", function () { 

  });