Reputation: 2359
I have a problem with a content overlay script I am developing. It seems that my closing event fires twice, but returns 'undefined' the first time (or second time, depending on which opening link you click).
You can find a stripped-down working example on JSFiddle: http://jsfiddle.net/UhSLy/2/
If you click on 1. Click and then on 2. Click it alerts undefined first, then Dummy.
When I delete one opening-link, everything works fine. But I have to have multiple links since they open different overlays.
What causes the problem and how can I avoid it?
Edit: Code from JSFiddle follows:
;(function ($, window, document, undefined) {
"use strict";
var pluginName = 'contentOverlay',
defaults = {
property: 'value'
};
function Plugin(element, options) {
this.element = element;
this.$element = $(element);
this.options = $.extend({}, defaults, options);
this.init();
}
Plugin.prototype = {
/**
* Init
*/
init: function () {
var self = this;
// Bind opening method
this.$element.click(function() {
self.open();
});
// Bind closing method
$('#close').click(function() {
self.close();
});
},
/**
* Open
*/
open: function () {
this.overlay = 'Dummy';
},
/**
* Close
*/
close: function () {
alert(this.overlay); // <==== PROBLEM: fires twice. returns 'undefined' once
},
};
$.fn[pluginName] = function (options) {
return this.each(function () {
if (!$.data(this, 'plugin_' + pluginName)) {
$.data(this, 'plugin_' + pluginName,
new Plugin(this, options));
}
});
}
$(function () {
$('.open').contentOverlay();
});
})(jQuery, window, document);
Upvotes: 4
Views: 4554
Reputation: 146191
I've came up with this (only the changes here)
open: function () {
this.overlay = 'Dummy';
this.opened=true;
},
$('#close').click(function() {
if(self.opened)
{
self.opened=false;
self.close();
}
});
I think code explains everything. The close
event will never fire if an instance doesn't exist.
Upvotes: 0
Reputation: 34107
If I may suggest look in here: http://jsfiddle.net/PgbfN/25/
I reckon your this if
condition which is to check if plugin is initialised is undefined
hence runs through twice.
To resolve I added isApplied
flag, once applied set the flag to true
. Rest hope demo will help :)
Hope it helps
$.fn[pluginName] = function(options) {
return this.each(function() {
alert('me ==> ' + (!$.data(this, 'plugin_' + pluginName)) + " ==== " + $.data(this, 'plugin_' + pluginName));
if (!isApplied) {
$.data(this, 'plugin_' + pluginName, new Plugin(this, options));
}
});
}
full code
var isApplied = false;
(function($, window, document, undefined) {
"use strict";
var pluginName = 'contentOverlay',
defaults = {
property: 'value'
};
function Plugin(element, options) {
this.element = element;
this.$element = $(element);
this.options = $.extend({}, defaults, options);
isApplied = true;
this.init();
}
Plugin.prototype = {
/**
* Init
*/
init: function() {
var self = this;
// Bind opening method
this.$element.click(function() {
self.open();
});
// Bind closing method
$(document).on('click', '#close', function() {
alert('Close is clicked');
//self.close(); //<<== Is called
});
},
/**
* Open
*/
open: function() {
this.overlay = 'Dummy';
},
/**
* Close
*/
close: function() {
alert(this.overlay); // <==== PROBLEM: fires twice. returns 'undefined' once
},
};
$.fn[pluginName] = function(options) {
return this.each(function() {
alert('me ==> ' + (!$.data(this, 'plugin_' + pluginName)) + " ==== " + $.data(this, 'plugin_' + pluginName));
if (!isApplied) {
$.data(this, 'plugin_' + pluginName, new Plugin(this, options));
}
});
}
$(function() {
$('.open').contentOverlay();
});
})(jQuery, window, document);
Upvotes: 0
Reputation: 16961
$('#close').click(function() {
self.close();
});
You're binding both objects close()
methods to the close handler. Basically, when you click on the close button, it's running two functions, one for each of the overlay objects. Because one overlay object doesn't exist, it's returning undefined
.
You could get around this problem by:
close: function () {
if(this.overlay != undefined){ // Skips over the undefined overlays
alert(this.overlay);
}
}
DEMO: http://jsfiddle.net/UhSLy/9/
Upvotes: 3