Tailwindcss/Flowbite 弹窗关闭按钮在input onchange事件中失效
问题:文件上传
onchange事件中创建的Flowbite提示框关闭按钮失效 我编写了一个showSuccessAlert函数,用于生成带滑入动画的提示弹窗,一段时间后自动滑出销毁。函数会向DOM插入从Flowbite复制的提示框组件。常规调用时弹窗显示、自动关闭和关闭按钮都正常工作,但在文件类型input的onchange事件回调中调用该函数时,弹窗能正常显示,关闭按钮完全失效,自动关闭功能不受影响。
原因分析
Flowbite的提示框关闭功能依赖自身JS在页面加载时初始化事件监听器,但它只会给页面加载时已存在的DOM元素绑定事件。当你在onchange事件中动态创建提示框后,Flowbite并没有感知到新元素的存在,也就不会给新的关闭按钮绑定点击事件,导致按钮失效。而页面加载时直接调用的弹窗能正常工作,是因为Flowbite初始化时它已经在DOM中了。
解决方案
提供两种可行的修复方式:
方案1:手动绑定关闭事件
不依赖Flowbite的自动初始化,自己给新创建的关闭按钮添加点击事件,实现弹窗销毁逻辑:
function showSuccessAlert(content, timeoutTime = 3000) { const alertContainer = document.querySelector("#alert"); const alertChild = document.createElement("div"); const classList = `flex items-center p-4 mb-4 text-green-800 border-t-4 border-green-300 bg-green-50 dark:text-green-400 dark:bg-gray-800 dark:border-green-800`.split(" "); classList.forEach(className => alertChild.classList.add(className)); alertChild.id = `alert-box-${alertContainer.childElementCount}`; alertChild.setAttribute("role", "alert"); alertChild.innerHTML = ` <svg class="flex-shrink-0 w-4 h-4" aria-hidden="true" xmlns="http://www.w3.org/2000/svg" fill="currentColor" viewBox="0 0 20 20"> <path d="M10 .5a9.5 9.5 0 1 0 9.5 9.5A9.51 9.51 0 0 0 10 .5ZM9.5 4a1.5 1.5 0 1 1 0 3 1.5 1.5 0 0 1 0-3ZM12 15H8a1 1 0 0 1 0-2h1v-3H8a1 1 0 0 1 0-2h2a1 1 0 0 1 1 1v4h1a1 1 0 0 1 0 2Z"/> </svg> <div id="alertContent" class="ml-3 text-sm font-medium">${content}</div> <button type="button" class="ml-auto -mx-1.5 -my-1.5 bg-green-50 text-green-500 rounded-lg focus:ring-2 focus:ring-green-400 p-1.5 hover:bg-green-200 inline-flex items-center justify-center h-8 w-8 dark:bg-gray-800 dark:text-green-400 dark:hover:bg-gray-700" aria-label="Close"> <span class="sr-only">Dismiss</span> <svg class="w-3 h-3" aria-hidden="true" xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 14 14"> <path stroke="currentColor" stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="m1 1 6 6m0 0 6 6M7 7l6-6M7 7l-6 6"/> </svg> </button> `; alertChild.style.transition = "transform 0.75s"; alertContainer.appendChild(alertChild); alertChild.style.animation = "wipe-alert 0.75s ease-in-out"; // 手动绑定关闭按钮点击事件 const closeBtn = alertChild.querySelector("button"); closeBtn.addEventListener("click", () => { alertChild.style.transform = "translateX(100%)"; setTimeout(() => alertContainer.removeChild(alertChild), 750); clearTimeout(autoCloseTimer); // 清除自动关闭定时器 }); // 自动关闭定时器 const autoCloseTimer = setTimeout(() => { alertChild.style.transform = "translateX(100%)"; setTimeout(() => alertContainer.removeChild(alertChild), 750); }, timeoutTime); }
方案2:手动调用Flowbite初始化方法
在动态创建提示框并插入DOM后,调用Flowbite的initAlert方法,让它给新元素绑定事件:
function showSuccessAlert(content, timeoutTime = 3000) { const alertContainer = document.querySelector("#alert"); const alertChild = document.createElement("div"); const classList = `flex items-center p-4 mb-4 text-green-800 border-t-4 border-green-300 bg-green-50 dark:text-green-400 dark:bg-gray-800 dark:border-green-800`.split(" "); classList.forEach(className => alertChild.classList.add(className)); alertChild.id = `alert-box-${alertContainer.childElementCount}`; alertChild.setAttribute("role", "alert"); // 保留data-dismiss-target属性,Flowbite需要它定位目标弹窗 alertChild.innerHTML = ` <svg class="flex-shrink-0 w-4 h-4" aria-hidden="true" xmlns="http://www.w3.org/2000/svg" fill="currentColor" viewBox="0 0 20 20"> <path d="M10 .5a9.5 9.5 0 1 0 9.5 9.5A9.51 9.51 0 0 0 10 .5ZM9.5 4a1.5 1.5 0 1 1 0 3 1.5 1.5 0 0 1 0-3ZM12 15H8a1 1 0 0 1 0-2h1v-3H8a1 1 0 0 1 0-2h2a1 1 0 0 1 1 1v4h1a1 1 0 0 1 0 2Z"/> </svg> <div id="alertContent" class="ml-3 text-sm font-medium">${content}</div> <button type="button" class="ml-auto -mx-1.5 -my-1.5 bg-green-50 text-green-500 rounded-lg focus:ring-2 focus:ring-green-400 p-1.5 hover:bg-green-200 inline-flex items-center justify-center h-8 w-8 dark:bg-gray-800 dark:text-green-400 dark:hover:bg-gray-700" data-dismiss-target="#${alertChild.id}" aria-label="Close"> <span class="sr-only">Dismiss</span> <svg class="w-3 h-3" aria-hidden="true" xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 14 14"> <path stroke="currentColor" stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="m1 1 6 6m0 0 6 6M7 7l6-6M7 7l-6 6"/> </svg> </button> `; alertChild.style.transition = "transform 0.75s"; alertContainer.appendChild(alertChild); alertChild.style.animation = "wipe-alert 0.75s ease-in-out"; // 调用Flowbite的初始化方法,绑定新提示框的关闭事件 if (window.Flowbite?.Alert) { window.Flowbite.Alert.initAlert(); } setTimeout(() => { alertChild.style.transform = "translateX(100%)"; setTimeout(() => alertContainer.removeChild(alertChild), 750); }, timeoutTime); }
其他代码保持不变
CSS和HTML代码无需修改,继续使用原代码即可。
内容的提问来源于stack exchange,提问作者hemant kumar
相关产品推荐
相关产品推荐

