Лучший способ определить обратный вызов и сразу его запустить? - PullRequest
2 голосов
/ 28 июня 2011

В jQuery я так много делаю:

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

Отлично работает, когда селектор находит только один элемент, но я не хочу, чтобы он срабатывал более одного раза, если найдено более одного совпадения.

Есть ли какой-нибудь способ объявить анонимную функцию и выполнить ее ровно один раз за один проход?

Или вам нужно сделать его неанонимным (дать ему имя), передать его и вызвать его один раз вручную?


Например, я могу связать событие .change с набором переключателей. В обратном вызове я проверяю, какой из них действительно установлен, а затем показываю / скрываю div. Когда страница загружается, div должен быть в правильном состоянии, поэтому я запускаю событие один раз и позволяю JS выяснить, следует ли показывать его. Но я не хочу, чтобы он срабатывал 3 раза, потому что у меня 3 переключателя.

Ответы [ 3 ]

6 голосов
/ 28 июня 2011

Используйте метод triggerHandler() [документы] вместо trigger() [документы] метод.

Это вызовет обработчик только один раз и не позволит событию всплыть или вызвать поведение по умолчанию.

Из документов:

Метод .triggerHandler () ведет себя аналогично .trigger () со следующими исключениями:

  • Метод .triggerHandler () не вызывает методПоведение события по умолчанию (например, отправка формы).
  • Хотя .trigger () будет работать со всеми элементами, сопоставленными с объектом jQuery, .triggerHandler () влияет только на первый соответствующий элемент.
  • События, созданные с помощью .triggerHandler (), не всплывают в иерархии DOM;если они не обрабатываются целевым элементом напрямую, они ничего не делают.
  • Вместо того, чтобы возвращать объект jQuery (чтобы разрешить сцепление), .triggerHandler () возвращает любое значение, которое было возвращено последним обработчиком, который он вызвалказнены.Если ни один обработчик не запущен, он возвращает undefined
2 голосов
/ 28 июня 2011

Если единственная проблема заключается в том, что селектор соответствует более чем одному элементу, просто используйте .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);
1 голос
/ 28 июня 2011

Я могу придумать два способа определить анонимную функцию и вызвать ее одновременно.

Первый - заставить функцию возвращать себя, используя значение 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());
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...