Как зарегистрировать обработчик событий javascript для элемента, который еще не был добавлен на страницу - PullRequest
3 голосов
/ 08 марта 2009

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

Если я попытаюсь, скажем, добавить событие onClick в таблицу td до того, как я создал таблицу и вставил ее в HTML, я получаю исключение «компонент недоступен».

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

Должен быть лучший способ сделать это. Я просто еще не понял это. У кого-нибудь есть идеи?

Ответы [ 4 ]

11 голосов
/ 08 марта 2009

Во-первых, я хотел бы знать, почему вам нужен другой идентификатор для каждого TD. Содержит ли идентификатор важную информацию, такую ​​как индекс? В этой ситуации может быть лучше создать каждый TD внутри цикла. Кроме того, очевидно, что вы не можете присоединить обработчик событий к элементу DOM, который не существует! Его не нужно вводить в DOM, но он ДОЛЖЕН существовать в каком-то качестве.

jQuery's live () не является волшебной загадкой, он просто использует делегирование событий, поэтому он присоединяет событие к родительскому элементу, например к таблице, и затем решает, что происходит в зависимости от цели нажатия. Вот простой пример. Я регистрирую обработчик для элемента 'body', а затем каждый раз проверяю, какова цель, если это TD-элемент, я делаюSomething () ->

document.body.onclick = function(e) {

    var realTarget = e ? e.target : window.event.srcElement;

    if ( realTarget.nodeName.toLowerCase() === 'td' ) {
        doSomething();
    }

};

Делегирование событий основывается на так называемом пузырении событий (или «распространении»), которое является способом, которым современные браузеры реализуют модель событий. Каждое событие при срабатывании будет проходить вверх через DOM до тех пор, пока оно не будет дальше. Таким образом, если вы щелкнете на ссылку в абзаце, сработает событие щелчка якоря, а затем сработает событие щелчка и т. Д. И т. Д.

5 голосов
/ 08 марта 2009

jQuery 1.3+ имеет новую функцию live (), которая может устанавливать обработчики событий для элементов, которые еще не существуют. проверить это

1 голос
/ 08 марта 2009

Как указал JimmyP, ваша проблема может быть легко решена с помощью всплывающего сообщения . Возможно, вы захотите написать функцию-обертку для обхода несоответствий браузера - моя собственная версия может быть найдена здесь и будет использоваться так:

capture('click', '#element-id', function(event) {
    // `this` will be the originating element
    // return `false` to prevent default action
});
1 голос
/ 08 марта 2009

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

Нет простого способа сказать «добавьте это ко всем элементам этого типа, сейчас и в будущем».

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

...