JQuery UI Dialog确认成功函数执行但不生效问题排查
问题:原生confirm替换为jQuery UI Dialog后删除逻辑失效
原本使用原生confirm实现的删除功能运行正常,替换为jQuery UI Dialog后,弹窗可正常显示,成功回调函数能执行(有console.log输出),但实际删除逻辑并未生效,怀疑是this指向问题。
原生可正常运行的代码
row.find('a.' + delCssSelector).click(function() { var result = confirm("Are you sure you want to Delete?"); if (result) { var row = $(this).parents('.dynamic-form'); var itemIdInput = row.find('input:hidden[id $= "-id"]'); var itemId = itemIdInput.val(); var deleteInput = `<input type="hidden" name="research_line_items_to_delete" value="${itemId}">`; if ($(deleteInput).val()) { $('#research_line_items_to_delete').append(deleteInput); } var row = $(this).parents('.' + options.formCssClass), del = row.find('input:hidden[id $= "-DELETE"]'), buttonRow = row.siblings("a." + addCssSelector + ', .' + options.formCssClass + '-add'), forms; if (del.length) { del.val('on'); row.hide(); forms = $('.' + options.formCssClass); totalForms.val(forms.length); } else { row.remove(); forms = $('.' + options.formCssClass).not('.formset-custom-template'); totalForms.val(forms.length); } for (var i = 0, formCount = forms.length; i < formCount; i++) { applyExtraClasses(forms.eq(i), i); if (!del.length) { forms.eq(i).find(childElementSelector).each(function() { updateElementIndex($(this), options.prefix, i); }); } } if (!showDeleteLinks()) { $('a.' + delCssSelector).each(function() { $(this).hide(); }); } if (buttonRow.is(':hidden') && showAddButton()) buttonRow.show(); if (options.removed) options.removed(row); return false; } });
改写后的jQuery UI Dialog代码(回调仅输出日志,逻辑不生效)
row.find('a.' + delCssSelector).click(function() { var target = $(this).attr("href"); var content = $(this).attr("title"); var title = $(this).attr("alt"); $("#dialog").dialog({ draggable: false, modal: true, resizable: false, width: 'auto', title: title, buttons: { 'Yes': function() { $(this).dialog('close'); callback(true); }, 'No': function() { $(this).dialog('close'); callback(false); } } }); function callback(value) { if (value) { var row = $(this).parents('.dynamic-form'); var itemIdInput = row.find('input:hidden[id $= "-id"]'); var itemId = itemIdInput.val(); var deleteInput = `<input type="hidden" name="research_line_items_to_delete" value="${itemId}">`; console.log("hereyo"); if ($(deleteInput).val()) { $('#research_line_items_to_delete').append(deleteInput); } console.log($(deleteInput).val()); var row = $(this).parents('.' + options.formCssClass), del = row.find('input:hidden[id $= "-DELETE"]'), buttonRow = row.siblings("a." + addCssSelector + ', .' + options.formCssClass + '-add'), forms; if (del.length) { del.val('on'); row.hide(); forms = $('.' + options.formCssClass); totalForms.val(forms.length); } else { row.remove(); forms = $('.' + options.formCssClass).not('.formset-custom-template'); totalForms.val(forms.length); } for (var i = 0, formCount = forms.length; i < formCount; i++) { applyExtraClasses(forms.eq(i), i); if (!del.length) { forms.eq(i).find(childElementSelector).each(function() { updateElementIndex($(this), options.prefix, i); }); } } if (!showDeleteLinks()) { $('a.' + delCssSelector).each(function() { $(this).hide(); }); } if (buttonRow.is(':hidden') && showAddButton()) buttonRow.show(); if (options.removed) options.removed(row); return false; } } });
关联HTML
<div id="dialog" title="Basic dialog"> <p>This is the default dialog which is useful for displaying information. The dialog window can be moved, resized and closed with the 'x' icon.</p> </div>
解决方案
问题核心就是**this指向错误**:
- 原生
confirm逻辑里,this指向触发点击的删除按钮; - 换成jQuery UI Dialog后,Dialog按钮回调里的
this指向Dialog容器(#dialog),自定义callback函数里的this默认指向全局对象(浏览器中为window),导致无法正确定位要删除的行元素,后续逻辑全部失效。
修改步骤:
- 在最外层
click事件中,提前保存当前删除按钮的引用; - 将删除逻辑中所有
$(this)替换为保存的按钮引用; - 简化嵌套层级,直接把删除逻辑写在"Yes"按钮的回调里,避免额外函数带来的
this混乱。
修改后的完整代码:
row.find('a.' + delCssSelector).click(function() { // 保存当前点击的删除按钮引用 var $deleteBtn = $(this); var title = $deleteBtn.attr("alt"); $("#dialog").dialog({ draggable: false, modal: true, resizable: false, width: 'auto', title: title, buttons: { 'Yes': function() { $(this).dialog('close'); // 执行删除逻辑,使用提前保存的按钮引用 var row = $deleteBtn.parents('.dynamic-form'); var itemIdInput = row.find('input:hidden[id $= "-id"]'); var itemId = itemIdInput.val(); var deleteInput = `<input type="hidden" name="research_line_items_to_delete" value="${itemId}">`; if (itemId) { // 直接判断itemId更可靠,无需重复创建jQuery对象 $('#research_line_items_to_delete').append(deleteInput); } var row = $deleteBtn.parents('.' + options.formCssClass), del = row.find('input:hidden[id $= "-DELETE"]'), buttonRow = row.siblings("a." + addCssSelector + ', .' + options.formCssClass + '-add'), forms; if (del.length) { del.val('on'); row.hide(); forms = $('.' + options.formCssClass); totalForms.val(forms.length); } else { row.remove(); forms = $('.' + options.formCssClass).not('.formset-custom-template'); totalForms.val(forms.length); } for (var i = 0, formCount = forms.length; i < formCount; i++) { applyExtraClasses(forms.eq(i), i); if (!del.length) { forms.eq(i).find(childElementSelector).each(function() { updateElementIndex($(this), options.prefix, i); }); } } if (!showDeleteLinks()) { $('a.' + delCssSelector).each(function() { $(this).hide(); }); } if (buttonRow.is(':hidden') && showAddButton()) buttonRow.show(); if (options.removed) options.removed(row); }, 'No': function() { $(this).dialog('close'); } } }); });
关键说明:
- 用
var $deleteBtn = $(this);锁定按钮引用,确保后续逻辑能正确获取触发删除操作的按钮; - 删除冗余的
callback函数,减少嵌套层级,彻底避免this指向混乱; - 优化
deleteInput的判断逻辑,直接用itemId判断更高效,无需重复创建jQuery对象。
内容的提问来源于stack exchange,提问作者Steve Smith
相关产品推荐
相关产品推荐

