[tr][td] js的事件监听跟css不一样,css只要设定好了样式,不论是原来就有的还是新添加的,都有一样的表现。而事件监听不是,你必须给每一个元素单独绑定事件。
常见的例子是处理表格的时候。每行行末有个删除按钮,点了这个能够删除这一行。 [*]
复制代码 通常,我会这么绑定 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]删除[/td] [*] [*]1.jQuery(function($){ [*]2. //添加行 [*]3. $("#add2").click(function(){ [*]4. $("#table2>tbody").append('[tr][td]新增行[/td][td]删除[/td][/tr]') [*]5. }); [*]6.}); [*]7.//删除行的函数,必须要放domready函数外面 [*]8.function deltr(delbtn){ [*]9. $(delbtn).parents("tr").remove(); [*]10.}; 复制代码 1号解决方案——重复绑定法 即,在domready的时候就给已有的元素绑定事件处理函数, 而后当新增加的元素的时候再次绑定。 [*]1.[td]删除[/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]删除[/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]删除[/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]删除[/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. [*]2. [td]这里是模板[/td] [*]3. [td]删除[/td] [*]4. [/tr] [*]5. [tr] [*]6. [td]这行原来就有[/td] [*]7. [td]删除[/td] [*]8. [/tr] [*]9. [tr] [*]10. [td]这行原来就有[/td] [*]11. [td]删除[/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还有结构与行为分离的思想的掌握程度。最适合的才是最好的。 [/td][/tr] |
|||