События jQuery: добавьте обработчик обратного вызова к уже существующим

На веб-странице есть элементы с обработчиками кликов и/или нажатий клавиш. Если я добавлю новый, он будет выполнен после них. Мне нужен способ добавить новый обратный вызов, который добавляется в список обработчиков событий, чтобы он выполнялся заранее. Как это возможно с jQuery?

Обновить

Почему я не могу просто использовать метод развязки jQuery? Я вставляю свой код jQuery на любую веб-страницу, поэтому я не знаю, используется ли он и какая структура JavaScript. Мне нужен универсальный способ обнаружения обработчиков событий и добавления своих. (Прежде чем вы спросите, я создаю приложение «записывающее устройство», которое отслеживает действия пользователей, чтобы сохранить их и выполнить позже.)

Обновление 2

Я использую только Firefox, совместимость с IE не требуется. Мне нужно дождаться полной загрузки страницы, после чего будет вызван мой скрипт jQuery.


person Alp    schedule 29.01.2012    source источник
comment
это сценарий, который вы контролируете? Другими словами, вы можете развязать, а затем снова связать все?   -  person kinakuta    schedule 29.01.2012
comment
обратный вызов всегда выполняется после того, как произошло событие. если вы хотите, чтобы ваш старый обработчик делал что-то еще, почему бы просто не изменить код в существующем обработчике?   -  person Benny Tjia    schedule 29.01.2012
comment
Насколько я понимаю, нет способа гарантировать, в каком порядке будут вызываться несколько обработчиков, связанных с .addEventListener(), и нет возможности перечислить, какие обработчики были связаны. Одна библиотека (например, jQuery) может обойти это, если вы связываете события только через библиотеку, но я не уверен, как вы могли бы обрабатывать события, связанные с несколькими библиотеками и/или простым JS. Если вы не можете переопределить .addEventListener() до запуска любого другого кода на странице, чтобы другие события привязки кода проходили через ваш прокси-сервер? (Что все равно не поможет вам для более старого IE...)   -  person nnnnnn    schedule 29.01.2012
comment
Нет необходимости в совместимости с IE, он работает только в FF. Я не могу запустить какой-либо код в начале, мне нужно дождаться завершения загрузки страницы, и после этого будет загружен мой скрипт jQuery.   -  person Alp    schedule 29.01.2012


Ответы (2)


Я также остановился на этой потребности и придумал обходной путь, основанный на том, как события всплывают в DOM. Итак, основная идея состоит в том, чтобы сделать следующее:

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

  2. В случае события click убедитесь, что оно занимает полную ширину и высоту своего родителя:

    • If the parent has padding/border add negative margin to the child so that it takes the full area of the parent
  3. Добавьте предварительное событие клика к созданному дочернему элементу

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

Пример:

      
      const $someButton=$('.btn')
      $someButton.click(()=> alert('default event'))
      /**
      * 1. Insert an extra element 
      * as direct child of the element 
      * you want to append the event to
      **/
      $someButton.wrapInner(
        '<div class="btn__first_event"></div>'
      )
      /**
      * 3. Add the prepended click event to 
      * the created child
      **/
      $someButton.find('.btn__first_event').click(()=>alert('Prepended Event'))
.btn{
   cursor:pointer;
   background-color: yellow;
   padding:10px;
   border-radius:3px;
   border: 1px solid;
   display: inline-block;
}
/*
 2. In the case of click event 
make sure it takes 
the full width and 
height of its parent
-------------------- 
note: some css is needed for 
offsetting padding / border
*/
.btn__first_event{
   margin: -10px;
   padding: 1px;
   border-radius:3px;
   background-color: rgba(0, 0, 255, 0.4)
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div class="btn">Click me<div>

person Andreas    schedule 15.02.2021

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

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

http://www.w3.org/TR/2000/REC-DOM-Level-2-Events-20001113/events.html#Events-flow-capture

Вы должны связать обработчик с помощью: (третий аргумент — хотите ли вы использовать захват событий)

document.body.addEventListener('click',handler,true)

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

person Roel    schedule 29.01.2012
comment
Кажется, это работает, спасибо. Хотя я считаю, что это не охватит все возможные случаи. - person Alp; 29.01.2012