定义回调并立即触发它的最佳方法是什么?

时间:2011-06-27 22:47:27

标签: javascript javascript-events

在jQuery中,我做了很多这样的事情:

$('#myId').bind('myevent', function() { ... }).trigger('myevent');

当选择器只找到一个元素时效果很好,但如果有多个匹配,我不希望它多次触发。

是否有某种方法可以基本上声明一个匿名函数并一次性执行一次?

或者您是否必须将其设为非匿名(给它起个名字),传入,然后手动调用一次?


例如,我可能会将.change事件绑定到单选按钮集。在回调中,我检查实际设置了哪一个,然后显示/隐藏div。当页面加载时,div需要处于正确的状态,所以我触发事件一次,让JS弄清楚它是否应该显示。但我真的不想要它发射3次,因为我有3个单选按钮。

3 个答案:

答案 0 :(得分:6)

使用triggerHandler()[docs]方法代替trigger()[docs]方法。

这将仅调用一次处理程序,并且不允许该事件冒泡或触发默认行为。

来自文档:

  

.triggerHandler()方法的行为   类似于.trigger(),与   以下例外:

     
      
  • .triggerHandler()方法不会导致默认行为   要发生的事件(例如表格)   提交)。
  •   
  • 虽然.trigger()将对jQuery匹配的所有元素进行操作   object,.triggerHandler()只影响   第一个匹配的元素。
  •   
  • 使用.triggerHandler()创建的事件不会冒泡   DOM层次结构;如果他们没有处理   由目标元素直接,他们   什么都不做。
  •   
  • 而不是返回jQuery对象(允许链接),   .triggerHandler()返回任何内容   值由最后一个处理程序返回   它导致被执行。如果不   处理程序被触发,它返回   未定义
  •   

答案 1 :(得分:2)

如果唯一的问题是选择器匹配多个元素,请使用.first()

$('some selector').bind('myevent', function()
{
    // ...
}).first().trigger('myevent');

将此转换为jQuery插件非常简单,您可以像.bind()一样使用它:

$('some selector').bindTrigger('myevent', function () { ... });

插件代码(未测试)

;(function ($)
{
    $.fn.bindTrigger = function ()
    {
        this.bind.apply(this, arguments).first().trigger(arguments[0]);
    };
})(jQuery);

答案 2 :(得分:1)

我可以想到两种方法来定义匿名函数并同时调用它。

第一个是使函数使用arguments.callee值返回自身并在该位置调用函数。一个例子可能会让它更清晰:

el.bind('myevent', (function() {
  ...;
  return arguments.callee; // return the function
})());

第一种方法的问题是,该函数总是返回自身。另一种方法是使用辅助方法扩展Function.prototype,如以下示例所示:

// extend the prototype once somewhere
Function.prototype.invoke = function(){
  this();      // invoke...
  return this; // and return the function
};

// invoke() on an anonymous function now calls the function
// and returns the function instead of the result.
el.bind('myevent', (function(){
  ...
}).invoke());