外部HTML脚本重复触发:jQuery.load多次调用后事件重复执行
解决jQuery.load多次加载外部HTML后事件重复触发的问题
你碰到的这个问题其实很典型——每次点击加载按钮调用load()时,external.html里的脚本都会重新执行一遍。而你用的$(document).on('click','#btn_clickme',...)是把事件委托绑定在document节点上的,每加载一次就会多添加一个相同的委托,所以最后点击#btn_clickme时,这些委托会挨个触发,就出现了多次alert的情况。
下面给你几个简单有效的解决方案:
方案1:绑定前先移除旧委托(修改external.html)
直接在external.html的脚本里,每次绑定事件前先清除之前的委托:
<script id='script_external'> // 先移除document上针对#btn_clickme的click委托,再重新绑定 $(document).off('click','#btn_clickme').on('click','#btn_clickme',function(){ alert("This msg is from external file"); }); </script>
这样每次加载脚本时,都会先把之前的委托清理掉,确保只有当前这一个委托生效。
方案2:直接绑定到目标元素(修改external.html)
既然#btn_clickme是通过load()加载进来的,加载完成后它已经存在于DOM中,那我们可以直接把事件绑定到这个元素本身,而不是委托到document:
<script id='script_external'> // 直接绑定到#btn_clickme元素 $('#btn_clickme').on('click',function(){ alert("This msg is from external file"); }); </script>
这种方式下,当你用html("")清空#page_content时,旧的#btn_clickme元素会被移除,对应的事件也会自动销毁。下次加载新的元素时,会重新绑定一次事件,自然不会有重复触发的问题。
方案3:在main.html加载前清理委托(不修改external.html)
如果不想改动external.html的代码,也可以在main.html里触发load()之前,先把document上的旧委托清理掉:
$(document).on('click','#btn_load',function(){ $('#loading').show(); $('#page_content').html(""); // 加载前先移除旧的委托 $(document).off('click','#btn_clickme'); $('#page_content').load('external.html',function(){ $('#loading').hide(); }); });
这个思路和方案1类似,只是把清理委托的操作放到了main页面的加载逻辑里。
个人更推荐方案2,它更贴合动态元素的生命周期,不需要手动管理委托的清理,代码也更简洁。
内容的提问来源于stack exchange,提问作者jp26198926
相关产品推荐
相关产品推荐

