简体   繁体   English

即使其他代码运行,事件侦听器也不会在循环的最后一次迭代中被删除

[英]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:主要部分发生了变化:

  • Setup dynamic events (easy using jQuery but can be done in vanilla)设置动态事件(使用 jQuery 很容易,但可以在原版中完成)
  • Change functions to accept the event as the first argument更改函数以接受事件作为第一个参数
  • Record/access element data using jQuery's .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.

相关问题 事件侦听器未被删除 - Event listener not being removed :焦点伪选择器样式在打开新选项卡时未被删除,即使触发模糊事件也是如此 - :focus pseudo selector style not being removed when a new tab is opened , even though blur event is fired 未删除事件侦听器 - 点亮元素 - event listener not being removed - lit element 没有删除节流的React事件侦听器 - React event listener with throttle not being removed 为什么功能即使在循环内被异步调用也依序运行? - Why functionalities runs sequentially even though they are being called asynchronously inside a loop? 即使删除了元素,事件监听器也会多次触发? - Multiple firings of event listener even after element has been removed? 滚动事件运行,即使我没有滚动 - Scroll event runs even though i have not scrolled 使用for循环进行数据驱动测试的Mocha始终在最后一次迭代中运行 - Mocha using for loop for data driven test always runs last iteration 即使我使用的是 :not 选择器,也会触发事件侦听器 - Event listener is triggered even though I'm using :not selector 即使鼠标悬停在Google Maps侦听器事件上,其行为也类似于单击 - Google maps listener event acts like a click even though it is a mouseover
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM