首页 文章

在jQuery中,如何将事件附加到动态html元素? [重复]

提问于
浏览
471

这个问题在这里已有答案:

假设我有一些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>

在这种情况下,当用户点击#anchor1时会创建“test4”链接 .

“test4”链接没有与之关联的click()处理程序,即使它具有class =“myclass” .

知道如何解决这个问题吗?

基本上,我想编写一次click()处理程序,并将其应用于页面加载时出现的内容和稍后通过Ajax / DHTML引入的内容 .

8 回答

  • 36

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

    Sean's answer显示了一个例子 .

    现已弃用:

    使用jQuery函数.live()和.die() . 在jQuery 1.3.x中可用文档:在单击时在警告框中显示每个段落的文本:$(“p”) . live(“click”,function(){
    alert($(this).text());
    });
    此外,livequery插件执行此操作并支持更多事件 .

  • 5

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

    link text

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

    如果你在jQuery 1.3上然后使用 . live()

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

  • 2

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

    $(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() 仍然有效 .

  • 794

    有时这样做 (the top-voted answer) 并不总是足够的:

    $('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();
    }
    

    希望这有帮助!

    问候,

  • 1

    您想使用 live() 功能 . 见the docs .

    例如:

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

    我正在添加一个新的答案来反映后来的jQuery版本中的更改 . 从jQuery 1.7开始,不推荐使用.live()方法 .

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

    从jQuery 1.7开始,不推荐使用.live()方法 . 使用.on()附加事件处理程序 . 旧版jQuery的用户应该使用.delegate()而不是.live() .

    对于jQuery 1.7,您可以使用.on()将事件处理程序附加到父元素,并将带有'myclass'的a选择器作为参数传递 .

    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元素) .

  • 1

    如果您要向DOM添加一堆锚点,请查看事件委派 .

    这是一个简单的例子:

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

相关问题