簡體   English   中英

引導模式關閉事件為什么會“堆棧”?

[英]Why does bootstrap modal close event “stack”?

我正在嘗試制作一個可以多次添加到頁面的確認控件,但是我偶然發現了導致這些控件彼此“接觸”的錯誤(顯然,我想讓它們獨立工作)。

我為此使用了Bootstrap,並且使用了盡可能少的jQuery(由於調試)。

經過切片后,我發現在代碼中,Bootstrap關閉功能將多次運行,從而導致此問題。 會有人碰巧知道為什么該Bootstrap函數會多次運行嗎?

這將是我的問題的原因

$("").on("hidden.bs.modal", function (e) {
  //Why does this stack?
  alert("Why does this stack?");
});

這是我的代碼的上下文 ,它將在其中多次運行:

 //Yes selector const positiveSelector = ".positive"; //No selector const negativeSelector = ".negative"; //Confirm? selector const confirmSelector = ".init-confirm" //Pending selector const pendingSelector = ".pending"; //Yes ele const positiveNodes = document.querySelectorAll(positiveSelector); //No ele const negativeNodes = document.querySelectorAll(negativeSelector); //Confirm? ele const confirmNodes = document.querySelectorAll(confirmSelector); //Pending ele const pendingNodes = document.querySelectorAll(pendingSelector); //Modal related: const $modalInit = $(".modal").html(); const targetModal = $("#bs-modal-xl"); positiveNodes.forEach(node => node.addEventListener("click", function () { let thisNode = this; thisNode.classList.add("btn-success"); thisNode.parentNode.querySelectorAll(negativeSelector).forEach(node => node.classList.remove("btn-warning")); thisNode.parentNode.parentNode.querySelectorAll(confirmSelector).forEach(node => node.removeAttribute("disabled")); })); negativeNodes.forEach(node => node.addEventListener("click", function () { let thisNode = this; thisNode.classList.add("btn-warning"); thisNode.parentNode.querySelectorAll(positiveSelector).forEach(node => node.classList.remove("btn-success")); thisNode.parentNode.parentNode.querySelectorAll(confirmSelector).forEach(node => node.setAttribute("disabled", "")); thisNode.parentNode.parentNode.querySelectorAll(pendingSelector).forEach(node => node.style.display = "none"); })); confirmNodes.forEach(node => node.addEventListener("click", function () { let thisNode = this; thisNode.parentNode.querySelectorAll(pendingSelector).forEach(node => node.style.display = "inline-block"); thisNode.parentNode.querySelectorAll(pendingSelector).forEach(node => node.classList.remove("btn-warning")); thisNode.parentNode.querySelectorAll(pendingSelector).forEach(node => node.classList.add("btn-danger")); thisNode.parentNode.querySelectorAll(pendingSelector).forEach(node => node.textContent = "Pending"); //Populate modal: ModalHandler($(".my-ele").clone(), "My ele", undefined, true, true); $(".modal .my-ele").show(); //Show Modal: targetModal.modal(); $(".modal").on("click", ".my-ele button", function () { targetModal.modal("hide"); }); //When closing Modal: targetModal.on("hidden.bs.modal", function (e) { //Why does this stack? alert("Why does this stack?"); }); })); //Modal handling (not required when not using Modal): function ModalHandler(content, title, footer = "", bigCloseBtn = false, emptyFooter = false) { $(".modal h4.modal-title").text(title); $(".modal .modal-body").html(content); if (footer != "" && footer != undefined) { $(".modal .modal-footer").html(footer); } if (bigCloseBtn) { $(".modal .modal-content .modal-header button.close").css("float", "right"); $(".modal .modal-content .modal-header button.close").addClass("btn btn-lg btn-danger"); //$(".modal .modal-content .modal-header button.close").html("close"); $(".modal .modal-content .modal-header button.close").removeClass("close"); } if (emptyFooter) { $(".modal .modal-content .modal-footer").html(""); } } $(".modal").on("hidden.bs.modal", function () { $(".modal").html($modalInit); }); 
 #foo-container { padding: 5px; } .pending { display: none; } .my-ele { display: none; } 
 <link href="https://stackpath.bootstrapcdn.com/bootstrap/3.4.1/css/bootstrap.min.css" rel="stylesheet"/> <script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script> <script src="https://stackpath.bootstrapcdn.com/bootstrap/3.4.1/js/bootstrap.min.js"></script> <div class="modal" id="bs-modal-xl" tabindex="-1" role="dialog" aria-labelledby="myLargeModalLabel"> <div class="modal-dialog modal-lg" role="document"> <div class="modal-content"> <div class="modal-header"> <button type="button" class="close" data-dismiss="modal" aria-label="Close"><span aria-hidden="true">&times;</span></button> <h4 class="modal-title">Modal title</h4> </div> <div class="modal-body"> <p>One fine body&hellip;</p> </div> <div class="modal-footer"> <button type="button" class="btn btn-default" data-dismiss="modal">Close</button> <button type="button" class="btn btn-primary">Save changes</button> </div> </div> </div> </div> <div id="foo-container"> <div class="confirmation-box"> <div class="btn-group btn-group-lg" role="group" aria-label="..."> <button type="button" class="btn btn-success positive">Yes</button> <button type="button" class="btn btn-warning negative">No</button> </div> <button type="button" class="btn btn-lg btn-danger init-confirm" disabled>Confirm?</button> <button type="button" class="btn btn-lg btn-danger pending" disabled>Pending</button> </div> <br /> <div class="confirmation-box"> <div class="btn-group btn-group-lg" role="group" aria-label="..."> <button type="button" class="btn btn-success positive">Yes</button> <button type="button" class="btn btn-warning negative">No</button> </div> <button type="button" class="btn btn-lg btn-danger init-confirm" disabled>Confirm?</button> <button type="button" class="btn btn-lg btn-danger pending" disabled>Pending</button> </div> </div> <div class="my-ele"> <button type="button" class="btn btn-lg btn-success">Clicky</button> </div> 

的jsfiddle

為了重現我的問題,必須通過單擊“是”按鈕以啟用“確認?”來打開模態。 按鈕,然后單擊此按鈕。 然后退出模態。 該事件將運行一次,但是,當重復打開和關閉模式時,警報將開始堆疊(由於事件由於某種原因而開始堆疊,我不理解)。

我之所以有

.on("hidden.bs.modal", function (e) {}); eventListener

任何

<button type="button" class="btn btn-lg btn-danger init-confirm" disabled>Confirm?</button>

因為我需要將clicked元素作為參數傳遞給外部函數。

我可以使模式關閉函數只運行一次而不是“讓它們堆積”嗎?

這是因為該事件一遍targetModal.on應用於targetModal.on 你需要把它off

targetModal.off();

 //Yes selector const positiveSelector = ".positive"; //No selector const negativeSelector = ".negative"; //Confirm? selector const confirmSelector = ".init-confirm" //Pending selector const pendingSelector = ".pending"; //Yes ele const positiveNodes = document.querySelectorAll(positiveSelector); //No ele const negativeNodes = document.querySelectorAll(negativeSelector); //Confirm? ele const confirmNodes = document.querySelectorAll(confirmSelector); //Pending ele const pendingNodes = document.querySelectorAll(pendingSelector); //Modal related: const $modalInit = $(".modal").html(); const targetModal = $("#bs-modal-xl"); positiveNodes.forEach(node => node.addEventListener("click", function() { let thisNode = this; thisNode.classList.add("btn-success"); thisNode.parentNode.querySelectorAll(negativeSelector).forEach(node => node.classList.remove("btn-warning")); thisNode.parentNode.parentNode.querySelectorAll(confirmSelector).forEach(node => node.removeAttribute("disabled")); })); negativeNodes.forEach(node => node.addEventListener("click", function() { let thisNode = this; thisNode.classList.add("btn-warning"); thisNode.parentNode.querySelectorAll(positiveSelector).forEach(node => node.classList.remove("btn-success")); thisNode.parentNode.parentNode.querySelectorAll(confirmSelector).forEach(node => node.setAttribute("disabled", "")); thisNode.parentNode.parentNode.querySelectorAll(pendingSelector).forEach(node => node.style.display = "none"); })); confirmNodes.forEach(node => node.addEventListener("click", function() { let thisNode = this; thisNode.parentNode.querySelectorAll(pendingSelector).forEach(node => node.style.display = "inline-block"); thisNode.parentNode.querySelectorAll(pendingSelector).forEach(node => node.classList.remove("btn-warning")); thisNode.parentNode.querySelectorAll(pendingSelector).forEach(node => node.classList.add("btn-danger")); thisNode.parentNode.querySelectorAll(pendingSelector).forEach(node => node.textContent = "Pending"); //Populate modal: ModalHandler($(".my-ele").clone(), "My ele", undefined, true, true); $(".modal .my-ele").show(); //Show Modal: targetModal.modal(); $(".modal").on("click", ".my-ele button", function() { targetModal.modal("hide"); }); //When closing Modal: targetModal.on("hidden.bs.modal", function(e) { //Why does this stack? alert("Why does this stack?"); targetModal.off(); }); })); //Modal handling (not required when not using Modal): function ModalHandler(content, title, footer = "", bigCloseBtn = false, emptyFooter = false) { $(".modal h4.modal-title").text(title); $(".modal .modal-body").html(content); if (footer != "" && footer != undefined) { $(".modal .modal-footer").html(footer); } if (bigCloseBtn) { $(".modal .modal-content .modal-header button.close").css("float", "right"); $(".modal .modal-content .modal-header button.close").addClass("btn btn-lg btn-danger"); //$(".modal .modal-content .modal-header button.close").html("close"); $(".modal .modal-content .modal-header button.close").removeClass("close"); } if (emptyFooter) { $(".modal .modal-content .modal-footer").html(""); } } $(".modal").on("hidden.bs.modal", function() { $(".modal").html($modalInit); }); 
 #foo-container { padding: 5px; } .pending { display: none; } .my-ele { display: none; } 
 <link href="https://stackpath.bootstrapcdn.com/bootstrap/3.4.1/css/bootstrap.min.css" rel="stylesheet" /> <script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script> <script src="https://stackpath.bootstrapcdn.com/bootstrap/3.4.1/js/bootstrap.min.js"></script> <div class="modal" id="bs-modal-xl" tabindex="-1" role="dialog" aria-labelledby="myLargeModalLabel"> <div class="modal-dialog modal-lg" role="document"> <div class="modal-content"> <div class="modal-header"> <button type="button" class="close" data-dismiss="modal" aria-label="Close"><span aria-hidden="true">&times;</span></button> <h4 class="modal-title">Modal title</h4> </div> <div class="modal-body"> <p>One fine body&hellip;</p> </div> <div class="modal-footer"> <button type="button" class="btn btn-default" data-dismiss="modal">Close</button> <button type="button" class="btn btn-primary">Save changes</button> </div> </div> </div> </div> <div id="foo-container"> <div class="confirmation-box"> <div class="btn-group btn-group-lg" role="group" aria-label="..."> <button type="button" class="btn btn-success positive">Yes</button> <button type="button" class="btn btn-warning negative">No</button> </div> <button type="button" class="btn btn-lg btn-danger init-confirm" disabled>Confirm?</button> <button type="button" class="btn btn-lg btn-danger pending" disabled>Pending</button> </div> <br /> <div class="confirmation-box"> <div class="btn-group btn-group-lg" role="group" aria-label="..."> <button type="button" class="btn btn-success positive">Yes</button> <button type="button" class="btn btn-warning negative">No</button> </div> <button type="button" class="btn btn-lg btn-danger init-confirm" disabled>Confirm?</button> <button type="button" class="btn btn-lg btn-danger pending" disabled>Pending</button> </div> </div> <div class="my-ele"> <button type="button" class="btn btn-lg btn-success">Clicky</button> </div> 

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM