I am attempting to create a jQuery plugin for my own use that can be used to setup a handler for jQuery mobile dialogs using a single command as such: $('#dialog').setup_dialog({ callback: callback_function });
However, my handler has a rather obvious memory leak due to closures in it:
$.fn.setup_dialog = function( options ) {
var settings = $.extend({
callback : 0
}, options);
var that = this;
return this.live('pagebeforeshow', function(event, ui) {
console.log("outside");
$('form', that).submit( function(e) {
var $inputs = $('form :input', that); // get all form inputs
var values = {};
$inputs.each(function() {
values[this.name] = $(this).val();
});
that.dialog('close');
if ( settings.callback && typeof(settings.callback) === "function" ) {
$('#'+ui.prevPage[0].id).live('pagebeforeshow', function() {
settings.callback(values, that);
console.log("inside");
});
}
return e.preventDefault();
});
});
}; /* setup_dialog */
If you ran the above code, you would see “inside” and “outside” printed first once, then three times (twice from a single submit), then six times (three times from a single submit), etc.
The intent of the code is to attach an event handler to the jQuery Mobile dialog when it comes up that will catch form submission, collect all the form values, and then pass them to a callback function that will modify the original page (that launched the dialog).
Note that because of the way jQuery Mobile uses AJAX to switch between pages, I need to use .live to bind the events (.bind or .one won’t work).
Any ideas how I can avoid the events accumulating (and maybe clean up the code a bit as well)?
The solution appears to be the following:
There were multiple ways to do this, including creating a closure and calling
$('#'+ui.prevPage[0].id).die().live('pagebeforeshow', function() {Not convinced this is the nicest solution though, so I’d love to hear some better ideas.