【问题标题】:Dynamically adding div's and setting onclick value in JavaScript for loop在 JavaScript for 循环中动态添加 div 并设置 onclick 值
【发布时间】:2020-07-24 07:14:15
【问题描述】:

我正在使用原生 JavaScript 创建照片轮播;从外部 JSON 文件中读取值,然后遍历 JSON 数据以动态添加缩略图、标题和 onclick 到轮播 div。所有图像和标题都可以正常工作,但无论单击哪个缩略图,onclick 都只会传递最后使用的值。

这是 JSON 文件

var Scenes = {
    "Title":["St. Mary Magdalene","Black Mountains","Pen Twyn Glas","Carreg Yr Ogof Cave","Beinn Narnain"],
    "Thumbnail":["TNStMary.jpg","TNMountains.jpg","TNPenTwynGlas.jpg","TNCarregYrOgof.jpg","TNBeinnNarnain.jpg"],
    "PanoSet":["001x","145+","183+","400x","500x"]
};

这是动态添加缩略图、标题和点击的代码。

var Scenes = {
    "Title":["St. Mary Magdalene","Black Mountains","Pen Twyn Glas","Carreg Yr Ogof Cave","Beinn Narnain"],
    "Thumbnail":["TNStMary.jpg","TNMountains.jpg","TNPenTwynGlas.jpg","TNCarregYrOgof.jpg","TNBeinnNarnain.jpg"],
    "PanoSet":["001x","145+","183+","400x","500x"]
};

var Repeat = (Scenes.Title.length);

for (i = 0; i < Repeat; i++) {
  NewDiv = document.createElement('div');
  NewDiv.id = 'Scene' + i;
  document.getElementById('Carousel').appendChild(NewDiv);
  document.getElementById('Scene' + i).className = "Scene";
  document.getElementById('Scene' + i).style.position = "absolute";
  document.getElementById('Scene' + i).style.top = "5px";
  document.getElementById('Scene' + i).style.left = 5 + (170 * i) + "px";
  document.getElementById('Scene' + i).onclick = function() {
    addScene(Scenes.PanoSet[i]);
  };

  NewDiv = document.createElement('div');
  NewDiv.id = 'SceneThumbnail' + i;
  document.getElementById('Scene' + i).appendChild(NewDiv);
  document.getElementById("SceneThumbnail" + i).className = "SceneThumbnail";
  document.getElementById("SceneThumbnail" + i).style.backgroundImage = "url(" + Scenes.Thumbnail[i] + ")";

  NewDiv = document.createElement('div');
  NewDiv.id = 'SceneTitle' + i;
  document.getElementById('Scene' + i).appendChild(NewDiv);
  document.getElementById("SceneTitle" + i).className = "SceneTitle";
  document.getElementById('SceneTitle' + i).innerHTML = Scenes.Title[i];
}
&lt;div id='Carousel'&gt;&lt;div&gt;

这似乎是问题所在(我包括以上所有内容以提供上下文)

document.getElementById('Scene'+i).onclick = function() {addScene(Scenes.PanoSet[i]);};

我点击了哪个新创建的 div,代码“500x”被传递给我的 addScene 函数。

我希望我看起来有些简单。有人可以提供解决方案吗?

【问题讨论】:

  • 你不需要一遍又一遍地调用document.getElementById('Scene'+i),你有NewDiv的元素就用那个
  • i 被你的循环静音,所以每次点击都指向i。如上所述,这是一个骗局
  • 除了修复i之外,您还可以查看事件委托(父元素上的onclick事件侦听器,从事件目标中获取您需要的内容)。

标签: javascript


【解决方案1】:

经典的 JS 陷阱。这样做:

document.getElementById('Scene'+i).onclick = ((id) => () =>addScene(Scenes.PanoSet[id]))(i);

你需要在i中绑定,而不是引用。处理程序代码在执行之前不会被评估,因此此时 i 的值将是循环完成时的值。

使用 IIFE(立即调用的函数表达式)创建一个上下文,其中 i 的正确静态值绑定到它返回的处理程序的范围内。

【讨论】:

    【解决方案2】:

    您可以找到如下索引。在onclick 中使用this 你会得到clicked div。然后将id 替换为this.getAttribute('id') 并将Scene 替换为''

    let x = this.getAttribute('id').replace('Scene', '');
    

    在下面试试。

    let Scenes = {
      "Title":["St. Mary Magdalene","Black Mountains","Pen Twyn Glas","Carreg Yr Ogof Cave","Beinn Narnain"],
      "Thumbnail":["TNStMary.jpg","TNMountains.jpg","TNPenTwynGlas.jpg","TNCarregYrOgof.jpg","TNBeinnNarnain.jpg"],
      "PanoSet":["001x","145+","183+","400x","500x"]
    };
    
    
    var Repeat = (Scenes.Title.length);
    
    for (i = 0; i < Repeat; i++) {
      NewDiv = document.createElement('div');
      NewDiv.id = 'Scene' + i;
      document.getElementById('Carousel').appendChild(NewDiv);
      document.getElementById('Scene' + i).className = "Scene";
      document.getElementById('Scene' + i).style.position = "absolute";
      document.getElementById('Scene' + i).style.top = "5px";
      document.getElementById('Scene' + i).style.left = 5 + (170 * i) + "px";
      document.getElementById('Scene' + i).onclick = function() {
        let x = this.getAttribute('id').replace('Scene', '');
        console.log(x);
        addScene(Scenes.PanoSet[x]);
      };
    
      NewDiv = document.createElement('div');
      NewDiv.id = 'SceneThumbnail' + i;
      document.getElementById('Scene' + i).appendChild(NewDiv);
      document.getElementById("SceneThumbnail" + i).className = "SceneThumbnail";
      document.getElementById("SceneThumbnail" + i).style.backgroundImage = "url(" + Scenes.Thumbnail[i] + ")";
    
      NewDiv = document.createElement('div');
      NewDiv.id = 'SceneTitle' + i;
      document.getElementById('Scene' + i).appendChild(NewDiv);
      document.getElementById("SceneTitle" + i).className = "SceneTitle";
      document.getElementById('SceneTitle' + i).innerHTML = Scenes.Title[i];
    
    
    }
    &lt;div id='Carousel'&gt;&lt;/div&gt;

    【讨论】:

      猜你喜欢
      • 2020-08-31
      • 1970-01-01
      • 2020-05-24
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2019-01-11
      • 2015-12-23
      • 2020-05-09
      相关资源
      最近更新 更多