Разница между функциями jQuery `click`,` bind`, `live`,` делегат`, `trigger` и` on` (с примером)? - PullRequest
139 голосов
/ 02 июня 2010

Я прочитал документацию по каждой функции на jQuery official website, но между перечисленными ниже функциями нет таких списков сравнения:

$().click(fn)
$().bind('click',fn)
$().live('click',fn)
$().delegate(selector, 'click', fn)
$().trigger('click') // UPDATED
$().on('click', selector ,fn); // more UPDATED

Пожалуйста, избегайте ссылок.

Как все вышеперечисленные функции в точности работают и какие предпочтения следует использовать в какой ситуации?

Примечание: Если есть какие-либо другие функции, имеющие такую ​​же функциональность или механизм, то, пожалуйста, уточните.

Обновление

Я также видел функцию $.trigger. Работает ли он аналогично вышеуказанным функциям?

Больше обновлений

Теперь .on добавлено в v1.7 , и я думаю, что это как-то покрывает все вышеперечисленные функции вместе.

Ответы [ 5 ]

161 голосов
/ 02 июня 2010

Прежде чем вы прочитаете это, вытащите этот список событий на другой странице, сам API чрезвычайно полезен, и все, что я обсуждаю ниже, связано непосредственно с этой страницы .

Во-первых, .click(function) буквально является сокращением для .bind('click', function), они эквивалентны. Используйте их при привязке обработчика непосредственно к элементу , например:

$(document).click(function() {
  alert("You clicked somewhere in the page, it bubbled to document");
});

Если этот элемент заменить или выбросить, этого обработчика больше не будет. Также элементы, которых не было , когда этот код был запущен для присоединения обработчика (например, селектор нашел его), не получат обработчик.

.live() и .delegate() аналогично связаны, .delegate() фактически использует .live() внутренне, они оба слушать события, чтобы пузыриться. Это работает для новых и старых элементов , они всплывают события одинаково. Вы используете их, когда ваши элементы могут измениться, например, добавление новых строк, элементов списка и т. д. Если у вас нет родителя / общего предка, который останется на странице и не будет заменен в любой момент, используйте .live(), например:

$(".clickAlert").live('click', function() {
  alert("A click happened");
});

Если, однако, у вас есть родительский элемент где-то, который не заменяется (поэтому его обработчики событий не прощаются), вы должны обработать его с помощью .delegate(), например так:

$("#commonParent").delegate('.clickAlert', 'click', function() {
  alert("A click happened, it was captured at #commonParent and this alert ran");
});

Это работает почти так же, как .live(), но событие вспыхивает меньше раз, прежде чем оно будет захвачено и обработчики выполнены. Еще одно распространенное использование обоих: говорят, что ваш класс изменяется на элементе, больше не совпадающем с селектором, который вы изначально использовали ... с этими методами селектор оценивается во время события , если он совпадает , обработчик запускается ... поэтому элемент больше не соответствует селектору, он больше не будет выполняться. Однако с .click() обработчик событий привязан прямо к элементу DOM, тот факт, что он не соответствует тому селектору, который использовался для его нахождения, не имеет значения ... событие привязано и остается пока этот элемент не исчезнет или обработчик не будет удален с помощью .unbind().

Еще одно распространенное использование для .live() и .delegate() - это производительность . Если вы имеете дело с лотами элементов, присоединение обработчика щелчков непосредственно к каждому элементу является дорогостоящим и длительным. В этих случаях более экономичным является установка обработчика single , и пусть пузырьки делают всю работу, взгляните на этот вопрос, где он имеет огромное значение , это хороший пример применения .


Запуск - для обновленного вопроса

Доступны 2 основные функции запуска обработчика событий, они подпадают под одну и ту же категорию «Присоединение обработчика событий» в API , это .trigger() и .triggerHandler(). .trigger('eventName') имеет несколько встроенных ярлыков для общих событий, например:

$().click(fn); //binds an event handler to the click event
$().click();   //fires all click event handlers for this element, in order bound

Вы можете просмотреть список, включающий эти ярлыки здесь .

Что касается разницы, .trigger() запускает обработчик событий (но большую часть времени это не действие по умолчанию, например, установка курсора в нужное место в нажатом <textarea>). Это приводит к тому, что обработчики событий происходят в том порядке, в котором они были связаны (как и собственное событие), запускают собственные действия события и всплывают DOM.

.triggerHandler() обычно для другой цели, здесь вы просто пытаетесь запустить привязанный обработчик (и), это не приводит к возникновению нативного события, например отправка формы. Он не накапливает DOM и не является цепным (он возвращает то, что возвращает обработчик события последней привязки для этого события). Например, если вы хотите вызвать событие focus, но не сфокусировать объект, вы просто хотите запустить код, связанный с .focus(fn), это будет сделано, тогда как .trigger() будет делать это так же, как на самом деле фокусировать элемент и пузыриться.

Вот пример из реального мира:

$("form").submit(); //actually calling `.trigger('submit');`

Это будет запускать любые обработчики отправки, например, плагин проверки jQuery , затем попытаться отправить <form>. Однако, если вы просто хотели проверить, так как он подключен через обработчик событий submit, но не отправлял <form> впоследствии, вы можете использовать .triggerHandler('submit'), например :

$("form").triggerHandler('submit');

Плагин предотвращает отправку формы обработчиком путем бомбардировки, если проверка валидации не проходит, но с этим методом нам все равно, что он делает. Независимо от того, была ли она прервана или нет, мы не пытаемся отправить форму, мы просто хотели вызвать ее для повторной проверки и больше ничего не делать. ( Отказ от ответственности: Это избыточный пример, поскольку в плагине есть метод .validate(), но это достойная иллюстрация намерений)

28 голосов
/ 02 июня 2010

Первые два эквивалентны.

// The following two statements do the same thing:
$("blah").click( function() { alert( "Click!" ); } );
$("blah").bind( "click", function() { alert( "Click!" ); } ); 

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

$("blah").bind( "click mouseover mouseout", function() { alert( "Click! Or maybe mouse moved." ); } ); 

Метод .live более интересен. Рассмотрим следующий пример:

<a class="myLink">A link!</a>
<a id="another">Another link!</a>

<script>
    $("a.myLink").click( function() { alert( 'Click!' ); } );

    $("a#another").addClass( "myLink" );
</script>

После выполнения второй строки скрипта вторая ссылка также будет иметь класс CSS «myLink». Но у него не будет обработчика событий, потому что у него не было класса, когда событие было присоединено.

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

<a class="myLink">A link!</a>
<a id="another">Another link!</a>

<script>
    $("a.myLink").live( "click", function() { alert( 'Click!' ); } );

    $("a#another").addClass( "myLink" );
</script>

В этом примере вторая ссылка также получит обработчик события, как только получит класс «myLink». Магия! : -)

Конечно, это не так буквально. На самом деле .live прикрепляет обработчик не к самому указанному элементу, а к самому корню дерева HTML (элементу «body»). У событий в DHTML есть эта забавная особенность «всплывания». Учтите это:

<div> <a> <b>text</b> </a> </div>

Если вы нажмете «текст», то сначала элемент получит событие «щелчок». После этого элемент получит событие «click». И после этого элемент

И, наконец, метод .delegate. Он просто берет все дочерние элементы вашего элемента, которые соответствуют данному селектору, и прикрепляет к ним «живой» обработчик. Взгляните:

$("table").delegate( "td", "click", function() { alert( "Click!" ); } );

// Is equivalent to:
$("table").each( function() {
    $(this).find( "td" ).live( "click", function() { alert( "Click!" ); } );
} );

Вопросы

8 голосов
/ 18 марта 2012

Начиная с jQuery 1.7, метод .live () устарел. Если вы используете версию jQuery <1.7, то официально рекомендуется использовать .delegate () вместо .live (). </p>

.live () теперь заменен на .on ().

Лучше всего перейти непосредственно на сайт jQuery для получения дополнительной информации, но вот текущие версии метода .on ():

.on( events [, selector] [, data], handler(eventObject) )
.on( events-map [, selector] [, data] )

http://api.jquery.com/on/

2 голосов
/ 02 июня 2010

$().click(fn) и $().bind('click', fn) идентичны на первый взгляд, но версия $.bind является более мощной по двум причинам:

  1. $().bind() позволяет назначить один обработчик нескольким событиям, например, $().bind('click keyup', fn).
  2. $().bind() поддерживает события в пространстве имен - мощная функция, если вы хотите удалить (отменить привязку) только определенные обработчики событий, с которыми связан элемент - подробнее в События в пространстве имен .

Live против делегата: на это уже был дан ответ в других ответах.

1 голос
/ 02 июня 2010

Здесь может помочь чтение API. Тем не менее, я знаю по макушке, так что вы можете продолжать быть ленивым (ууу!).

$('#something').click(fn);
$('#something').bind('click',fn);

Здесь нет никакой разницы (что я знаю). .click - это просто удобный / вспомогательный метод для .bind('click'

* +1007 *

Это очень отличается, поскольку .live добавляет события в селектор, который вы передаете (которого у вас нет здесь), и продолжает смотреть на DOM, когда узлы вставляются / удаляются

$('#some_element').delegate('td','click',fn);

Это отличается только тем, как вы назначаете обработчики событий. .delegate сконцентрировано на барботировании событий DOM. Основной принцип заключается в том, что каждое событие всплывает вверх через дерево DOM, пока не достигнет корневого элемента (document или window или <html> или <body>, я точно не помню).

В любом случае, вы привязываете обработчик onclick ко всем <td> в $('#some_element') (вы должны указать селектор, хотя вы могли бы сказать $(document)). При щелчке по одному из его потомков событие всплывает до <td>. Затем вы можете извлечь исходный элемент события (что jQuery делает для вас автоматически).

Это полезно, когда есть тонны элементов, и у вас есть только несколько (или одна центральная) точка (и), через которые пройдут эти события. Это экономит усилия браузера и память для консолидации этих обработчиков событий в меньшем количестве объектов.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...