javascript - 嵌套变量不正确地递增

标签 javascript jquery

我有以下代码:

'use strict';

// Data
class cat {
  constructor(name, picture, clicks) {
    this.name = name;
    this.picture = picture;
    this.clicks = clicks;
  }
};

var cat1 = new cat('Mercury', 'cat1.jpg', 0);
var cat2 = new cat('Venus', 'cat2.jpg', 0);
var cat3 = new cat('Mars', 'cat3.jpg', 0);
var cat4 = new cat('Jupiter', 'cat4.jpg', 0);
var cat5 = new cat('Saturn', 'cat5.jpg', 0);
var cat6 = new cat('Neptune', 'cat6.jpg', 0);

var cats = [cat1, cat2, cat3, cat4, cat5, cat6];


// Program
for (var i = 0; i < cats.length; i++) {
  // Current cat
  var icat = cats[i];

  $('#cat_list').append('<li id="cat' + (i + 1) + '">' + icat.name + '</li>');
  $('#cat' + (i + 1)).on('click', (function(iSaved, icatSaved) {
    return function() {
      console.log('You clicked on cat' + (iSaved + 1) + ' from the list!');
      $('#cat_title').text(icatSaved.name);
      $('#cat_image').attr('src', 'img/' + icatSaved.picture);
      $('#catClicks').text(icatSaved.clicks);
      $('#cat_image').on('click', function() {
        icatSaved.clicks++;
        $('#catClicks').text(icatSaved.clicks);
      });
    };
  })(i, icat));
};

除了嵌入式点击处理程序会增加所讨论的猫对象的点击次数外,它工作得很好。看起来点击递增最终会影响不止一个猫对象,并且还会导致其中一些在单击图片时增加 2、3 或 4。我一定是在做一些愚蠢的事情来获得这种行为,但我不确定是什么。这是因为我在列表点击处理程序中嵌入了点击处理程序吗?

–吉姆

最佳答案

您正在另一个事件监听器中设置一个事件监听器。每次点击 #cat{N} 时,您都会为 #cat_image 添加另一个事件监听器。因此,一遍又一遍地点击它,为同一个元素设置越来越多的事件监听器。当您单击 #cat_image 时,所有这些事件监听器都会被调用,并且由于它们都在递增 clicks 属性,后者只需一次单击就会递增很多次。

解决这个问题的最佳方法是使用事件委托(delegate):

for (var i = 0; i < cats.length; i++) {
    var icat = cats[i];

    // add a class of .cat and a data-index attribute to all cats
    $('#cat_list').append('<li class="cat" data-index="' + i + '">' + icat.name + '</li>');
    //                         ^^^^^^^^^^^ ^^^^^^^^^^^^^^^^^^^^^^
};


var catSaved = null;                              // move this outside the event listener to be visible for both event listeners
$('#cat_list').on('click', '.cat', function(e) {  // whenever a .cat element get clicked from within #cat_list element
    var index = $(this).data('index');            // get the index of that cat from cats array (previously stored in data-index)
    catSaved = cats[index];                       // get the cat itself

    $('#cat_title').text(catSaved.name);
    $('#cat_image').attr('src', 'img/' + catSaved.picture);
    $('#catClicks').text(catSaved.clicks);
});

$('#cat_image').on('click', function() {          // move this event listener outside, to set it only once
    if(catSaved) {                                // if we have a catSaved element
        catSaved.clicks++;                        // ...
        $('#catClicks').text(catSaved.clicks);
    }
});

关于javascript - 嵌套变量不正确地递增,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/46256743/

相关文章:

javascript - "this.el"在 $ ('ul' , this.el 中的含义)

javascript - 调用返回 JSON 的 PHP 会返回错误,但我可以看到响应

javascript - 数组.map : get the index of each element to use in the return function

javascript - 如何将 'import' Vuejs组件写入index.html?

jquery - 仅当悬停在 li 中的 span 上时才显示下拉菜单

javascript - 在表行 JQuery 中添加和删除类

javascript - 如何在 HTML CSS Javascript 中完全显示 onclick 事件的隐藏选项卡

javascript - (React Native) 当用户第一次打开这个 App 时,Modal 只会向每个用户显示一次

javascript - ExtJS 3.2.0,隐藏tabpanel的标题

javascript - jQuery UI Autocomplete 键入时取消最后一个查询