Подтвердить что ты не робот

JQuery: Chaining on() при использовании делегирования

В старые времена я с большим успехом использовал цепочку вызовов live(), например:

$(".something")
    .live("click", function(e) { ... })
    .live("change", function(e) { ... })
    .live("submit", function(e) { ... });

В эти дни live(), bind() и delegate() были заменены блестящим новым on().

Я попробовал просто заменить live() на on(), что казалось бы очевидным:

$(".something")
    .on("click", function(e) { ... })
    .on("change", function(e) { ... })
    .on("submit", function(e) { ... });

Однако почти так же очевидно, что это не сработает, если вы рассмотрите, как работает on(). Это из http://api.jquery.com/on/:

"Обработчики событий привязаны только к текущим выбранным элементам, они должны существовать на странице в момент, когда ваш код выполняет вызов .on()."

В соответствии с документами jQuery мне нужно привязать к document и делегировать на .something для обработки прямых событий. К сожалению, это означает, что я в конечном итоге повторяю свой селектор делегатов (.document), если я хочу реплицировать то, что у меня выше, с помощью on():

$(document)
    .on("click", ".something", function(e) { ... })
    .on("change", ".something", function(e) { ... })
    .on("submit", ".something", function(e) { ... });

Это работает так, как ожидалось, но мне очень хотелось бы иметь возможность цепочки более четко, как я, используя live(). Я что-то пропустил?

4b9b3361

Ответ 1

Я считаю, что вы можете это сделать:

$(document).on({
    "click" : function(e) { ... },
    "change" : function(e) { ... },
    "submit" : function(e) { ... }
}, ".something");

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

Ответ 2

.live() имеет множество проблем. Один из них состоял в том, что при запуске кода он оценивал селектор ".something", но затем не использовал результат (например, расточительный), а затем переоценивал его во время выполнения, когда произошло событие (как и для правильной работы).

Кроме того, .live() принудительно включил все динамические события в объект document, который мог бы действительно замедлить обработку событий, если у вас было много динамических обработчиков событий. .on(), с другой стороны, позволяет выбрать статический родитель, который намного ближе к реальному объекту и присоединить обработчик события к этому объекту, поэтому различные динамические обработчики событий могут быть прикреплены как ближе к источнику, так и к различным объектам, что делает их производительность во время выполнения намного лучше, когда есть много обработчиков событий.

Итак, вам нужно просто жить с новым способом, который работает .on(), поскольку он намного эффективнее. Для вас не должно быть большого дела, что вам нужно сделать небольшую повторную настройку динамического селектора, если вы используете ту же форму, которую используете сейчас, или вы можете передать карту в качестве первого параметра в .on() и обрабатывать несколько событий в одном вызове .on(). Для получения дополнительной информации см. Вторую форму .on() в jQuery doc для .on().

Здесь простое объяснение использования .on() для динамического поведения.

Ответ 3

Как я понимаю ваш вопрос, вы хотите что-то короткое, как live(). Используя on(), вам нужно написать немного больше, но если .something добавляется динамически, тогда у вас есть еще одна опция, которая также делегирует событие.

var $div = $('<div/>', {
  'class': 'something',
   click: function () { ... },
   change: function () { ... }
})

// Already has events attached
// no need to delegate
$div.appendTo('body')