我正在编写一个jQuery插件,其中启动/停止插件的事件是可自定义的,因此潜在的同一个事件既可以启动也可以停止插件(例如,单击以启动并单击以停止)。

这是一种优雅的方法,理想情况下不涉及超时或侦听器的取消绑定和重新绑定(并且不要包含太多“ isPlaying”,“ isBeingStarted”标志等),以确保调用正确的回调

最佳答案

(注意:当我发布此答案时,该问题中有一个错字,只要不涉及超时,似乎绑定/取消绑定就可以了。)

我看不到超时的任何需要,只要适当地绑定/取消绑定即可:

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是已配置的停止事件名称(带有名称空间)。

这是一个完整的示例,其中包含名称空间并使用data记住选项(如果愿意,可以使用闭包)-live copy

// 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-live example

// 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);
  });
});


...因此,插件在非插件代码繁荣之前抢占了事件,非插件代码再也看不到事件(example)。

因此,尽管有很多开销,我怀疑您的朋友在这里是bind / unbind。

10-07 18:59
查看更多