【问题标题】:Adding event listeners on array of pics in specific way以特定方式在图片数组上添加事件侦听器
【发布时间】:2016-02-27 16:28:17
【问题描述】:

我有一堆图像,应该一个一个地分布在容器中,这意味着每个图像都在前一个图像加载和显示后准确显示,每个图像都应该有一个事件监听器。
这是我的解决方案https://jsfiddle.net/e2sfzn1u/4/
我使用Image.onload 将图像节点添加到标记并为该节点定义事件侦听器,当这些准备就绪时,它会转到另一个图像(递归)。

var pics = [
   'http://i.imgur.com/1oT2ZpOb.jpg',
   'http://i.imgur.com/XsViuLib.jpg',
   'http://i.imgur.com/aTDTI8Eb.jpg',
   'http://i.imgur.com/4kLvWOdb.jpg'
]
var cont = document.getElementById('container');
var each = function(arr, i) {
   if (i === undefined) {
      i = 0;
   }
   if (i < arr.length) {
      var img = new Image();
      img.onload = function() {
         cont.innerHTML += '<div class="sas" id="' + i + '" ></div>';
         var pic = document.getElementById(i);
         pic.appendChild(img);
         pic.addEventListener('click', function() {
            alert('mda')
         });
         each(arr, i + 1);
      };
      img.src = arr[i];
   }
};
each(pics);

看起来很简单,但有一个问题——事件监听器只为最后一个元素定义。

【问题讨论】:

  • 您可以尝试为元素设置onclick属性,这会将变量存储在属性onclick中。

标签: javascript jquery arrays dom-events


【解决方案1】:

一个更简单的解决方案是在循环中创建所有img 元素,然后在它们上使用一个委托的单击事件处理程序。像这样的:

for (var i = 0; i < pics.length; i++) {
    $('<img />', {
        'src': pics[i],
        'class': 'sas',
        'data-id': i,
        'load': function() {
            var id = $(this).data('id');
            console.log(id + ' img loaded');
        }
    }).appendTo('#container')
}

$('#container img').click(function() {
    alert($(this).data('id'));
});

Updated fiddle

【讨论】:

  • 你可以使用var elem = $(); for(....){ elem = elem.add($('&lt;img&gt;')) } elem.appenTo(...) ,而不是在 for 循环中干扰 dom
  • 问题是应该设置事件侦听器,正如我在介绍中已经提到的那样,在图像完全加载后(仅使用 for 循环并不能保证)
  • @AshotKazaryan 没有区别。该事件仍然存在于创建时的元素上。
  • @RoryMcCrossan 不幸的是,因为我的特定事件侦听器正在根据这些图像尺寸进行一些计算(这就是为什么它们应该预先加载)
  • 啊,我以为你指的是click 事件。我为您更新了我的答案,包括load() 事件处理程序。
【解决方案2】:

我终于找到了解决方案
问题出在这里

cont.innerHTML += '<div class="sas" id="' + i + '" ></div>';

我尝试按照@RoryMcCrossan 建议的方式制作它 - 我以正确的方式创建了 div 元素

//cont.innerHTML += '<div id="' + i + '"></div>';
var div = cont.appendChild(document.createElement('div'))
div.setAttribute('id', i);
div.setAttribute('class','sas');
var pic = document.getElementById(i);
pic.appendChild(img)
div.addEventListener('click', function () {
   alert('mda')
});

我唯一的解释是 Element.innerHTML 比通过节点添加元素要慢得多,所以我想给全人类一个巨大的建议——永远不要使用硬编码的 innerHTML 来操作 DOM。谢谢

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2010-11-26
    • 2020-06-29
    • 2018-12-10
    • 2019-03-21
    • 1970-01-01
    相关资源
    最近更新 更多