如何向尚未添加到页面的元素注册 Javascript 事件处理程序

发布于 2024-07-14 06:59:35 字数 365 浏览 7 评论 0 原文

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

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

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

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

I'm trying to build a greasemonkey script which will dynamically create tables of data based on user interaction with... other dynamically created tables of data. My problem is that I'm having to make two passes every time I create a table: one to create the table, and another to go grab all of the objects in the table I want to add event handlers to (by id) and add the various event handlers to them.

If I attempt to, say, add an onClick event to a table td before I've created the table and inserted it into the HTML, I get a "component is not available" exception.

This is incredibly cumbersome, because I either have to maintain, separately, a list of the ids and what I should do to those elements when I make my second pass to add the handlers, or develop a naming convention by which I know, based on the id, what I should do with the element.

There HAS to be a better way to do this. I just haven't figured it out yet. Anyone have any ideas?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(4

浅紫色的梦幻 2024-07-21 06:59:35

首先,我很想知道为什么每个 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 向上传播,直到无法再进一步传播为止。 因此,如果您单击段落中的锚点,则锚点的“单击”事件将触发,然后该段落的“单击”事件将触发等等。

Firstly, I'd love to know why you need a different ID for every single TD. Is the ID holding important information, such as an index? In this situation it might be better creating each TD within a loop. Also, obviously you can't attach an event handler to a DOM element which doesn't exist! It doesn't have to be injected into the DOM but it DOES have to exist in some capacity.

jQuery's live() isn't a magical mystery, it just uses event delegation, so it attaches the event to a parent element, such as the table and then decides what happens dependent on the target of the click. Here's a rudimentary example. I register a handler to the 'body' element, and then I test each time to see what the target is, if it's a TD element I doSomething() ->

document.body.onclick = function(e) {

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

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

};

Event delegation relies on something called event bubbling (or "propogation") which is the way in which modern browsers implement the event model. Each event, when triggered will travel upwards through the DOM until it can go no further. So if you click on an anchor within a paragraph the anchor's 'click' event will fire and THEN the paragraph's 'click' event will fire etc. etc.

兔小萌 2024-07-21 06:59:35

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

jQuery 1.3+ has a new live() function that can set up event handlers for elements that don't exist yet .. check it out

笔芯 2024-07-21 06:59:35

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

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

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

You have to wait for the element to be added to the page, then add the event handler then.

There is no easy way to say "add this to all elements of this type, now and in the future".

It is possible to have a timer periodically check the page for new elements, applying a queue of events (or other properties) to them as they appear, all behind the scenes. This can be abstracted out and re-used, for example Jquery can do that sort of thing.

雨巷深深 2024-07-21 06:59:35

正如 JimmyP 指出的那样,您的问题可以使用 可以在这里找到并且可以像这样使用:

capture('click', '#element-id', function(event) {
    // `this` will be the originating element
    // return `false` to prevent default action
});

As JimmyP pointed out, your problem can easily be solved using event bubbling. You might consider writing a wrapper function to work around browser inconsistencies - my own version can be found here and would be used like this:

capture('click', '#element-id', function(event) {
    // `this` will be the originating element
    // return `false` to prevent default action
});
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文