`

jquery 新建的元素事件绑定问题

 
阅读更多

http://www.cnblogs.com/linzheng/archive/2010/10/17/1853568.html

js的事件监听跟css不一样,css只要设定好了样式,不论是原来就有的还是新添加的,都有一样的表现。而事件监听不是,你必须给每一个元素单独绑定事件。

常见的例子是处理表格的时候。每行行末有个删除按钮,点了这个能够删除这一行。

<table>
    
<tbody>
        
<tr>
            
<td>这行原来就有</td>
            
<td><buttonclass="del">删除</button></td>
        
</tr>
        
<tr>
            
<td>这行原来就有</td>
            
<td><buttonclass="del">删除</button></td>
        
</tr>
    
</tbody>
</table>

通常,我会这么绑定

  1. jQuery(function($){
  2.    //已有删除按钮初始化绑定删除事件
  3.     $(".del").click(function() {
  4.         $(this).parents("tr").remove();
  5.    });
  6. });

对于在domready之前就存在的删除按钮,一切都很完美。但如果在domready之后用js动态添加几行,那新增的几行中的这些按钮都将失去任何作用。

如何解决这个问题?以下提供4种解决方案:
=============================
0号解决方案——onclick法
如果不顾结构与行为分离的准则的话,通常,我会这么做。
注意,此时的deltr这个function必须是全局函数,得放jQuery(function($) {})外面,放里边就成局部函数了,html里的onclick就调用不到了!

  1. <td><buttononclick="deltr(this)">删除</button></td>
  1. jQuery(function($){
  2.    //添加行
  3.     $("#add2").click(function(){
  4.         $("#table2>tbody").append('<tr><td>新增行</td><td><button nclick="deltr(this)">删除</button></td></tr>')
  5.    });
  6. });
  7. //删除行的函数,必须要放domready函数外面
  8. function deltr(delbtn){
  9.     $(delbtn).parents("tr").remove();
  10. };

=============================
1号解决方案——重复绑定法
即,在domready的时候就给已有的元素绑定事件处理函数,
而后当新增加的元素的时候再次绑定。

  1. <td><buttonclass="del">删除</button></td>
  1. jQuery(function($){
  2.    //定义删除按钮事件绑定
  3.    //写里边,防止污染全局命名空间
  4.    function deltr(){
  5.         $(this).parents("tr").remove();
  6.    };
  7.    //已有删除按钮初始化绑定删除事件
  8.     $("#table3 .del").click(deltr);
  9.    //添加行
  10.     $("#add3").click(function(){
  11.         $('<tr><td>新增行</td><td><button class="del">删除</button></td></tr>')
  12.            //在这里给删除按钮再次绑定事件。
  13.             .find(".del").click(deltr).end()
  14.             .appendTo($("#table3>tbody"));
  15.    });
  16. });

=============================
2号解决方案——事件冒泡法
利用事件冒泡的原理,我们给这个按钮的祖先元素绑定事件处理函数。
然后通过event.target这个对象来判断,这个事件是不是我们要找的对象触发的。
通常可以利用一些DOM属性,比如event.target.className、event.target.tagName等之类的来判断。

  1. <td><buttonclass="del">删除</button></td>
  1. jQuery(function($){
  2.    //第四个表格的删除按钮事件绑定
  3.     $("#table4").click(function(e) {
  4.        if (e.target.className=="del"){
  5.             $(e.target).parents("tr").remove();
  6.        };
  7.    });
  8.    //第四个表格的添加按钮事件绑定
  9.     $("#add4").click(function(){
  10.         $("#table4>tbody").append('<tr><td>新增行</td><td><button class="del">删除</button></td></tr>')
  11.    });
  12. });
3号解决方案——复制事件法
上面几种方案可以说即便你没有用到jQuery库,你也能相对比较容易的实现。但这种方案相对依赖jQuery的程度更高。而且必须要求jQuery 1.2版以上。低版本jQuery需要插件。
上面两个方案都是对删除函数动了很多脑筋,换了多种触发、绑定的方式。这个方案不同,可以与平时纯静态的元素一样在domready的时候绑定。但在我们添加新行的时候我们改动一下,不再想上面那样拼接字符串来添加新行了。这回我们尝试使用复制DOM元素的方式。并且复制的时候连同绑定的事件一起复制,复制完之后再用find之类的修改内部的元素。
同时,就像这个例子,如果你会把所有元素都删除光,那template这个模板是必须的,如果不会删光,那就未必需要用template了。为了防止被误删,此处我把template设了隐藏。
我使用了jQuery中特有的clone(true)
  1. .template{display:none;}
  1. <trclass="template">
  2.            <td>这里是模板</td>
  3.            <td><button class="del">删除</button></td>
  4.        </tr>
  5.        <tr>
  6.            <td>这行原来就有</td>
  7.            <td><button class="del">删除</button></td>
  8.        </tr>
  9.        <tr>
  10.            <td>这行原来就有</td>
  11.            <td><button class="del">删除</button></td>
  12.        </tr>
  1. jQuery(function($){
  2.    //第五个表格的删除按钮事件绑定
  3.     $("#table5 .del").click(function() {
  4.         $(this).parents("tr").remove();
  5.    });
  6.    //第五个表格的添加按钮事件绑定
  7.     $("#add5").click(function(){
  8.         $("#table5>tbody>tr:eq(0)")
  9.            //连同事件一起复制
  10.             .clone(true)
  11.            //去除模板标记
  12.             .removeClass("template")
  13.            //修改内部元素
  14.             .find("td:eq(0)")
  15.                 .text("新增行")
  16.                 .end()
  17.            //插入表格
  18.             .appendTo($("#table5>tbody"))
  19.    });
  20. });

=============================
总评:
上面4种方案,各有优劣。
0号方案,结构与行为完全没有分离,而且污染全局命名空间。最不推荐。所以我都不把它当作一个方案来看。但对于js初学者,可以用来项目救急。
1号方案,中规中矩,没啥好也没啥不好
2号方案,这种方法充分的发挥了js事件冒泡的优势。而且效率最高。但同时由于这种方案无视了jQuery强大的选择器,所以如果涉及的元素属性要求过多就会比较麻烦了。你会徘徊在众多if的条件的是非关系之中。后来我想起来,可以用jQuery中的$(event.target).is(selector)来作为条件。这样可以极大提升开发效率,但略微降低执行效率。
3号方案,这是我认为最能体现结构与行为分离的思想的一种方案。但缺点也很明显,对于jQuery依赖性过于高了,要不就自己写一个复制连同事件一起复制的函数,但这也显然对于初学者来说异常困难。但从未来的趋势的角度来看,还是很推荐使用这种方案的。

具体选用哪一个方案,没有定数。具体看你的项目以及你js还有结构与行为分离的思想的掌握程度。最适合的才是最好的。

=============================
附加:
把3号方案改造成完美的结构行为分离的样式。
首先,带有template的是模板元素。他是一切复制的源泉,为了防止被误删,所以设为不可见。如果不会删除光,那么这个模板元素也是可选的。因为你可以复制任何一个已经存在的用于循环元素。
其次,给每个重复的元素加上一个repeat,方便用于删除按钮找到这一级元素。这个是可选的,有时候并不需要。
最后是给每一个要修改的元素加上一个类,便于用find找到。比如我这里就家了content类,新增加的可以修改里边的值。
这样一个完美的结构与行为分离的案例就完成了。

  1. <tableid="table6">
  2.    <tbody id="tbody6">
  3.        <tr class="template repeat">
  4.            <td class="content">这里是模板</td>
  5.            <td><button class="del">删除</button></td>
  6.        </tr>
  7.        <tr class="repeat">
  8.            <td class="content">这行原来就有</td>
  9.            <td><button class="del">删除</button></td>
  10.        </tr>
  11.        <tr class="repeat">
  12.            <td class="content">这行原来就有</td>
  13.            <td><button class="del">删除</button></td>
  14.        </tr>
  15.    </tbody>
  16.    <tfoot>
  17.        <tr>
  18.            <td>&nbsp;</td>
  19.            <td><button id="add6">添加</button></td>
  20.        </tr>
  21.    </tfoot>
  22. </table>
  1. jQuery(function($){
  2.    //第六个表格的删除按钮事件绑定
  3.     $("#tbody6 .del").click(function() {
  4.         $(this).parents(".repeat").remove();
  5.    });
  6.    //第六个表格的添加按钮事件绑定
  7.     $("#add6").click(function(){
  8.         $("#tbody6>.template")
  9.            //连同事件一起复制
  10.             .clone(true)
  11.            //去除模板标记
  12.             .removeClass("template")
  13.            //修改内部元素
  14.             .find(".content")
  15.                 .text("新增行")
  16.                 .end()
  17.            //插入表格
  18.             .appendTo($("#tbody6"))
  19.    });
  20. });

同样,这段js也适用于如下的html结构

  1. <ulid="tbody6">
  2.    <li class="template repeat">
  3.        <span class="content">这里是模板</span>
  4.        <span><button class="del">删除</button></span>
  5.    </li>
  6.    <li class="repeat">
  7.        <span class="content">这行原来就有</span>
  8.        <span><button class="del">删除</button></span>
  9.    </li>
  10.    <li class="repeat">
  11.        <span class="content">这行原来就有</span>
  12.        <span><button class="del">删除</button></span>
  13.    </li>
  14. </ul>

<script type="text/javascript"></script>

分享到:
评论

相关推荐

    jquery 新建的元素事件绑定问题解决方案

    在DOM加载完成后先给现有的元素绑定事件处理函数,然后在添加新元素时再次为新元素绑定相同事件。这种方法虽然有效,但可能会导致多个事件监听器附加到同一元素上,可能影响性能。例如: ```javascript function...

    jQuery新建文件夹展开缩收代码.zip

    【jQuery新建文件夹展开缩收代码.zip】是一个包含JavaScript特效的资源包,主要利用了jQuery库和Bootstrap.js框架来实现一种模拟文件夹结构的效果。在实际的网页设计和开发中,这种功能常用于构建文件管理系统或者...

    jquery高仿浏览器新建标签页网址缩略图导航特效代码

    jQuery的`$.ajax`或`$.get`方法可以异步获取远程资源,然后将获取到的图标数据绑定到对应的标签页元素上。 5. **收藏功能**:为了实现收藏功能,我们需要存储用户的收藏记录,这可能涉及到本地存储(如localStorage...

    JQUERY demo+api

    3. **事件处理**:jQuery提供了绑定事件的方法,如`$(selector).click(function(){...})`,可以为元素添加点击事件监听器。同时,`$(document).ready()`确保DOM加载完成后再执行函数,避免了页面闪烁问题。 4. **...

    AJAX与jquery试题

    【知识点详解】 1. **jQuery的基本使用*...总结,这个AJAX与jQuery试题主要测试了对jQuery的选择器、DOM操作、事件处理、链式操作以及动态创建元素等基础知识的掌握。解答这些题目需要熟悉jQuery的基本语法和常见API。

    jQuery实战中文版.pdf

    - **事件处理**:利用jQuery可以轻松绑定各种事件处理器。 - **插件扩展**:jQuery提供了丰富的插件机制,可以方便地扩展其功能。 #### 三、jQuery实战应用 - **基础用法**: - 加载jQuery库; - 使用`$(document...

    jquery 教程

    - **新建DOM对象**: 可以使用jQuery动态创建新的DOM元素,并将其插入到页面中。 - **事件处理**: 支持多种事件绑定方式,如`.click()`、`.hover()`等,方便处理用户的交互行为。 - **动画效果**: 提供简单易用的动画...

    JQuery事件委托原理与用法实例分析

    在传统的事件绑定方式中,如果一个页面中有多个同类型的可交互元素(如列表项`&lt;li&gt;`),我们通常需要为每一个元素分别绑定事件监听器。但这样会增加内存消耗和处理时间,尤其是当动态添加新的元素时,需要额外绑定...

    jQuery.rar

    1. **jqueryDemo.html**:这可能是一个包含jQuery应用的HTML页面,展示了如何引入jQuery库,并可能包含使用jQuery进行DOM操作、事件绑定和动画效果的实例。 2. **jquery-3.4.1.js**:这是未压缩的jQuery库文件,...

    jquery-1.1.3.1.js,jquery.linscroll.js

    - **事件处理**:通过`.on()`, `.click()`, `.mouseover()`等方法绑定和触发事件。 - **动画效果**:jQuery的`.animate()`方法可以创建自定义动画,`.fadeIn()`, `.slideUp()`等预定义动画则提供常见效果。 2. **...

    jQuery应用技巧大全

    jQuery的事件绑定函数如$.on()、$.off()简化了事件处理。$.on()不仅可以绑定单个事件,还可以一次性绑定多个事件。此外,使用.delegate()或.live()(已被弃用,但理解其原理有益)可以实现事件冒泡和委托,提高性能...

    jQuery新建文件夹展开缩收代码

    // 触发展开/缩收事件绑定 applyFolderBehaviors(); } }); }); }); ``` 在这个例子中,当用户提交表单时,一个新的文件夹名被发送到服务器(这里的URL应替换为实际的API地址),然后在服务器返回成功响应后,...

    jquery实例

    事件委托是jQuery中的一个高级技巧,通过在父元素上绑定事件,可以处理子元素的动态添加和删除,提高代码的灵活性。 动画效果是jQuery的一大亮点。`.fadeIn()`, `.slideUp()`, `.animate()`等方法可以创建出流畅的...

    jQuery新建文件夹展开缩收特效代码

    本文将深入探讨“jQuery新建文件夹展开缩收特效代码”这一主题,这是利用jQuery和Bootstrap.js实现的一个功能,允许用户模拟文件夹的展开与收缩,支持多重嵌套,并提供新建文件夹的功能。 首先,jQuery的核心在于它...

    jQuery的实现原理的模拟代码 -3 事件处理

    在JavaScript中,事件处理通常通过为DOM元素绑定事件监听器来实现,当相应的事件发生时,监听器会触发一个回调函数。 jQuery作为JavaScript的一个库,提供了一套简化事件处理的API。它封装了底层的事件处理细节,并...

    jQuery实现表格行的动态增加与删除(改进版)

    首先,jQuery的选择器和事件绑定是实现这一功能的关键。通过`$(document).ready()`函数确保在DOM加载完成后执行相关代码。`$("#tab tr")`选择表格的所有行,并设置它们的对齐方式为居中。`$("#but")`则选择了带有...

    基于jQuery的学校网站设计与实现

    3. **事件处理**:jQuery简化了事件绑定,如`click()`,`mouseover()`等,还可以使用`.on()`方法处理动态添加的元素的事件。 4. **动画效果**:`.fadeIn()`,`slideUp()`,`animate()`等方法可以创建各种平滑的过渡...

    JS实现为动态创建的元素添加事件操作示例

    `live` 方法允许为尚未存在的元素绑定事件,它会监听到这些元素的祖先元素的事件冒泡,从而触发绑定的事件处理函数。 ```javascript $("#nep").live("click", function() { var that = $(this); console.log...

    jquery教程

    - **绑定事件**:如 `.click()`, `.hover()`, `.change()` 等方法可以为元素绑定事件。 - **解绑事件**:如 `.off()` 方法可以移除绑定的事件处理函数。 - **动画效果**: - **基本动画**:如 `.fadeIn()`, `....

Global site tag (gtag.js) - Google Analytics