关于动态创建的HTML事件的JavaScript问题

关于动态创建的HTML事件的JavaScript问题,javascript,events,dynamic,onclick,dom-events,Javascript,Events,Dynamic,Onclick,Dom Events,我在使用JavaScript定位动态创建的元素时遇到了一些问题 问题1 缩短的JavaScript代码: var lightbox = document.createElement('div'), nav = document.createElement("nav"), imga = document.querySelectorAll(".gallery a"); for (i = 0; i < imga.length; i++) { imga[i].addEven

我在使用JavaScript定位动态创建的元素时遇到了一些问题

问题1 缩短的JavaScript代码:

var lightbox = document.createElement('div'),
    nav = document.createElement("nav"),
    imga = document.querySelectorAll(".gallery a");
for (i = 0; i < imga.length; i++) {
    imga[i].addEventListener("click", function() {
        document.body.insertBefore(lightbox, document.body.firstChild);
        lightbox.appendChild(nav);
    });
}
var img,
    imga = document.querySelectorAll(".gallery a");
for (i = 0; i < imga.length; i++) {
    imga[i].addEventListener("click", function() {
            for (i = 0; i < imga.length; i++) {
                img = document.createElement("img");
                lightbox.appendChild(img);
            }
    });
}
我试过很多东西,比如:

var selector = document.querySelectorAll("nav a");
for (i = 0; i < selector.length; i++) {
    selector[i].addEventListener("click", function() {
        // doesn't work because the <nav> is inserted dynamically
    });
}
有人能帮我吗?我对JavaScript不是很有经验。

第2期 简单的解决方案是将事件处理程序添加到循环中的所有元素中

var img,
    imga = document.querySelectorAll(".gallery a");

for (i = 0; i < imga.length; i++) {
    imga[i].addEventListener("click", function() {
        for (i = 0; i < imga.length; i++) {
            img = document.createElement("img");
            img.setAttribute("src", imga[i].getAttribute("href"));
            lightbox.appendChild(img);

            img.addEventListener('click', fn, false);
        }
    });
}

就我而言,解决方案并不难。@adeneo让我开始考虑嵌套事件处理程序,结果很好——我可以不用修改就使用所有选择器:

var lightbox = document.createElement('div'),
    nav = document.createElement("nav"),
    imga = document.querySelectorAll(".gallery a"),
    gallery = document.getElementsByClassName("gallery"),
    img;
for (i = 0; i < imga.length; i++) {
    imga[i].addEventListener("click", function() {
        lightbox.appendChild(nav);
        document.body.insertBefore(lightbox, document.body.firstChild);
        for (i = 0; i < imga.length; i++) {
            img = document.createElement("img");
            lightbox.appendChild(img);
        }
        lightbox.addEventListener("click", function() {
            // works fine
        });
        var nava = document.querySelectorAll("#lightbox nav a");
        for (i = 0; i < nava.length; i++) {
            nava[i].addEventListener("click", function() {
                // works fine
            });
        }
        var limg = document.querySelectorAll("#lightbox img");
        for (i = 0; i < limg.length; i++) {
            limg[i].addEventListener("click", function() {
                // works fine
            });
        }
    });
}
var lightbox=document.createElement('div'),
nav=document.createElement(“nav”),
imga=document.queryselectoral(“.gallery a”),
gallery=document.getElementsByClassName(“gallery”),
img;
对于(i=0;i
谢谢您的回复。您的“委托事件处理程序”看起来不太优雅,没有更好的解决方案吗?而且,如果我把
e.stopPropagation()
this
之类的东西放在这些if语句中,它们的目标是什么?
这个
语句和其他语句都依赖于函数选择器,对吗?如果您想要更优雅,应该仔细看看jQuery是如何实现的。jQuery将
事件.target
绑定为事件处理程序中的
this
,因此
this
实际上成为动态元素等。因此,可以创建比只检查
节点类型
更方便的函数。然而,原则上这正是jQuery和其他库所做的,它们依赖冒泡将事件处理程序附加到父元素,然后检查event.target中DOM树上的任何元素是否匹配某个字符串选择器等。不幸的是,我无法编写整个选择器引擎和事件处理库作为答案,我只能向您展示委托事件处理程序在原则上是如何工作的,您必须花费所有的时间来制作符合您需要的东西。我相信它确实可以。我只想要尽可能少的代码。然而,在您的第一个解决方案中,我受到启发,将所有事件处理程序都嵌套在第一个事件处理程序中,这在我的案例中非常有效(请参阅我发布的答案)。谢谢你的帮助!这是个好问题+1下一步@EddieB我还没有读到承诺的内容,在我的情况下它们能实现吗?
img.addEventListener("click", function() {
    // doesn't work because img = document.createElement("img")
    // has to be inside another function
});
var img,
    imga = document.querySelectorAll(".gallery a");

for (i = 0; i < imga.length; i++) {
    imga[i].addEventListener("click", function() {
        for (i = 0; i < imga.length; i++) {
            img = document.createElement("img");
            img.setAttribute("src", imga[i].getAttribute("href"));
            lightbox.appendChild(img);

            img.addEventListener('click', fn, false);
        }
    });
}
var img,
    imga = document.querySelectorAll(".gallery a");

lightbox.addEventListener('click', function(e) {
    if ( e.target.nodeType.toLowerCase() === 'img' ) {
         // do stuff
    }
}, false);

for (i = 0; i < imga.length; i++) {
    imga[i].addEventListener("click", function() {
        for (i = 0; i < imga.length; i++) {
            img = document.createElement("img");
            img.setAttribute("src", imga[i].getAttribute("href"));
            lightbox.appendChild(img);
        }
    });
}
nav.addEventListener("click", function(e) {
    if ( e.target.nodeType.toLowerCase() === 'a' ) {

         // an achor was clicked, do stuff

    }
});
var lightbox = document.createElement('div'),
    nav = document.createElement("nav"),
    imga = document.querySelectorAll(".gallery a"),
    gallery = document.getElementsByClassName("gallery"),
    img;
for (i = 0; i < imga.length; i++) {
    imga[i].addEventListener("click", function() {
        lightbox.appendChild(nav);
        document.body.insertBefore(lightbox, document.body.firstChild);
        for (i = 0; i < imga.length; i++) {
            img = document.createElement("img");
            lightbox.appendChild(img);
        }
        lightbox.addEventListener("click", function() {
            // works fine
        });
        var nava = document.querySelectorAll("#lightbox nav a");
        for (i = 0; i < nava.length; i++) {
            nava[i].addEventListener("click", function() {
                // works fine
            });
        }
        var limg = document.querySelectorAll("#lightbox img");
        for (i = 0; i < limg.length; i++) {
            limg[i].addEventListener("click", function() {
                // works fine
            });
        }
    });
}