JavaScript为什么单击EventListener为上图触发



基本上,我正在尝试构建一个猫点击器应用程序,在其中单击猫图片以增加单击计数。我们可以使用下拉菜单来更改所显示的猫图片。问题在于,当我更改图像并单击它时,上一个图像的计数也会增加。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 D:

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(,但是在渲染((上,您始终设置一个新的事件侦听器。在渲染功能的最底部,您拥有

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

我认为您是要删除旧听众,但这不是它的工作方式。且仅当传递的函数与传递到addEventListener中的函数相同的对象时,RemoveEventListener的操作是删除单击处理程序。这是不可能的,因为您在addEventListener调用中使用了匿名功能。您永远不会保存对该功能的引用,因此您以后再也无法删除。

修复

解决此问题的最佳方法是仅致电addEventListener一次。这样,您就不必担心管理点击处理程序。如果您只有一个事件处理程序,那么它将如何知道要增加哪个计数?这就是数据 - 播放的地方。您可以将CAT名称保存为data-cat-name,然后每次单击时阅读它:

ONCLICK代码

请注意,这里唯一的区别是将catname从元素中删除,然后基于IT添加计数

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;

最新更新