( Примечание: Когда я отправил этот ответ, в вопросе была опечатка, из-за которой казалось, что связывание / открепление будет в порядке, если не задействованы тайм-ауты.)
Я не вижу необходимости в тайм-аутах, просто привязывайте / отменяйте привязку соответствующим образом:
this.bind(startEvent, start);
function start() {
$(this).unbind(startEvent).bind(stopEvent, stop);
}
function stop() {
$(this).unbind(stopEvent).bind(startEvent, start);
}
В приведенном выше примере я предполагаю, что startEvent
- это настроенное имя стартового события (и я, вероятно,добавьте к нему пространство имен, например, пользователь передает "click"
, но вы добавляете к нему ".niftyplugin"
, в результате чего startEvent
содержит "click.niftyplugin"
, так что вы можете связывать / отменять привязку по желанию), а stopEvent
- настроенное событие остановкиname (с пространством имен).
Вот полный пример с пространствами имен и использованием data
для запоминания опций (вы можете использовать закрытие, если хотите) - живая копия :
// Plugin stuff
(function($) {
$.fn.niftyPlugin = niftyPlugin;
function niftyPlugin(options) {
var data;
data = {
startEvent: (options && options.startEvent || "click") + ".niftyplugin",
stopEvent: (options && options.stopEvent || "click") + ".niftyplugin"
};
this.data("niftyPlugin", data).bind(data.startEvent, start);
return this;
}
function start() {
var $this = $(this),
data = $this.data("niftyPlugin");
$this.unbind(data.startEvent).bind(data.stopEvent, stop);
display("Start");
}
function stop() {
var $this = $(this),
data = $this.data("niftyPlugin");
$this.unbind(data.stopEvent).bind(data.startEvent, start);
display("Stop");
}
function display(msg) {
$("<p>").html(msg).appendTo(document.body);
}
})(jQuery);
// Use
jQuery(function($) {
$("#theButton").click(function() {
$("<p>Non-plugin hook fired</p>").appendTo(document.body);
}).niftyPlugin({
startEvent: "click"
});
});
Единственная другая альтернатива, которую я вижу, это stopImmediatePropagation
- живой пример :
// Plugin stuff
(function($) {
$.fn.niftyPlugin = niftyPlugin;
function niftyPlugin(options) {
var startEvent, stopEvent, running = false;
startEvent = (options && options.startEvent || "click") + ".niftyplugin";
stopEvent = (options && options.stopEvent || "click") + ".niftyplugin";
this.bind(startEvent, start).bind(stopEvent, stop);
return this;
function start(event) {
if (running) {
return;
}
running = true;
display("Start");
event.stopImmediatePropagation();
}
function stop(event) {
if (!running) {
return;
}
running = false;
display("Stop");
event.stopImmediatePropagation();
}
}
function display(msg) {
$("<p>").html(msg).appendTo(document.body);
}
})(jQuery);
// Use
jQuery(function($) {
$("#theButton").click(function() {
$("<p>Non-plugin hook fired</p>").appendTo(document.body);
}).niftyPlugin({
startEvent: "click"
});
});
Мне не нравитсяэто, хотя, потому что это мешает другим обработчикам для события.Например, в приведенном выше примере, если я изменю использование на следующее:
// Use
jQuery(function($) {
$("#theButton").niftyPlugin({
startEvent: "click"
}).click(function() {
$("<p>Non-plugin hook fired</p>").appendTo(document.body);
});
});
... чтобы плагин захватывал события перед кодом, не являющимся плагином, boom , код не подключаемого модуля никогда не видит событие ( пример ).
Так что, несмотря на накладные расходы, я подозреваю, что bind / unbind - ваши друзья здесь.