简体   繁体   English

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

[英]Best way to define a callback and fire it once immediately?

In jQuery, I do stuff like this a lot: 在jQuery中,我做了很多这样的事情:

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

Works great when the selector only finds one element, but I don't want it to fire more than once if there's more than one match. 当选择器只找到一个元素时工作得很好,但如果有多个匹配,我不希望它多次触发。

Is there some way to basically declare an annonymous function and execute it exactly once all in one swoop? 有没有办法基本上声明一个匿名函数并一次性执行一次?

Or do you have to make it non-annonymous (give it a name), pass it in, and call it once manually? 或者你必须使它成为非匿名(给它一个名字),传递它,并手动调用它一次?


For example, I might bind a .change event to set of radio buttons. 例如,我可能会将.change事件绑定到单选按钮集。 In the callback, I check which one is actually set and then show/hide a div. 在回调中,我检查实际设置了哪一个,然后显示/隐藏div。 When the page loads, the div needs to be in the correct state, so I fire the event once and let the JS figure out whether or not it should be shown. 当页面加载时,div需要处于正确的状态,所以我触发事件一次,让JS弄清楚是否应该显示它。 But I don't really want it to fire 3 times because I've got 3 radio buttons. 但我真的不想要它发射3次,因为我有3个单选按钮。

Use the triggerHandler() [docs] method instead of the trigger() [docs] method. 使用triggerHandler() [docs]方法而不是trigger() [docs]方法。

This will invoke the handler only once, and will not allow the event to bubble or trigger the default behavior. 这将只调用一次处理程序,并且不允许事件冒泡或触发默认行为。

From the docs: 来自文档:

The .triggerHandler() method behaves similarly to .trigger(), with the following exceptions: .triggerHandler()方法的行为与.trigger()类似,但有以下例外:

  • The .triggerHandler() method does not cause the default behavior of an event to occur (such as a form submission). .triggerHandler()方法不会导致事件的默认行为(例如表单提交)。
  • While .trigger() will operate on all elements matched by the jQuery object, .triggerHandler() only affects the first matched element. 虽然.trigger()将对jQuery对象匹配的所有元素进行操作,但.triggerHandler()仅影响第一个匹配的元素。
  • Events created with .triggerHandler() do not bubble up the DOM hierarchy; 使用.triggerHandler()创建的事件不会冒泡DOM层次结构; if they are not handled by the target element directly, they do nothing. 如果它们不是直接由目标元素处理的,它们什么都不做。
  • Instead of returning the jQuery object (to allow chaining), .triggerHandler() returns whatever value was returned by the last handler it caused to be executed. .triggerHandler()不返回jQuery对象(允许链接),而是返回它导致执行的最后一个处理程序返回的任何值。 If no handlers are triggered, it returns undefined 如果没有触发处理程序,则返回undefined

If the only issue is when the selector matches more than one element, just use .first() : 如果唯一的问题是当选择器匹配多个元素时,只需使用.first()

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

It would be very straightforward to turn this into a jQuery plugin, which you'd use just like .bind() : 把它变成一个jQuery插件是非常简单的,你可以像.bind()一样使用它:

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

Plugin code (not tested) 插件代码(未测试)

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

I can think of two ways to define an anonymous function and call it at the same time. 我可以想到两种方法来定义匿名函数并同时调用它。

The first is to make the function return itself using the arguments.callee value and invoke the function at that place. 第一个是使用arguments.callee值使函数返回自身并在该位置调用函数。 An example probably makes it clearer: 一个例子可能会让它更清晰:

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

The problem with this first approach is, that the function always returns itself. 第一种方法的问题是,该函数总是返回自身。 Another approach is to extend the Function.prototype with a helper method as in the following example demonstrates: 另一种方法是使用辅助方法扩展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());

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM