Jamie
Jamie

Reputation: 371

jQuery plugin multiple instances, bind event only once

I am writing a jQuery plugin and ran into a interesting problem where I wanted to bind an event in the plugin onto body and delegate down to a specific child element.

This was no problem, however the plugin is built to support multiple instances on the same page, which leads to the event being fired the number of times the plugin exists on the page. (It's been bound that many times)

Other than a boolean flag that is attached to window, is there anyway to only bind once, from within the plugin code?

I can fix the problem by either binding outside the plugin code so it is only bound once, or by making sure the timer is set only once, however I'd prefer to not have the event get fired 20 times. I'm looking more for if there is another way..

Possible Solution

if (!window.tip.hoverIntent || window.tip.hoverIntent === undefined) {
    //bind handler..
    window.tip.hoverIntent = true;
}

Event Handler

$('body').on({
    mouseenter: function() {
        clearTimeout(window.tip.timerID);
    },
    mouseleave: function() {
        window.tip.timerID = setTimeout(function() {
            $('.tip-shown').remove();
        }, 250);
    }
}, '.tip-shown');

Upvotes: 1

Views: 561

Answers (2)

jcubic
jcubic

Reputation: 66490

You can use a flag outside of the plugin function

var first_time = true;
$.fn.my_plugin = function() {
    if (first_time) {
        first_time = false;
        $('body').on({
            mouseenter: function() {
                clearTimeout(window.tip.timerID);
            },
            mouseleave: function() {
                window.tip.timerID = setTimeout(function() {
                    $('.tip-shown').remove();
                }, 250);
            }
        }, '.tip-shown');

    }
};

Upvotes: 1

bastianwegge
bastianwegge

Reputation: 2498

you could try to evaluate if your handler was already called before and then break. Like the following:

function eventHandler(e)
{
  if(e.handled !== true)
  {
    e.handled = true;
  }
  return false;
}

That should fire your event only once.

Upvotes: 0

Related Questions