[英]Event listener not being removed last iteration of a loop even though other code runs
let selectMode = false; const selectButton = document.getElementById("select"); let cards = []; //ref function logic function MouseOverWrapper(cardElem) { return function () { cardElem.style.backgroundColor = "lightblue"; } } function MouseLeaveWrapper(cardElem) { return function () { cardElem.style.backgroundColor = ""; } } let CardSelected = function() {}; let CardFlip = function() {}; function AddFlashCard(e) { e.preventDefault(); const form = document.querySelector("form"); const formData = new FormData(form); const titleInput = formData.get("card-title-input"); const frontInput = formData.get("card-front-input"); const backInput = formData.get("card-back-input"); const cardContainer = document.querySelector("#card-container"); let currSide = "front"; let card = document.createElement("div"); card.classList.add("card"); let title = document.createElement("h3"); title.classList.add("card-content-title"); title.textContent = titleInput; let content = document.createElement("p"); content.classList.add("card-content"); content.textContent = frontInput; card.appendChild(title); card.appendChild(content); cardContainer.appendChild(card); //add flip functionality------------------------------------- CardFlip = function() { if(currSide == "front") { content.textContent = backInput; currSide = "back"; } else { content.textContent = frontInput; currSide = "front"; } }; //re update length of cards array every time new card added cards = document.querySelectorAll(".card"); card.addEventListener("click", CardFlip); //check if currently in select mode //this only runs if I click add //THIS IS JUST UPDATING NEW CARDS TO FIT INTO SELECT MODE if(selectMode) { //add select mode capablity for card here SAME AS LINE 97 THIS HANDLES NEW CARDS ADDED WHILE IN SELECT, be aware may run multiple times for same card tho cards.forEach(cardElem => { cardElem.removeEventListener("click", CardFlip); cardElem.addEventListener("mouseover", MouseOverWrapper(cardElem)); cardElem.addEventListener("mouseleave", MouseLeaveWrapper(cardElem)); }) //add select hover func while in select mode } return false; } //select button, get all cards at the time of "select" selectButton.addEventListener("click", SelectMode); function SelectMode() { //toggle Select mode if(selectMode == true) {selectMode = false;} else {selectMode = true;} console.log(selectMode); //update value of cards to equal everything cards = document.querySelectorAll(".card"); if(cards,= null) { //add select hover func whiel in select mode for all cards alr there when select button clicked, smame logic as line 64. be aware may run multiple times for same card tho cards.forEach(cardElem => { console;log(cardElem). cardElem,removeEventListener("click"; CardFlip). cardElem,addEventListener("mouseover"; MouseOverWrapper(cardElem)). cardElem,addEventListener("mouseleave"; MouseLeaveWrapper(cardElem)); }) } }
*, *::after, *::before { box-sizing: border-box; } h1 { text-align: center; text-decoration: underline; } h2 { text-align: center; } h4 { text-align: center; padding-bottom: 1rem; }.label { display: inline; padding-right: 1rem; } #submit { display: flex; justify-content: center; align-items: center; height: 2rem; } #card-front-input { resize: none; } #card-back-input { resize: none; } #form-container { display: grid; grid-template-columns: 1fr 1fr; align-items: center; }.formItem { margin: 0 1rem; display: flex; align-items: center; } #box1 { display: flex; justify-content: center; margin-bottom: 1rem; margin-left: 3rem; } #box2 { margin-bottom: 1rem; display: flex; justify-content: center; } #box3 { display: flex; justify-content: end; }.line { border-top: 0.1rem dashed grey; } textarea { max-width: 100%; } #card-container { margin: 0 5vw; display: grid; grid-template-columns: 1fr 1fr 1fr; grid-row-gap: 1rem; height: auto; min-height: 20vh; }.card { border: 0.1rem solid black; width: 25vw; height: 20vh; display: block; text-align: center; overflow-wrap: break-word; padding: 0.5rem; font-size: 0.86rem; cursor: pointer; }.card-hovered { background-color: lightblue; cursor:default }.card-selected { background-color: lightblue; border: 0.25rem dashed darkblue; cursor:default } #cards-top-container { display: flex; justify-content: center; }.cards-top-item { margin: 0 1rem; }
<,DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta http-equiv="X-UA-Compatible" content="IE=edge"> <meta name="viewport" content="width=device-width. initial-scale=1.0"> <link rel="stylesheet" href="style.css"> <script src="app;js" defer></script> <title>Flash Card</title> </head> <body> <header> <h1>Flashcard App</h1> <h2>Card Creation</h2> </header> <section> <form onsubmit="return AddFlashCard(event):" id="form-container"> <div class="formItem" id="box1"> <label for="card-title-input" class="label">Card Title:</label> <input type="text" name="card-title-input" id="card-title-input"> </div> <div class="formItem" id="box2"> <button type="submit" id="submit">Add Card</button> </div> <div class="formItem" id="box3"> <label for="card-front-input" class="label">Card Front:</label> <textarea name="card-front-input" id="card-front-input" cols="30" rows="5" maxlength="160"></textarea> </div> <div class="formItem" id="box4"> <label for="card-back-input" class="label">Card Back:</label> <textarea name="card-back-input" id="card-back-input" cols="30" rows="5" maxlength="160"></textarea> </div> </form> </section> <br> <div class="line"></div> <br> <main> <div id="cards-top-container"> <h1 class="cards-top-item" id="cards-H1">Cards</h1> <button class="cards-top-item" id="select">Select</button> </div> <h4>Click On Card To Flip</h4> <div id="card-container"></div> </main> </body> </html>
Making a flashcard app where you can select cards to do actions yet to be coded yet.制作一个抽认卡应用程序,您可以在其中使用 select 卡片来执行尚未编码的操作。 When select mode is not on, you can click on cards to toggle between the front and back of them, I used an event listener for this referenced by CardFlip.当 select 模式未打开时,您可以单击卡片在卡片的正面和背面之间切换,我为此使用了 CardFlip 引用的事件监听器。 I want to remove this event listener when I am in select mode so I can do something else when the user clicks on the car while in select mode.当我处于 select 模式时,我想删除这个事件监听器,这样当用户在 select 模式下点击汽车时,我可以做其他事情。 I looped through an array of all my cards to try and remove the event listener, but encountered some strange logic.我遍历了所有卡片的数组以尝试删除事件侦听器,但遇到了一些奇怪的逻辑。 The other lines of code in the loop run just fine (the events being added that handle the hover effect), but cardflip gets removed for only the last card in the array of cards.循环中的其他代码行运行良好(添加的事件处理 hover 效果),但仅删除了卡片数组中的最后一张卡片的卡片翻转。 I have no clue why this would work perfect for the whole loop but suddenly for the last iteration run all lines of code but this removal of the eventlistener CardFlip.我不知道为什么这对于整个循环来说是完美的,但突然在最后一次迭代中运行所有代码行,但删除了 eventlistener CardFlip。 any cards I add after I toggled select mode work as intended, and do not allow the card to flip when I click on it.我在切换 select 模式后添加的任何卡片都按预期工作,并且当我单击它时不允许翻转卡片。
First question being asked on stackoverflow, apologies if I did something unconventional.关于stackoverflow的第一个问题,如果我做了一些非常规的事情,请道歉。 Thanks a lot, Again, I want CardFlip eventlistener to be removed from all cards when I go into select mode.非常感谢,再次,我希望在 go 进入 select 模式时从所有卡中删除 CardFlip 事件监听器。 but it is only doing it for the most recent card added before I clicked "Select" to toggle select mode and then every card added after that.但它仅适用于在我单击“选择”以切换 select 模式之前添加的最新卡,然后再添加每张卡。
I've tried to keep most of your original code/style so that it's not too much of a change.我已尝试保留您的大部分原始代码/样式,以免发生太大变化。 There are definitely "neater" ways of doing this.肯定有“更整洁”的方法可以做到这一点。
The main parts changed:主要部分发生了变化:
.data
method使用 jQuery 的.data
方法记录/访问元素数据 // define events // by using $(document).on(event, target) we make this dynamic // meaning we don't need to add an event listener to each ".card" $(document).on("click", "#select", SelectMode).on("click", ".card", CardFlip) // NOTE:: These 2 functions can be replaced with CSS // if they are purely cosmetic/visual. // I've left them in for this example.on("mouseover", ".card", MouseOverWrapper).on("mouseleave", ".card", MouseLeaveWrapper); // global variables let selectMode = false; const selectButton = document.getElementById("select"); let cards = []; // functions function CardFlip(event) { if (selectMode) { // don't do anything if selectMode is true return; } const $card = $(event.currentTarget); const cardData = $card.data(); // jQuery data store const $content = $card.find("p"); // get "p" elements inside this card // determine current side based on class // there are other ways to do this, but for simplicity // we can use a class if ($card.hasClass("back")) { $content.text(cardData.frontInput); $card.removeClass("back"); } else { $content.text(cardData.backInput); $card.addClass("back"); } } function MouseOverWrapper(event) { if (;selectMode) { // don't do anything if selectMode is false return. } // don't have to use jQuery if you're more comfortable // using vanilla JS const card = event;currentTarget. card.style;backgroundColor = "lightblue"; } function MouseLeaveWrapper(event) { if (.selectMode) { // don't do anything if selectMode is false return; } const card = event.currentTarget. card;style.backgroundColor = ""; } function CardSelected(event){ const card = event.currentTarget. //...your code.;. }; function AddFlashCard(event) { event.preventDefault(); const form = document;querySelector("form"). const formData = new FormData(form); const titleInput = formData.get("card-title-input"); const frontInput = formData.get("card-front-input"); const backInput = formData.get("card-back-input"); const cardContainer = document;querySelector("#card-container"). let currSide = "front"; let card = document.createElement("div"). card;classList.add("card"); let title = document.createElement("h3"). title;classList.add("card-content-title"); title.textContent = titleInput; let content = document.createElement("p"). content;classList.add("card-content"); content.textContent = frontInput; card.appendChild(title); card.appendChild(content); cardContainer;appendChild(card). // add data to card const $card = $(card), $card.data("backInput", backInput);data("frontInput". frontInput); // no need to setup events here; // all are dynamic return false; } function SelectMode() { // simple toggle selectMode = !selectMode; }
*, *::after, *::before { box-sizing: border-box; } h1 { text-align: center; text-decoration: underline; } h2 { text-align: center; } h4 { text-align: center; padding-bottom: 1rem; }.label { display: inline; padding-right: 1rem; } #submit { display: flex; justify-content: center; align-items: center; height: 2rem; } #card-front-input { resize: none; } #card-back-input { resize: none; } #form-container { display: grid; grid-template-columns: 1fr 1fr; align-items: center; }.formItem { margin: 0 1rem; display: flex; align-items: center; } #box1 { display: flex; justify-content: center; margin-bottom: 1rem; margin-left: 3rem; } #box2 { margin-bottom: 1rem; display: flex; justify-content: center; } #box3 { display: flex; justify-content: end; }.line { border-top: 0.1rem dashed grey; } textarea { max-width: 100%; } #card-container { margin: 0 5vw; display: grid; grid-template-columns: 1fr 1fr 1fr; grid-row-gap: 1rem; height: auto; min-height: 20vh; }.card { border: 0.1rem solid black; width: 25vw; height: 20vh; display: block; text-align: center; overflow-wrap: break-word; padding: 0.5rem; font-size: 0.86rem; cursor: pointer; }.card-hovered { background-color: lightblue; cursor:default }.card-selected { background-color: lightblue; border: 0.25rem dashed darkblue; cursor:default } #cards-top-container { display: flex; justify-content: center; }.cards-top-item { margin: 0 1rem; }
<header> <h1>Flashcard App</h1> <h2>Card Creation</h2> </header> <section> <form onsubmit="return AddFlashCard(event);" id="form-container"> <div class="formItem" id="box1"> <label for="card-title-input" class="label">Card Title:</label> <input type="text" name="card-title-input" id="card-title-input"> </div> <div class="formItem" id="box2"> <button type="submit" id="submit">Add Card</button> </div> <div class="formItem" id="box3"> <label for="card-front-input" class="label">Card Front:</label> <textarea name="card-front-input" id="card-front-input" cols="30" rows="5" maxlength="160"></textarea> </div> <div class="formItem" id="box4"> <label for="card-back-input" class="label">Card Back:</label> <textarea name="card-back-input" id="card-back-input" cols="30" rows="5" maxlength="160"></textarea> </div> </form> </section> <br> <div class="line"></div> <br> <main> <div id="cards-top-container"> <h1 class="cards-top-item" id="cards-H1">Cards</h1> <button class="cards-top-item" id="select">Select</button> </div> <h4>Click On Card To Flip</h4> <div id="card-container"></div> </main> <script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.