使用jQuery重载div标签时内部脚本无法执行,如何解决?
解决jQuery load刷新后脚本不执行的问题
这个问题其实是jQuery的load()方法的默认特性导致的——当你用load()加载指定选择器的HTML片段时,jQuery会自动剥离返回内容里的<script>标签,不会执行它们,哪怕你明确指定了#div1也一样。而页面首次加载时能执行脚本,是因为浏览器会完整解析整个HTML文档,遇到脚本标签就直接执行了,和load()的处理逻辑完全不同。
下面给你几个可行的解决办法,你可以根据自己的场景选择:
方法1:分离脚本到独立函数(推荐)
把smarty1.tpl里的脚本逻辑抽出来,放到父页面(smarty2.tpl)或者单独的JS文件中,通过函数调用的方式执行,这也是前端代码分离的最佳实践。
- 在smarty2.tpl里定义一个执行脚本的函数:
function executeDiv1Script() { alert('script is executing'); // 把smarty1.tpl里原来的其他脚本逻辑也移到这里 }
- 页面初始化和
load()完成后分别调用这个函数:
$(document).ready(function() { // 页面首次加载时执行一次 executeDiv1Script(); $('#choose').change(function(event) { $("#div1").load(location.href + " #div1", function() { // 刷新完成后再次执行脚本 executeDiv1Script(); }); }); });
- 记得把smarty1.tpl里的
<script>标签删掉,只保留HTML结构即可。
方法2:手动获取HTML并处理脚本(保留原模板脚本)
如果必须保留脚本在smarty1.tpl里,可以不用load(),改用$.get()手动获取页面内容,然后提取DOM并执行脚本:
$('#choose').change(function(event) { $.get(location.href, function(responseData) { // 从返回的整个页面中提取#div1的内容 var newDiv1 = $(responseData).find('#div1'); // 替换页面上的#div1 $('#div1').replaceWith(newDiv1); // 手动执行#div1里的所有脚本 newDiv1.find('script').each(function() { // 创建新的script标签执行内容 var scriptEl = document.createElement('script'); scriptEl.textContent = $(this).text(); document.body.appendChild(scriptEl); // 执行完可以移除,避免冗余 document.body.removeChild(scriptEl); }); }); });
注意:如果你的脚本内容包含用户输入等不可控内容,这种方式要注意安全风险,避免XSS问题。
方法3:给脚本加标识,在回调中触发
给smarty1.tpl里的脚本添加自定义属性,然后在load()的回调中找到这些脚本并执行:
- 修改smarty1.tpl里的脚本:
<script data-div1-script> alert('script is executing'); </script>
- 在smarty2.tpl的
change事件回调中处理:
$('#choose').change(function(event) { $("#div1").load(location.href + " #div1", function() { // 找到带自定义属性的脚本并执行 $(this).find('script[data-div1-script]').each(function() { eval($(this).text()); }); }); });
这种方式改动最小,不用大改原有的模板结构,但同样要注意eval的安全问题。
内容的提问来源于stack exchange,提问作者Amir
相关产品推荐
相关产品推荐

