如何使用 jQuery 将事件附加到动态 HTML 元素?

发布于 2024-08-03 21:59:32 字数 1082 浏览 6 评论 0原文

假设我有一些 jQuery 代码,将事件处理程序附加到类 .myclass 的所有元素。

例如:

$(function(){
    $(".myclass").click( function() {
        // do something
    });
});

我的 HTML 可能如下所示:

<a class="myclass" href="#">test1</a>
<a class="myclass" href="#">test2</a>
<a class="myclass" href="#">test3</a>

可以正常工作。 但是,请考虑 .myclass 元素是否在将来某个时间写入页面。

例如:

<a id="anchor1" href="#">create link dynamically</a>
<script type="text/javascript">
$(function(){
    $("#anchor1").click( function() {
        $("#anchor1").append('<a class="myclass" href="#">test4</a>');
    });
});
</script>

在本例中,当用户单击 a#anchor1 时,将创建 test4 链接。

test4 链接没有与其关联的 click() 处理程序,尽管它具有 class="myclass"

基本上,我想编写一次 click() 处理程序,并将其应用于页面加载时出现的内容以及稍后通过 AJAX / DHTML 引入的内容。知道我该如何解决这个问题吗?

Suppose I have some jQuery code that attaches an event handler to all elements with class .myclass.

For example:

$(function(){
    $(".myclass").click( function() {
        // do something
    });
});

And my HTML might be as follows:

<a class="myclass" href="#">test1</a>
<a class="myclass" href="#">test2</a>
<a class="myclass" href="#">test3</a>

That works with no problem.
However, consider if the .myclass elements were written to the page at some future time.

For example:

<a id="anchor1" href="#">create link dynamically</a>
<script type="text/javascript">
$(function(){
    $("#anchor1").click( function() {
        $("#anchor1").append('<a class="myclass" href="#">test4</a>');
    });
});
</script>

In this case, the test4 link is created when a user clicks on a#anchor1.

The test4 link does not have the click() handler associated with it, even though it has class="myclass".

Basically, I would like to write the click() handler once and have it apply to both content present at page load, and content brought in later via AJAX / DHTML. Any idea how I can fix this?

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

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

发布评论

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

评论(8

半边脸i 2024-08-10 21:59:32

我添加了一个新答案以反映 jQuery 后续版本中的更改。从 jQuery 1.7 开始,.live() 方法已被弃用。

来自 http://api.jquery.com/live/

从 jQuery 1.7 开始,.live() 方法已被弃用。使用 .on() 附加事件处理程序。旧版本 jQuery 的用户应优先使用 .delegate() 而不是 .live()。

对于 jQuery 1.7+,您可以使用 .on() 将事件处理程序附加到父元素,并传递与“myclass”组合的选择器作为参数。

请参阅 http://api.jquery.com/on/

因此,

$(".myclass").click( function() {
    // do something
});

您可以写...

$('body').on('click', 'a.myclass', function() {
    // do something
});

而不是 ...适用于主体中带有“myclass”的所有标签,无论是已经存在还是稍后动态添加。

此处使用 body 标记是因为该示例没有更接近的静态周围标记,但 .on 方法调用发生时存在的任何父标记都将起作用。例如,将添加动态元素的列表的 ul 标记将如下所示:

$('ul').on('click', 'li', function() {
    alert( $(this).text() );
});

只要 ul 标记存在,就可以工作(还不需要存在 li 元素)。

I am adding a new answer to reflect changes in later jQuery releases. The .live() method is deprecated as of jQuery 1.7.

From http://api.jquery.com/live/

As of jQuery 1.7, the .live() method is deprecated. Use .on() to attach event handlers. Users of older versions of jQuery should use .delegate() in preference to .live().

For jQuery 1.7+ you can attach an event handler to a parent element using .on(), and pass the a selector combined with 'myclass' as an argument.

See http://api.jquery.com/on/

So instead of...

$(".myclass").click( function() {
    // do something
});

You can write...

$('body').on('click', 'a.myclass', function() {
    // do something
});

This will work for all a tags with 'myclass' in the body, whether already present or dynamically added later.

The body tag is used here as the example had no closer static surrounding tag, but any parent tag that exists when the .on method call occurs will work. For instance a ul tag for a list which will have dynamic elements added would look like this:

$('ul').on('click', 'li', function() {
    alert( $(this).text() );
});

As long as the ul tag exists this will work (no li elements need exist yet).

Bonjour°[大白 2024-08-10 21:59:32

有时,这样做(得票最高的答案)并不总是足够:

$('body').on('click', 'a.myclass', function() {
    // do something
});

这可能是一个问题,因为事件处理程序的触发顺序。如果您发现自己这样做,但由于处理顺序而导致问题。您始终可以将其包装到一个函数中,该函数在调用时“刷新”侦听器。

例如:

function RefreshSomeEventListener() {
    // Remove handler from existing elements
    $("#wrapper .specific-selector").off(); 

    // Re-add event handler for all matching elements
    $("#wrapper .specific-selector").on("click", function() {
        // Handle event.
    }
}

因为它是一个函数,所以每当我以这种方式设置侦听器时,我通常会在文档准备好时调用它:

$(document).ready(function() {
    // Other ready commands / code

    // Call our function to setup initial listening
    RefreshSomeEventListener();
});

然后,每当您添加一些动态添加的元素时,再次调用该方法:

function SomeMethodThatAddsElement() {
    // Some code / AJAX / whatever.. Adding element dynamically

    // Refresh our listener, so the new element is taken into account
    RefreshSomeEventListener();
}

希望这会有所帮助!

问候,

Sometimes doing this (the top-voted answer) is not always enough:

$('body').on('click', 'a.myclass', function() {
    // do something
});

This can be an issue because of the order event handlers are fired. If you find yourself doing this, but it is causing issues because of the order in which it is handled.. You can always wrap that into a function, that when called "refreshes" the listener.

For example:

function RefreshSomeEventListener() {
    // Remove handler from existing elements
    $("#wrapper .specific-selector").off(); 

    // Re-add event handler for all matching elements
    $("#wrapper .specific-selector").on("click", function() {
        // Handle event.
    }
}

Because it is a function, whenever I set up my listener this way, I typically call it on document ready:

$(document).ready(function() {
    // Other ready commands / code

    // Call our function to setup initial listening
    RefreshSomeEventListener();
});

Then, whenever you add some dynamically added element, call that method again:

function SomeMethodThatAddsElement() {
    // Some code / AJAX / whatever.. Adding element dynamically

    // Refresh our listener, so the new element is taken into account
    RefreshSomeEventListener();
}

Hopefully this helps!

Regards,

输什么也不输骨气 2024-08-10 21:59:32

在 jQuery 1.7 之后,首选方法是 .on().off()

肖恩的回答展示了一个例子。

现已弃用:

使用 jQuery 函数 .live() 和 < a href="http://docs.jquery.com/Events/die" rel="nofollow noreferrer">.die()。可用于
jQuery 1.3.x

来自文档:

<块引用>

将每个段落的文本显示在
每当单击时都会出现警报框:

$("p").live("点击", function(){
  警报( $(this).text() );
});

此外,livequery 插件可以执行此操作并支持更多事件。< /p>

After jQuery 1.7 the preferred methods are .on() and .off()

Sean's answer shows an example.

Now Deprecated:

Use the jQuery functions .live() and .die(). Available in
jQuery 1.3.x

From the docs:

To display each paragraph's text in an
alert box whenever it is clicked:

$("p").live("click", function(){
  alert( $(this).text() );
});

Also, the livequery plugin does this and has support for more events.

[浮城] 2024-08-10 21:59:32

如果您要向 DOM 添加一堆锚点,请改为考虑事件委托。

这是一个简单的例子:

$('#somecontainer').click(function(e) {   
  var $target = $(e.target);   
  if ($target.hasClass("myclass")) {
    // do something
  }
});

If you're adding a pile of anchors to the DOM, look into event delegation instead.

Here's a simple example:

$('#somecontainer').click(function(e) {   
  var $target = $(e.target);   
  if ($target.hasClass("myclass")) {
    // do something
  }
});
甜味拾荒者 2024-08-10 21:59:32

您可以将单个单击事件绑定到所有元素的页面,无论它们是否已经在该页面上,或者它们是否会在将来的某个时间到达,就像这样:已经

$(document).bind('click', function (e) {
   var target = $(e.target);
   if (target.is('.myclass')) {
      e.preventDefault(); // if you want to cancel the event flow
      // do something
   } else if (target.is('.myotherclass')) {
      e.preventDefault();
      // do something else
   }
});

使用它有一段时间了。就像魅力一样。

在 jQuery 1.7 及更高版本中,建议使用 .on() 代替 bind 或任何其他事件委托方法,但 .bind() 仍然有效。

You can bind a single click event to a page for all elements, no matter if they are already on that page or if they will arrive at some future time, like that:

$(document).bind('click', function (e) {
   var target = $(e.target);
   if (target.is('.myclass')) {
      e.preventDefault(); // if you want to cancel the event flow
      // do something
   } else if (target.is('.myotherclass')) {
      e.preventDefault();
      // do something else
   }
});

Been using it for a while. Works like a charm.

In jQuery 1.7 and later, it is recommended to use .on() in place of bind or any other event delegation method, but .bind() still works.

独行侠 2024-08-10 21:59:32

将处理程序绑定到所有当前和未来匹配元素的事件(如单击)。还可以绑定自定义事件。

链接文本

$(function(){
    $(".myclass").live("click", function() {
        // do something
    });
});

Binds a handler to an event (like click) for all current - and future - matched element. Can also bind custom events.

link text

$(function(){
    $(".myclass").live("click", function() {
        // do something
    });
});
清欢 2024-08-10 21:59:32

如果您使用 jQuery 1.3+,则使用 .live()

将处理程序绑定到事件(例如
单击)查看所有当前和未来的信息
匹配的元素。还可以绑定自定义
事件。

If your on jQuery 1.3+ then use .live()

Binds a handler to an event (like
click) for all current - and future -
matched element. Can also bind custom
events.

无悔心 2024-08-10 21:59:32

您想要使用 live() 函数。请参阅文档

例如:

$("#anchor1").live("click", function() {
    $("#anchor1").append('<a class="myclass" href="#">test4</a>');
});

You want to use the live() function. See the docs.

For example:

$("#anchor1").live("click", function() {
    $("#anchor1").append('<a class="myclass" href="#">test4</a>');
});
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文