1. Главная страница » Компьютеры

Jquery document on click

Автор: | 16.12.2019

Primary tabs

Forums:

Проблема

Пусть у нас есть код для двух блоков (родитель необязательно непосредственный):

  1. для родителя:
  2. для потомка (используем именно такую форму, так как подразумевается, что этот элемент добавляется динамически):

— тут используется "живая" привязка и вот этот то обрабочик хоть и привязывается но не вызывается.

Причина

Фишка в том, что в данном случае для того, чтобы произошла обработка события клика по элементу, необходимо, чтобы это событие "всплыло вврех" по иерархии вложенных DOM блоков аж до уровня document, но во время всплытия оно перехватывается обработчиком родителя (который тоже обработывает клик и возвращает false)

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

Решение

Есть два подхода:

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

Для "потомка", о котором говорилось выше, это будет выглядеть так как-то:

  • Или переписать все "перехватчики" событий (т.е. обработчики, которые заканчиваются как-то так) тоже с использованием document (тогда обработчик потомка можно оставить как выше), т.е. для обработчика родитля выше это будет выглядеть как:
  • — второй вариант на мой взгляд удобнее для не слишком сложных интерфейсов.

    Определение и применение

    jQuery метод .on() приcоединяет для выбранных элементов функцию обработчика события для одного, или нескольких событий.

    jQuery синтаксис:

    Добавлен в версии jQuery

    Значения параметров

    Параметр Описание
    events Один, или несколько разделенных пробелами типов событий (опционально допускается указывать пространство имен).
    Например: " click " или " click dblclick.myNamespace "
    eventMap Объект, содержащий строковый ключ, или ключи, определяющие тип события, а в качестве значения этих ключей выступает функция, которая будет выполнена каждый раз, когда конкретное событие срабатывает.
    Например:
    selector Строка селектора для фильтрации потомков выбранных элементов, запускающих событие. Обратите внимание, что если параметр отсутствует, или имеет значение null , то обработчик всегда вызывается при достижении выбранного элемента (не зависимо событие вызвано на элементе, или вложенном элементе).
    data Какие-либо данные, или объект, содержащий данные, которые будут переданы в обработчик событий при его срабатывании (свойство объекта Event event.data ).
    handler Функция, которая будет выполнена каждый раз, когда событие срабатывает. Функция в качестве параметра может принимать объект Event и при необходимости дополнительные параметры для решения конкретной задачи. Значение false также может использоваться в качестве сокращенной записи функции, которая имеет тело return false (при вызове возвращает значение false ).

    Пример использования

    Имена событий и пространства имён

    Любые имена событий могут быть использованы в качестве аргумента события. jQuery будет проходить через стандартные типы событий JavaScript, вызывая функцию обработчик, в то время когда браузер их генерирует, откликаясь на те, или иные действия пользователя, например такое событие как нажатие левой кнопкой мыши на элемент.

    Обращаю Ваше внимание на то, что метод .trigger() может вызвать как стандартные имена событий браузера, так и пользовательские имена событий. Пользовательские имена событий должны содержать только алфавитно-цифровые символы, символ подчеркивания и двоеточие. Пространства имен, начинающиеся с подчеркивания, зарезервированы для использования библиотекой jQuery.

    Пространства имен событий, или пользовательские имена событий упрощают удаление, или запуск необходимых обработчиков событий, по этой причине они зачастую используются при написании различных плагинов. Давайте рассмотрим использование пространств имен и пользовательских имен событий в jQuery на следующем примере:

    В этом примере с использованием jQuery метода .on() мы приcоединяем для элемента (кнопка) функцию обработчика события myEvent (пользовательское событие) и назначаем два пространства имен.

    Кроме того, с помощью обработчика событий " click " (клик левой кнопкой мыши) задаем функцию при нажатии на элемент , которая с помощью метода .trigger() вызывает два события " myEvent.myNamespace " и " myEvent.myAnotherNamespace " в результате чего в консоль будут выведены значения пространств имен объекта Event (свойство event.namespace).

    Следующая часть примера демонстрирует работу с пространствами имен. С помощью метода .on() мы приcоединяем для элемента обработчики событий " click " и " click " пространства имен myNamespace2.

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

    , которая вызывает событие " click " пространства имен myNamespace2, и затем с помощью метода .off() удаляет этот обработчик событий (при нажатии на будет выводиться только одно сообщение).

    Результат нашего примера:

    Пример использования jQuery метода .on() (пространства имен)

    Прямые и делегированные события

    Метод .on() позволяет задать как прямые, так и делегированные события. За это отвечает параметр selector метода, в том случае, если он опущен, или равен null устанавливается прямой обработчик события, он вызывается каждый раз, когда событие происходит на выбранных элементах, независимо от того, происходит ли это непосредственно на элементе, или всплывает от дочернего (вложенного) элемента.

    В том случае, если параметр selector указан, то в этом случае будет установлен делегированный обработчик события,он вызывается в том случае, когда событие происходит непосредственно на привязанном элементе (указанном в параметре метода), а не на самом элементе. В этом случае jQuery контролирует всплытие события и запускает обработчик события для любых элементов по этому пути в дереве DOM, соответствующих значению указанному в параметре метода.

    Давайте с Вами разберем когда использовать прямые, а когда делегированные события, в чем заключаются их преимущества и недостатки. Прямые обработчики событий привязываются только к выбранным в данный момент элементам, они должны существовать во время вызова метода .on(). Необходимо осуществлять привязку после того как документ будет готов, или необходимые элементы будут существовать в разметке HTML (дереве DOM).

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

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

    Обращаю Ваше внимание, что при работе с делегированными событиями для экономии ресурсов рекомендуется размещать элемент, которому делегирована обработка события ближе по дереву DOM к отслеживаемым элементам. Кроме того, делегированные события не работают для SVG (масштабируемая векторная графика).

    Перейдем к рассмотрению примера:

    В этом примере с использованием jQuery метода .on() мы приcоединяем для элемента (кнопка) функцию обработчика события " click ", которая с помощью метода .append() вставляет содержимое (элемент списка ) в конец элемента .

    С использованием jQuery метода .on() мы создали прямое событие, которое при клике левой кнопкой мыши на элементе , вложенном в элемент вызывает функцию, которая методом .text() изменяем текст элемента и методом .css() изменяет цвет текста.

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

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

    Результат нашего примера:

    Обработчик события для динамически добавленных элементов

    Обработчик событий и его среда

    Обязательный параметр handler является функцией, или значением false в том случае, если в качестве первого параметра передается объект eventMap, содержащий ключ, или ключи, а в качестве значения этих ключей выступает функция. Допускается передавать анонимную функцию, или передавать имя, объявленной именованной функции:

    Когда браузер запускает событие, или когда jQuery метод .trigger() был вызван, jQuery передает обработчику объект события ( Event ), он может использоваться для анализа и изменения состояния события, например чтобы обеспечить кроссбраузерность. Этот объект представляет из себя нормализованный набор данных, предоставленных браузером пользователя. Оригинальный объект по прежнему будет доступен в свойстве event.originalEvent .

    По умолчанию большинство событий переходят от исходной цели события к объекту document . На каждом элементе по пути следования jQuery вызывает все соответствующие обработчики событий, которые были присоединены.

    Функция обработчик может предотвратить дальнейший подъем события по дереву DOM, предотвращаю запуск обработчиков этих элементов путем вызова метода event.stopPropagation(). Однако все остальные обработчики, прикрепленные к текущему элементу, будут запущены, чтобы предотвратить это поведение, вы можете вызвать метод объекта event.stopImmediatePropagation().

    Обработчик может вызывать метод event.preventDefault(), который позволяет отменить любое действие, установленное по умолчанию, например, это полезно, чтобы предотвратить переход на другую страницу при нажатии на ссылку. Учтите, что не все события имеют действия по умолчанию, и не все действия по умолчанию могут быть отменены.

    Если функция обработчик возвращает false , то в этом случае автоматически будут вызваны методы event.stopPropagation() и event.preventDefault(). Значение параметра false в качестве обработчика события равнозначно следующему коду:

    Например, чтобы предотвратить переход на другую страницу при нажатии на элемент , достаточно приcоединить для них следующее событие:

    Когда jQuery вызывает обработчик, ключевое слово this ссылается на элемент, который доставил это событие, для прямых событий это элемент, к которому событие было присоединено, а для делегированных событий это один из элементов, который был указан в параметре selector.

    Обратите внимание, что this может быть не равен свойству event.target в том случае, если событие всплыло от потомков элемента. Для того, чтобы конкретный элемент можно было использовать с методами jQuery необходимо создать объект jQuery из одного элемента следуюшим образом:

    Передача данных в обработчик события

    Если вместе с методом .on() используется аргумент data и его значение не равно null , или undefined , то оно передается в обработчик события и доступно в свойстве event.data каждый раз, когда событие срабатывает. Аргумент data может быть любого типа, но если используется строковое значение, то селектор должен быть указан, или передан как null , чтобы данные не были приняты за селектор. Рекомендуется использовать простой объект для передачи нескольких значений в качестве свойств. Начиная с версии jQuery 1.4, один и тот же обработчик событий может быть связан с элементом несколько раз:

    В качестве альтернативы вы можете передавать необходимые данные обработчику событий с помощью второго аргумента метода .trigger(), или метода .triggerHandler().

    Давайте рассмотрим следующий пример, который демонстрирует как с помощью метода .trigger() передать произвольные данные через объект события:

    В этом примере мы инициализировали переменную, которая содержит функцию, которая при вызове возвращает случайное число от 0 до 1. С помощью метода .on() для элемента установили обработчики пользовательских событий " login " и " logoff ". В качестве второго параметра метода передали объект, содержащий данные, которые будут переданы в обработчик событий при его срабатывании (свойство объекта Event — event.data). Обратите внимание, что в качестве значения свойства нашего объекта будет использован результат вызова функции, содержащайся в созданной нами переменной.

    Для события " login " мы передаем функции, которая будет выполнена каждый раз, когда событие срабатывает в качестве параметров, объект Event и два дополнительных параметра, значения которых она получит при вызове метода .trigger() для данного типа событий. Функция выводит в консоль значения дополнительных параметров и значение свойства secretkey, переданное в объект данных (свойство объекта Event — event.data).

    Для события " logoff " мы передаем функции, которая будет выполнена каждый раз, когда событие срабатывает в качестве параметра объект Event . Функция выводит в консоль значения свойств объекта Event , включая пользовательские свойства, которые мы передаем в объект при вызове метода .trigger() для данного типа событий и значение свойства secretkey, переданное в объект данных (свойство объекта Event — event.data).

    Для того, чтобы выполнить все функции обработчики событий, присоединенные у выбранного элемента для типа событий " login " и " logoff " мы используем jQuery метод.trigger(). В первом случае мы указываем в качестве первого параметра метода .trigger() строковое значение, которое соответствует типу событий " login " и передаем массив данных. Обратите внимание, что данные содержащиеся под нулевым индексом в массиве будут соответствовать первому дополнительному параметру в обработчике этого события.

    Во втором случае мы указываем в качестве параметра метода .trigger() объект данных, содержащий пары ключ-значение, который мы передадим в объект события jQuery ( Event ). Обратите внимание, что свойство type этого объекта должно соответствовать событию, которое мы хотим инициировать, иначе обработчик события вызван не будет.

    Результат нашего примера:

    Пример использования jQuery метода .trigger() (передача дополнительных данных)

    Дополнительная информация

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

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

    Такие события как " focus " и " blur " по спецификации W3C не всплывают, но в jQuery определены кроссбраузерные события " focusin " и " focusout ", которые подлежат всплытию. Когда события " focus ", или " blur " используются для присоединения делегированных обработчиков событий, jQuery отображает имена и передает их как " focusin " и " focusout " соответственно. Для обеспечения согласованности и ясности используйте имена типов событий " focusin " и " focusout ".

    Во всех браузерах события " load ", " scroll " и " error " (например, в элементе ) не всплывают. В Internet Explorer 8 и ниже события " paste " и " reset " не всплывают. Такие события не поддерживаются для использования с делегированием, но их можно использовать, когда обработчик событий непосредственно присоединен к элементу, генерирующему это событие.

    Is there a well-known mistake I could be making here?

    I’ve got a script that’s using .on() because an element is dynamically generated, and it isn’t working. Just to test it out, I replaced the selector with the dynamic element’s wrap, which is static, and it still didn’t work! When I switched to plain old .click for the wrap it worked, though.
    (This just won’t work for the dynamic element obviously, the one that matters.)

    This works:

    This doesn’t:

    UPDATE:

    I right-clicked and did "Inspect Element" in Chrome to just double-check something, and then after that the click event worked. I refreshed and it didn’t work, inspected element, and then it worked. What does this mean?

    5 Answers 5

    You are using the correct syntax for binding to the document to listen for a click event for an element with .

    It’s probably not working due to one of:

    • Not using recent version of jQuery
    • Not wrapping your code inside of DOM ready
    • or you are doing something which causes the event not to bubble up to the listener on the document.

    To capture events on elements which are created AFTER declaring your event listeners — you should bind to a parent element, or element higher in the hierarchy.

    In this example, only the "bound to document" alert will fire.

    Your code should work, but I’m aware that answer doesn’t help you. You can see a working example here (jsfiddle).

    As someone already pointed out, you are using an ID instead of a class. If you have more that one element on the page with an ID, then jquery will return only the first element with that ID. There won’t be any errors because that’s how it works. If this is the problem, then you’ll notice that the click event works for the first test-element but not for any that follow.

    If this does not accurately describe the symptoms of the problem, then perhaps your selector is wrong. Your update leads me to believe this is the case because of inspecting an element then clicking the page again and triggering the click. What could be causing this is if you put the event listener on the actual document instead of test-element . If so, when you click off the document and back on (like from the developer window back to the document) the event will trigger. If this is the case, you’ll also notice the click event is triggered if you click between two different tabs (because they are two different document s and therefore you are clicking the document.

    If neither of these are the answer, posting HTML will go a long way toward figuring it out.

    Читайте также:  Gtx 960 2gb тест

    Добавить комментарий

    Ваш адрес email не будет опубликован. Обязательные поля помечены *