3

我正在尝试构建一个greasemonkey 脚本,该脚本将根据用户与...其他动态创建的数据表的交互动态创建数据表。我的问题是,每次创建表时我都必须进行两次传递:一次创建表,另一次获取表中我想要添加事件处理程序的所有对象(按 id)并添加他们的各种事件处理程序。

onClick例如,如果我在创建表并将其插入 HTML 之前尝试将事件添加到表 td,则会收到“组件不可用”异常。

这非常麻烦,因为我要么必须单独维护一个 id 列表以及在我第二次添加处理程序时应该对这些元素做什么,要么开发一个我知道的命名约定,基于id,我应该对元素做什么。

必须有更好的方法来做到这一点。我只是还没有弄清楚。有人有想法么?

4

4 回答 4

11

首先,我很想知道为什么每个 TD 都需要不同的 ID。ID 是否包含重要信息,例如索引?在这种情况下,最好在循环中创建每个 TD。此外,显然您不能将事件处理程序附加到不存在的 DOM 元素!它不必注入到 DOM 中,但它必须以某种容量存在。

jQuery 的 live() 并不是一个神奇的谜团,它只是使用事件委托,因此它将事件附加到父元素,例如表格,然后根据点击的目标决定发生什么。这是一个基本的例子。我向“body”元素注册了一个处理程序,然后我每次都测试一下目标是什么,如果它是一个 TD 元素我 doSomething() ->

document.body.onclick = function(e) {

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

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

};

事件委托依赖于称为事件冒泡(或“传播”)的东西,这是现代浏览器实现事件模型的方式。每个事件在被触发时将通过 DOM 向上传播,直到无法继续。因此,如果您单击段落中的锚点,则锚点的“单击”事件将触发,然后该段落的“单击”事件将触发等等。

于 2009-03-08T09:15:32.943 回答
5

jQuery 1.3+ 有一个新的 live() 函数,可以为尚不存在的元素设置事件处理程序..看看

于 2009-03-08T07:14:28.380 回答
1

正如 JimmyP 所指出的,使用事件冒泡可以轻松解决您的问题。您可能会考虑编写一个包装函数来解决浏览器的不一致问题 - 我自己的版本可以在这里找到,并且可以像这样使用:

capture('click', '#element-id', function(event) {
    // `this` will be the originating element
    // return `false` to prevent default action
});
于 2009-03-08T14:37:00.313 回答
1

您必须等待元素添加到页面,然后添加事件处理程序。

没有简单的方法可以说“在现在和将来将它添加到这种类型的所有元素中”。

可以让计时器定期检查页面中的新元素,在它们出现时将事件队列(或其他属性)应用于它们,所有这些都在幕后进行。这可以被抽象出来并重新使用,例如Jquery可以做那种事情。

于 2009-03-08T07:15:15.213 回答