为何htmx:confirm事件在所有Ajax调用时均触发?
问题描述
为了用SweetAlert2替代浏览器默认确认UI,参考htmx官方示例给body绑定了htmx:confirm事件监听器,但现在所有Htmx发起的Ajax请求(包括页面加载、点击无hx-confirm属性的按钮)都会弹出确认框,预期仅带hx-confirm属性的#btn-change-w-confirm按钮触发确认框,这是操作有误还是正常现象?
示例代码
<!DOCTYPE html> <html> <head> <title>htmx test</title> </head> <body> <h1>TODOs</h1> <div id="content" hx-get="https://jsonplaceholder.typicode.com/todos/1" hx-trigger="load"> <p>...loading</p> </div> <br/> <button id="btn-change" hx-get="https://jsonplaceholder.typicode.com/todos/2" hx-target="#content">Change TODO</button> <button id="btn-change-w-confirm" hx-get="https://jsonplaceholder.typicode.com/todos/3" hx-confirm="Are you sure you want to change todo?" hx-target="#content">Change TODO w/Confirm</button> <script src="https://unpkg.com/htmx.org@1.9.12" integrity="sha384-ujb1lZYygJmzgSwoxRggbCHcjc0rB2XoQrxeTUQyRjrOnlCoYta87iKBWq3EsdM2" crossorigin="anonymous"></script> <script src="https://cdn.jsdelivr.net/npm/sweetalert2@11"></script> <script> document.body.addEventListener('htmx:confirm', function(e) { console.log('htmx:confirm', e.detail); e.preventDefault(); Swal.fire({ title: e.detail.question, showCancelButton: true, icon: "warning", }).then(function(result) { if(result.isConfirmed) e.detail.issueRequest(true); }); }); </script> </body> </html>
解决方法
这是操作有误导致的。htmx会为所有Ajax请求触发htmx:confirm事件,但只有带有hx-confirm属性的元素会在e.detail.question中携带确认文本,无该属性的元素触发事件时这个值为undefined。你的代码没有做判断就直接拦截所有请求并弹出弹窗,所以才会出现全局触发的问题。
修改事件监听器,增加判断逻辑,仅当存在确认文本时才弹出SweetAlert2:
document.body.addEventListener('htmx:confirm', function(e) { // 无确认需求时直接放行请求 if (!e.detail.question) return; console.log('htmx:confirm', e.detail); e.preventDefault(); Swal.fire({ title: e.detail.question, showCancelButton: true, icon: "warning", }).then(function(result) { if(result.isConfirmed) e.detail.issueRequest(true); }); });
这样修改后,只有带有hx-confirm属性的按钮才会触发自定义确认框,其他请求会正常执行,不会弹出确认弹窗。
内容的提问来源于stack exchange,提问作者Moses Machua
相关产品推荐
相关产品推荐

