如何动态地将事件侦听器添加到 NodeElement

How to dynamically add an event listener to a NodeElement

我在这里需要实现的是向其中包含图像缩略图的一系列 span 元素添加点击事件侦听器,以便使它们 select 可用。这些是当用户使用相对形式输入文件时动态创建的。

到目前为止我管理的是引用包含它们的输出元素的新创建的子节点。

Html:

<div id="imageBox"><output id="list"><!-- Newly created span elements here --></output></div>

具有全局作用域的相关脚本:

var father = document.getElementById('list');
var children = father.childNodes;

然后我在 body 元素侦听器中全局处理点击:

document.body.addEventListener('click', function( event ) {

if (children) {

for (var i = 0; i < children.length; i++) {

  children[i].addEventListener("click", function(){
    if(this.style.boxShadow === '') this.style.boxShadow ='0 0 1em blue';
    else this.style.boxShadow = '';}, false);
    }
  }

}, false);

但如我所料,只需双击新元素即可。

我试图在读取和加载 selected 文件输入的函数中添加一个回调函数,该函数包装了上面的 for 循环,但它不起作用。

function handleFileSelect(evt) {
var files = evt.target.files; // FileList object

// Loop through the FileList and render image files as thumbnails.
for (var i = 0, f; f = files[i]; i++) {

  // Only process image files.
  if (!f.type.match('image.*')) {
    continue;
  }

  var reader = new FileReader();

  // Closure to capture the file information.
  reader.onload = (function(theFile) {
    return function(e) {
      // Render thumbnail.
      var span = document.createElement('span');
      span.innerHTML = ['<img class="thumb" src="', e.target.result,'" title="', escape(theFile.name), '"/>'].join('');
      document.getElementById('list').insertBefore(span, null);

      console.log(children.length);

      clickable();
    };
  })(f);

  // Read in the image file as a data URL.
  reader.readAsDataURL(f);
}


}

function clickable(){
if (children) {

for (var i = 0; i < children.length; i++) {

  children[i].addEventListener("click", function(){
    if(this.style.boxShadow === '') this.style.boxShadow ='0 0 1em blue';
    else this.style.boxShadow = '';}, false);
    }
  }
}

知道如何处理这个问题,让它一键运行吗?

Fiddle:

https://jsfiddle.net/b130p9tb/2/

进度更新:

现在它可以正常工作,可以正确响应单击,但是当尝试 select 多个项目时,它只能根据项目的数量对成对或不均匀的项目起作用。例如。 : 一个项目,它工作正常,但只有第二个是 selectable。用三个代替只有第一个和第三个,依此类推。

已更新 fiddle:https://jsfiddle.net/b130p9tb/3/

问题是您每次添加图片时都会为所有元素添加侦听器。因此,当您添加第一张图片时,您就有了一个事件侦听器。然后当你添加第二张图片时,你的第一个元素有 2 个事件监听器。所以它选择,然后立即取消选择。等等

更简单的方法是在 list 元素 上添加 listener 并使用 event 目标修改样式。如果侦听器位于列表元素上,则事件将是实际单击的图像。因此,只有一个侦听器,您就会得到预期的行为。此外,您可以使用 class 简化样式切换。像这样:

document.getElementById('list').addEventListener("click", function (e) {
    e.target.classList.toggle('selected');
}, false);

https://jsfiddle.net/ugvqy1r5/1/