动态插入HTML元素click事件失效?jQuery UI Dialog删除后导航交互修复
jQuery UI Dialog删除后新导航元素点击失效问题
我用jQuery UI Dialog展示可编辑页面数据,整体运行正常,但删除页面后重新加载导航元素时出问题。流程在AJAX成功回调里执行,用返回的新内容替换现有导航容器。
首次删除操作正常,通过$("#pagelist").html(data.links.join(""));插入的HTML显示没问题,但后续点击操作完全失效,必须刷新整个页面才行。
问题:如何更新元素并让新插入的元素具备交互功能?
精简代码
JavaScript
$(function() { $("#modalHtml").dialog({ autoOpen: false, height: 720, width: "90%", modal: true, closeOnEscape: true, classes: {"ui-dialog": "the-modal"}, buttons: [] }); $("#modal_Open_Button").click(function() { $("#modalHtml").dialog("open"); }); // nav item delete $("#pagelist").find(".pagelist-del").each(function(i,v) { $(v).on("click",function(e) { let pgid = $(this).data("page-delete"); $.post("ajax.php", { action: "page_delete", delid: pgid, tbl: "shows" }).done(function(data) { // reload navigation elements. // this works fine only for the display // but none of the click() events function unless the page is reloaded $("#pagelist").html(data.links.join("")); }); }); return; }); });
HTML
<button id="modal_open_button">Open Modal</button> <div id="modalHtml" title="Shows" style="display: none;"> <div id="pagelist"> <div class="flex flexmid gap2"> <span data-page-edit="1" class="pagelist-link" title="edit page">The new show</span> <span data-page-disable="1" title="disable">/</span> <span data-page-delete="1" class="pagelist-del" title="delete">X</span> </div> </div> </div>
ajax.php
if( file_exists($req->tbl.'/'.$req->delid.'.json') ) { $tbl = $req->tbl; $pagefile = $tbl.'/'.$req->delid.'.json'; $img = json_decode(file_get_contents($pagefile)); $img = $img->image; unlink($tbl.'/'.$img); unlink($pagefile); $datafiles = filelist($tbl,'.json',true); // scandir() process natsort($datafiles); $lastId = (int)basename(end($datafiles)); $pages=[]; foreach($datafiles as $k => $dbfile) { $pgid = (int)basename($dbfile); $data = file_get_contents($dbfile); $data = json_decode($data); $pages[] = ' <div class="flex flexmid gap2"> <span data-page-edit="'.$pgid.'" class="pagelist-link" title="edit page">'.$data->title.'</span> <span data-page-disable="'.$pgid.'" title="disable">/</span> <span data-page-delete="'.$pgid.'" class="pagelist-del" title="delete">X</span> </div>'; } // method to return JSON data to AJAX success function jsdata([ 'notice'=>'Page deleted successfully', 'class'=>'success', 'links'=>$pages, 'lastid'=>$lastId ]); }
解决方案
问题出在事件绑定方式上:你原来的代码是给页面加载时就存在的.pagelist-del元素逐个绑定点击事件,但AJAX更新后插入的新元素是动态生成的,没有被绑定事件,所以点击无效。
改用事件委托即可解决,把事件绑定到已经存在的父元素#pagelist上,让父元素监听子元素的点击事件:
修改后的JavaScript代码:
$(function() { $("#modalHtml").dialog({ autoOpen: false, height: 720, width: "90%", modal: true, closeOnEscape: true, classes: {"ui-dialog": "the-modal"}, buttons: [] }); $("#modal_Open_Button").click(function() { $("#modalHtml").dialog("open"); }); // 事件委托:绑定到父元素#pagelist,监听.pagelist-del的点击 $("#pagelist").on("click", ".pagelist-del", function(e) { let pgid = $(this).data("page-delete"); $.post("ajax.php", { action: "page_delete", delid: pgid, tbl: "shows" }).done(function(data) { $("#pagelist").html(data.links.join("")); }); }); });
原理说明
事件委托利用了DOM事件冒泡机制:点击子元素时,事件会向上冒泡到父元素,父元素通过判断触发事件的目标元素是否匹配.pagelist-del,来执行对应的逻辑。这样不管子元素是页面初始就有的,还是AJAX动态添加的,都能触发点击事件。
内容的提问来源于stack exchange,提问作者Nadal
相关产品推荐
相关产品推荐

