簡體   English   中英

javascript為什么單擊eventListener會觸發前一張圖片?

[英]Javascript why click eventListener is firing for previous image?

基本上,我試圖構建一個貓點擊器應用程序,在其中單擊貓圖片以增加點擊次數。 我們可以使用下拉菜單更改正在顯示的貓圖片。 問題是,當我更改圖像並單擊它時,前一張圖像的計數也會增加。 JSBin鏈接與代碼

 var cats = { cat1: ['Tiger ', "https://lh3.ggpht.com/nlI91wYNCrjjNy5f-S3CmVehIBM4cprx-JFWOztLk7vFlhYuFR6YnxcT446AvxYg4Ab7M1Fy0twaOCWYcUk=s0#w=640&h=426", 0], cat2: ['Puss', "https://lh3.ggpht.com/kixazxoJ2ufl3ACj2I85Xsy-Rfog97BM75ZiLaX02KgeYramAEqlEHqPC3rKqdQj4C1VFnXXryadFs1J9A=s0#w=640&h=496", 0 ], cat3: ['Smokey', "https://lh5.ggpht.com/LfjkdmOKkGLvCt-VuRlWGjAjXqTBrPjRsokTNKBtCh8IFPRetGaXIpTQGE2e7ZCUaG2azKNkz38KkbM_emA=s0#w=640&h=454", 0 ], cat4: ['Misty', "https://images.unsplash.com/photo-1482066490729-6f26115b60dc?ixlib=rb-0.3.5&ixid=eyJhcHBfaWQiOjEyMDd9&s=2e749e5a9492af91a0c4e366e0f58bb4&auto=format&fit=crop&w=700&q=60", 0 ], cat5: ['Ashes', "https://images.unsplash.com/photo-1457410129867-5999af49daf7?ixlib=rb-0.3.5&ixid=eyJhcHBfaWQiOjEyMDd9&s=db366be68b7ffcb315597fcf0c1b6a51&auto=format&fit=crop&w=700&q=60", 0 ], cat6: ['Kitty', "https://images.unsplash.com/photo-1417028441456-f283323fe2d6?ixlib=rb-0.3.5&ixid=eyJhcHBfaWQiOjEyMDd9&s=5b2d5f4ce317590a93f0ff7ccc1abd39&auto=format&fit=crop&w=700&q=60", 0 ] } //the following code make sure we have one cat info available as we load the page. render(cats); //load cats from drop down. function showCat() { var val = document.getElementById('mySelect').value; document.getElementById('catPic').src = ''; render(cats, val); } function render(cats, val = 'cat1') { document.getElementById('catName').innerHTML = cats[val][0]; document.getElementById('catPic').src = cats[val][1]; var clickCount = cats[val][2]; console.log("click1 : " + clickCount); document.getElementById('catCount').innerHTML = 'Click Count : ' + clickCount; var elemCat = document.getElementById('catPic'); elemCat.addEventListener('click', function() { clickCount++; cats[val][2] = clickCount; console.log("click2 : " + clickCount); document.getElementById('catCount').innerHTML = "Click Count : " + clickCount; }, false); elemCat.removeEventListener('click', function() { console.log('Removing Event Listener'); }, false); } 
 <html> <head> <title>Cat Clicker</title> </head> <body> <select id="mySelect" onchange="showCat()" name="Select the Cat"> <option value="cat1">Tiger</option> <option value="cat2">Puss</option> <option value="cat3">Smokey</option> <option value="cat4">Misty</option> <option value="cat5">Ashes</option> <option value="cat6">Kitty</option> </select> <h1 id="catName"></h1> <img id="catPic" src="#" alt="cat-photo"> <h3 id="catCount"></h3> </body> </html> 

您需要對調用addEventListener的函數有一個靜態引用,以便以后將其刪除。 添加了elemCat.addEventListener('click', function () {的偵聽器將永遠不可刪除,因為它是匿名的並且沒有存儲在變量中。您應該將偵聽器函數分配給外部變量,以便以后可以將其remove

 var cats = { cat1: ['Tiger ', "https://lh3.ggpht.com/nlI91wYNCrjjNy5f-S3CmVehIBM4cprx-JFWOztLk7vFlhYuFR6YnxcT446AvxYg4Ab7M1Fy0twaOCWYcUk=s0#w=640&h=426", 0], cat2: ['Puss', "https://lh3.ggpht.com/kixazxoJ2ufl3ACj2I85Xsy-Rfog97BM75ZiLaX02KgeYramAEqlEHqPC3rKqdQj4C1VFnXXryadFs1J9A=s0#w=640&h=496", 0 ], cat3: ['Smokey', "https://lh5.ggpht.com/LfjkdmOKkGLvCt-VuRlWGjAjXqTBrPjRsokTNKBtCh8IFPRetGaXIpTQGE2e7ZCUaG2azKNkz38KkbM_emA=s0#w=640&h=454", 0 ], cat4: ['Misty', "https://images.unsplash.com/photo-1482066490729-6f26115b60dc?ixlib=rb-0.3.5&ixid=eyJhcHBfaWQiOjEyMDd9&s=2e749e5a9492af91a0c4e366e0f58bb4&auto=format&fit=crop&w=700&q=60", 0 ], cat5: ['Ashes', "https://images.unsplash.com/photo-1457410129867-5999af49daf7?ixlib=rb-0.3.5&ixid=eyJhcHBfaWQiOjEyMDd9&s=db366be68b7ffcb315597fcf0c1b6a51&auto=format&fit=crop&w=700&q=60", 0 ], cat6: ['Kitty', "https://images.unsplash.com/photo-1417028441456-f283323fe2d6?ixlib=rb-0.3.5&ixid=eyJhcHBfaWQiOjEyMDd9&s=5b2d5f4ce317590a93f0ff7ccc1abd39&auto=format&fit=crop&w=700&q=60", 0 ] } //the following code make sure we have one cat info available as we load the page. render(cats); //load cats from drop down. function showCat() { var val = document.getElementById('mySelect').value; document.getElementById('catPic').src = ''; render(cats, val); } var currentListener; function render(cats, val = 'cat1') { document.getElementById('catName').innerHTML = cats[val][0]; document.getElementById('catPic').src = cats[val][1]; var clickCount = cats[val][2]; console.log("click1 : " + clickCount); document.getElementById('catCount').innerHTML = 'Click Count : ' + clickCount; var elemCat = document.getElementById('catPic'); if (currentListener) elemCat.removeEventListener('click', currentListener); currentListener = function() { clickCount++; cats[val][2] = clickCount; console.log("click2 : " + clickCount); document.getElementById('catCount').innerHTML = "Click Count : " + clickCount; } elemCat.addEventListener('click', currentListener); } 
 <html> <head> <title>Cat Clicker</title> </head> <body> <select id="mySelect" onchange="showCat()" name="Select the Cat"> <option value="cat1">Tiger</option> <option value="cat2">Puss</option> <option value="cat3">Smokey</option> <option value="cat4">Misty</option> <option value="cat5">Ashes</option> <option value="cat6">Kitty</option> </select> <h1 id="catName"></h1> <img id="catPic" src="#" alt="cat-photo"> <h3 id="catCount"></h3> </body> </html> 

問題

發生的情況是您每次都重復使用相同的elemCat (只需設置innerHTML),但是在render()上,您始終會設置一個新的事件偵聽器。 在渲染功能的最底部,

elemCat.removeEventListener('click', function () {
        console.log('Removing Event Listener');
    }, false);

我認為您的意思是刪除舊的聽眾,但這不是它的工作原理。 removeEventListener的作用是刪除單擊處理程序,當且僅當傳入的函數與傳入addEventListener的函數是同一對象時。 這是不可能的,因為您在addEventListener調用中使用了匿名函數。 您永遠不會保存對該函數的引用,因此以后無法刪除它。

解決方法

解決此問題的最佳方法是只調用一次addEventListener 這樣,您不必擔心管理點擊處理程序。 如果您只有一個事件處理程序,那么它將如何知道要遞增的計數? 這就是data-props進入的地方。您可以將cat名稱另存為data-cat-name ,然后在每次單擊時將其讀取:

onClick代碼

注意這里唯一的區別是將catName從元素中拉出,然后基於該元素增加計數

const elemCat = document.getElementById('catPic');
elemCat.addEventListener('click', function() {
  const catName = elemCat.dataset.catName;
  cats[catName][1] += 1; // increment the count
  document.getElementById('catCount').innerHTML = 'Click Count : ' + cats[catName][1];
});

onChange代碼

您的onChange代碼大致相同。

const val = document.getElementById('mySelect').value;
const catPic = document.getElementById('catPic');
catPic.src = cats[val][0];
catPic.dataset.catName = val;

暫無
暫無

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

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