基本上,我正在尝试构建一个猫点击应用程序,我们点击猫图片来增加点击次数。我们可以使用下拉菜单更改正在显示的猫图片。问题是,当我更改图像并单击它时,前一个图像的计数也会增加。 JSBin link with code
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>
答案 0 :(得分:2)
您需要对您调用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>
答案 1 :(得分:1)
发生的事情是你每次重复使用相同的elemCat
(你只需设置innerHTML),但是在你的render()上,你总是设置一个新的事件监听器。在渲染功能的最底部,你有
elemCat.removeEventListener('click', function () {
console.log('Removing Event Listener');
}, false);
我认为你的意思是删除旧的听众,但这不是它的工作方式。 removeEventListener所做的是删除click处理程序当且仅当传入的函数与传递给addEventListener
的函数相同时。这是不可能的,因为您在addEventListener
电话中使用匿名功能。您永远不会保存对该功能的引用,因此您以后无法将其删除。
解决此问题的最佳方法是仅拨打addEventListener
一次。这样您就不必担心管理点击处理程序。如果您只有一个事件处理程序,那么它将如何知道要递增的计数?这就是数据道具的来源。您可以将猫名称保存为data-cat-name
,然后在每次点击时将其读取:
请注意,唯一的区别是将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代码看起来大致相同。
const val = document.getElementById('mySelect').value;
const catPic = document.getElementById('catPic');
catPic.src = cats[val][0];
catPic.dataset.catName = val;