Codeigniter中AJAX加载的子视图内swal函数无法正常工作
解决CodeIgniter AJAX加载子视图后SweetAlert失效的问题
我之前也碰到过动态加载内容里JS失效的情况,结合你的代码,咱们一步步排查解决:
1. 先确认SweetAlert依赖是否全局可用
首先检查主页面(也就是引入settings_js.php的页面)有没有正确加载SweetAlert的JS和CSS文件。你在第一个AJAX的error回调里能正常调用swal(),说明主页面已经引入了,但要注意版本匹配:
- 如果你用的是SweetAlert2,必须引入
sweetalert2.min.js,因为swal.mixin是SweetAlert2的专属语法,旧版SweetAlert(v1)没有这个方法。 - 打开浏览器控制台(F12),直接输入
swal,如果能看到函数定义,说明全局可用;如果提示undefined,那就是依赖加载出了问题。
2. 修复动态内容的JS执行与事件绑定问题
你的子视图里用$("#bnk_form").submit(...)直接绑定事件,但如果这段JS在表单元素插入DOM前就执行了,绑定会直接失败。另外AJAX加载的HTML里的<script>标签偶尔会因为加载顺序问题无法正常执行,这里给你两个可行方案:
方案A:把子视图的JS移到AJAX的success回调中
把表单提交逻辑从子视图抽出来,放到主页面load_banks()函数的success回调里,确保DOM元素存在后再绑定事件:
function load_banks() { $.ajax({ url: 'settings/banks_view', type: "POST", dataType: "HTML", processData: false, contentType: false, success: function (data) { $(".content-page").html(data); // 在这里绑定表单提交事件,确保元素已存在 $("#bnk_form").submit(function (e) { e.preventDefault(); var form = document.forms.namedItem("bnk_form"); var oData = new FormData(form); $.ajax({ url: 'settings/bank_data_save', type: "POST", data: oData, dataType: "JSON", processData: false, contentType: false, success: function (data) { if (data.status == true) { $('#bank-modal').modal('toggle'); const toast = swal.mixin({ toast: true, position: 'top-end', showConfirmButton: false, timer: 3000 }); toast({ type: 'success', title: 'Signed in successfully' }) } else { swal("ERROR!", data, "error") } }, error: function (jqXHR, textStatus, errorThrown) { swal("JS ERROR!", jqXHR.responseText, 'error'); } }); }); }, error: function (jqXHR, textStatus, errorThrown) { swal("ERROR!", jqXHR.responseText, 'error'); } }) }
方案B:使用事件委托绑定事件
如果不想迁移代码,可以用jQuery的事件委托,把事件绑定到已存在的父元素(比如.content-page)上,这样动态插入的元素也能触发事件:
// 把这段代码放在主页面的JS里(比如settings_js.php),不要放在子视图中 $(".content-page").on("submit", "#bnk_form", function (e) { e.preventDefault(); var form = document.forms.namedItem("bnk_form"); var oData = new FormData(form); $.ajax({ url: 'settings/bank_data_save', type: "POST", data: oData, dataType: "JSON", processData: false, contentType: false, success: function (data) { if (data.status == true) { $('#bank-modal').modal('toggle'); const toast = swal.mixin({ toast: true, position: 'top-end', showConfirmButton: false, timer: 3000 }); toast({ type: 'success', title: 'Signed in successfully' }) } else { swal("ERROR!", data, "error") } }, error: function (jqXHR, textStatus, errorThrown) { swal("JS ERROR!", jqXHR.responseText, 'error'); } }); });
事件委托的原理是把事件绑定到已存在的父元素上,子元素触发事件时会冒泡到父元素处理,不管子元素是静态还是动态插入的,都能正常触发。
3. 检查控制台报错信息
打开浏览器开发者工具(F12)的Console标签,看看有没有JS报错:
- 如果提示
swal is not defined:说明SweetAlert没正确加载,或者加载顺序有问题(子视图JS先执行,SweetAlert还没加载完成)。 - 如果提示
Cannot read property 'mixin' of undefined:说明你用的是旧版SweetAlert,需要升级到SweetAlert2才能用swal.mixin。 - 如果提示
$("#bnk_form") is null:说明绑定事件时元素还不存在,用上面的方案A或B就能解决。
4. 避免重复绑定事件
如果多次调用load_banks(),每次插入新表单和JS会导致重复绑定,点击表单会触发多次AJAX请求。用事件委托的话就能避免这个问题,因为事件只绑定一次在父元素上。
按照上面的步骤排查,应该就能解决swal无法正常工作的问题了。
内容的提问来源于stack exchange,提问作者Hamaad Hussain
相关产品推荐
相关产品推荐

