简体   繁体   English

无法将 javascript eventListener 添加到最近创建的元素

[英]Cannot add javascript eventListener to recently created element

I use Javascript to created 625 <div class="box"><div> then I want to add event listener for each box.我使用 Javascript 创建了 625 个<div class="box"><div>然后我想为每个框添加事件侦听器。 The boxes is successfully created but the listener is not working.盒子已成功创建,但侦听器不工作。 Here my full code, I really appreciate for all of your response.这是我的完整代码,我非常感谢您的所有回复。 Thanks谢谢

<!DOCTYPE html>
<html>
<head>
    <title>Number AI | Machine Learning Technologhy</title>
    <style>
        .box-container{
            display: grid;
            width: 300px;
            height: 300px;
            border: 1px solid blue;
            grid-template-columns: auto auto auto auto auto auto auto auto auto auto auto auto auto auto auto auto auto auto auto auto auto auto auto auto auto;
        }
        .box{
            width:10px;
            height:10px;
            border: 1px solid black;
            text-align: center;
        }
    </style>
    <script type="text/javascript">
        function initiateBox(){
            for (let i = 0; i < 625; i++) {
                let box = document.createElement("DIV");
                box.classList.add("box");
                document.querySelector('.box-container').appendChild(box);
            }
        };
        window.onload = initiateBox;
    </script>
</head>
    <body>
        <h2>Number AI</h2>
        <div class="box-container"></div>
        
        <script>
            document.querySelectorAll(".box").forEach(box =>{
                box.addEventListener("mouseover",function(){
                    box.style.backgroundColor = 'black';
                });
            });
        </script>
    </body>
</html>

Several things几件事

  1. use addEventListeners on load and on mouseover在加载和鼠标悬停时使用 addEventListeners
  2. delegate so you can cerate the boxes at any time after the container exists委托,以便您可以在容器存在后随时创建这些框
  3. Perhaps a CSS hover is the actual way to do this ?也许 CSS 悬停是实现此目的的实际方法?

Anyway, here is the delegation script无论如何,这是委托脚本

 function initiateBox() { const container = document.querySelector('.box-container'); for (let i = 0; i < 625; i++) { let box = document.createElement("div"); box.classList.add("box"); container.appendChild(box); } container.addEventListener("mouseover", function(e) { const tgt = e.target; if (tgt.classList.contains("box")) tgt.style.backgroundColor = 'black'; }); }; window.addEventListener("load",initiateBox)
 .box-container { display: grid; width: 300px; height: 300px; border: 1px solid blue; grid-template-columns: auto auto auto auto auto auto auto auto auto auto auto auto auto auto auto auto auto auto auto auto auto auto auto auto auto; } .box { width: 10px; height: 10px; border: 1px solid black; text-align: center; }
 <title>Number AI | Machine Learning Technologhy</title> <h2>Number AI</h2> <div class="box-container"> </div>

Well, you have several options here.好吧,你在这里有几个选择。 But the simplest one (Not the efficient one) is to add the event listener on box creation like this:但最简单的(不是高效的)是在创建框时添加事件侦听器,如下所示:

 <!DOCTYPE html> <html> <head> <title>Number AI | Machine Learning Technologhy</title> <style> .box-container { display: grid; width: 300px; height: 300px; border: 1px solid blue; grid-template-columns: auto auto auto auto auto auto auto auto auto auto auto auto auto auto auto auto auto auto auto auto auto auto auto auto auto; } .box { width: 10px; height: 10px; border: 1px solid black; text-align: center; } </style> <script type="text/javascript"> function initiateBox() { for (let i = 0; i < 625; i++) { let box = document.createElement("DIV"); box.classList.add("box"); box.addEventListener("mouseover", function() { box.style.backgroundColor = 'black'; }); document.querySelector('.box-container').appendChild(box); } }; window.onload = initiateBox; </script> </head> <body> <h2>Number AI</h2> <div class="box-container"></div> </body> </html>

But in any case, if you looking for an efficient way to do this as @mplungjan pointed out in comments it's better to use delegation approach like this:但无论如何,如果您正在寻找一种有效的方法来做到这一点,正如@mplungjan 在评论中指出的那样,最好使用这样的委托方法:

 <!DOCTYPE html> <html> <head> <title>Number AI | Machine Learning Technologhy</title> <style> .box-container { display: grid; width: 300px; height: 300px; border: 1px solid blue; grid-template-columns: auto auto auto auto auto auto auto auto auto auto auto auto auto auto auto auto auto auto auto auto auto auto auto auto auto; } .box { width: 10px; height: 10px; border: 1px solid black; text-align: center; } </style> <script type="text/javascript"> function initiateBox() { const boxContainer = document.querySelector('.box-container'); for (let i = 0; i < 625; i++) { let box = document.createElement("DIV"); box.classList.add("box"); boxContainer.appendChild(box); } boxContainer.addEventListener("mouseover", function(event) { const target = event.target; if (target.classList.contains('box')) target.style.backgroundColor = 'black'; }); }; window.onload = initiateBox; </script> </head> <body> <h2>Number AI</h2> <div class="box-container"></div> </body> </html>

I think the second script is run before the box elements are appended to the document, thus not finding any boxes.我认为第二个脚本是在将框元素附加到文档之前运行的,因此找不到任何框。 You could add the eventListener to the initiateBox function you created, like so:您可以将 eventListener 添加到您创建的启动框函数中,如下所示:

function initiateBox(){
        for (let i = 0; i < 625; i++) {
            let box = document.createElement("DIV");
            box.classList.add("box");
            box.addEventListener("mouseover",function(){
                box.style.backgroundColor = 'black';
            });
            document.querySelector('.box-container').appendChild(box);
        }
    };
    window.onload = initiateBox;

If the background color is actually the property you are going to change on the mouseOver, I would suggest doing that with a CSS hover though.如果背景颜色实际上是您要在 mouseOver 上更改的属性,我建议使用 CSS 悬停来实现。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM