在jQuery中,我做了很多这样的事情:
$('#myId').bind('myevent', function() { ... }).trigger('myevent');
当选择器只找到一个元素时效果很好,但如果有多个匹配,我不希望它多次触发。
是否有某种方法可以基本上声明一个匿名函数并一次性执行一次?
或者您是否必须将其设为非匿名(给它起个名字),传入,然后手动调用一次?
例如,我可能会将.change
事件绑定到单选按钮集。在回调中,我检查实际设置了哪一个,然后显示/隐藏div。当页面加载时,div需要处于正确的状态,所以我触发事件一次,让JS弄清楚它是否应该显示。但我真的不想要它发射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());