Can jQuery click events be unbound or reset?

2019-08-09 06:09发布

问题:

I've discovered a resource leak on a webpage I'm working on.

This webpage has two textfields, that upon click show a modal dialog, perform a data request to the backend, and then present that information in a table that the user can select an entry from for use in the textbox they originally clicked.

I'm binding the click events to the textboxes like so:

var $field = $('#one-of-the-text-fields');

$field.click(function () {
        App.DialogClass.show();
        App.DialogClass.PopulateTable();
        App.DialogClass.GotoPageButtonAction(actionArgs);  // Offender!
});

...Which calls...

App.DialogClass = (function($) {

var pub {},
    $gotoPage = $('#pageNumberNavigationField'),
    $gotoPageButton = $('#pageNumberNavigationButton');

// ...SNIP unimportant other details...

pub.GotoPageButtonAction = function (args) {
    $gotoPageButton.click(function () {
        var pageNumber = $gotoPage.val();
        pub.PopulateTable(args);   // Breakpoint inserted here...
    });
};

return pub;

})(jQuery);

I noticed the leak because when I ran through using Chrome's JavaScript debugger, I'm always having one extra breakpoint hit every time I click a different button (e.g. the first time I click field A, the breakpoint is hit twice. When I hit field B after that, the break point is hit three times. If I click A after that, the breakpoint is hit four times. Extrapolate as necessary.)

Nowhere in my code am I doing anything about an existing click event for a given field. I suspect my leak stems from the fact that the events are not getting cleaned up. That being said, I am also not terribly familiar with JavaScript/jQuery. What are some techniques for removing click events from a control?

回答1:

Sure. Just unbind them:

$field.unbind('click');

However, bear in mind that this will remove all event handlers for click, not just yours. For safety, you should use namespaces when binding handlers:

$field.bind('click.mynamespace', function(){
    // do something
});

Then,

$field.unbind('click.mynamespace');

So, then, only your handler will be removed.



回答2:

If you have used .bind() to bind them .unbind() removes the events

If you have used .on() to bind them .off() removes the events



回答3:

JQuery offers the unbind function to unbind event listeners.

Note that you may also do it in vanilla JS using removeEventListener.

But instead of unbinding, you probably should not bind each time in GotoPageButtonAction : once is enough.