代码之家  ›  专栏  ›  技术社区  ›  P.Petkov

Javascript事件侦听器未按预期反应-某些事件未激发

  •  0
  • P.Petkov  · 技术社区  · 3 年前

    我得到了下面的简单页面。

    <style>
        #notifier {
            position: fixed;
            width: 320px;
            bottom: 0;
            left: 0;
            padding: 10px;
        }
    
        #notification-silo {
            width: 300px;
            height: 100%;
            position: relative;
        }
    
            #notification-silo .notification {
                position: absolute;
                bottom: 0;
                width: 300px;
                background-color: #fff;
                box-shadow: 2px 2px 8px 2px #666;
            }
    
            #notification-silo .header {
                background-color: #1266AB;
                color: #fff;
                padding: 5px;
            }
    
            #notification-silo .error .header {
                background-color: #1266AB;
            }
    
            #notification-silo .warning .header {
                background-color: #ff8f5f;
            }
    
            #notification-silo .header .title {
                width: 260px;
                display: inline-block;
            }
    
            #notification-silo .header .close-wrapper {
                display: inline-block;
            }
    
                #notification-silo .header .close-wrapper button {
                    height: 25px;
                    width: 25px;
                    background-color: #2277bb;
                    border: 0;
                    color: #ff8f5f;
                    border-radius: 50%;
                }
    
            #notification-silo .warning .header .close-wrapper button {
                background-color: #ffaa77;
                color: #2277bb;
            }
    
        #notifier .body {
            padding: 5px;
            border: 1px solid lightgray;
        }
    </style>
    
    <div id="notifier">
        <div id="notification-silo">
        </div>
    </div>
    
    <script>
        function show(html) {
            let notification, notificationArray, body, closeButton, existingNotificationHeights, sum, bottom, notification_template, siloElement, marginBetweenNotifications;
    
            siloElement = document.querySelector("#notification-silo");
            notification_template = `<div class="notification">
                                        <div class="header">
                                            <div class="title">Message</div>
                                            <div class="close-wrapper">
                                                <button>X</button>
                                            </div>
                                        </div>
                                        <div class="body"></div>
                                    </div>`;
            marginBetweenNotifications = 10;
    
            // calculate position
            existingNotificationHeights = [...siloElement.children].map(notification => notification.offsetHeight);
            sum = existingNotificationHeights.length ? existingNotificationHeights.reduce((a, b) => a + b) : 0;
            bottom = sum + existingNotificationHeights.length * marginBetweenNotifications;
    
            // creat elements by update innerHTML
            siloElement.innerHTML += notification_template.trim();
            notificationArray = [...siloElement.querySelectorAll(".notification")];
            notification = notificationArray[notificationArray.length - 1];
            notification.style.bottom = bottom + "px";
            body = notification.querySelector(".body");
            body.innerHTML += html;
    
            // add event listener to close button
            closeButton = notification.querySelector(".close-wrapper button");
            closeButton.addEventListener("click", (ev) => {
                console.log("click is fired");
            });
        };
        
        show("System message 1");
        show("System message 2");
        show("System message 3");
        show("System message 4");
        show("System message 5");
    </script>
    

    它意味着通过show(msg)功能创建简单的通知消息。有趣的是,当创建几条消息并尝试将事件侦听器添加到关闭按钮时,只有最后一个按钮获得侦听器并实际侦听click event。所有其他关闭按钮不会对鼠标点击做出反应。你能帮我弄明白为什么吗?

    1 回复  |  直到 3 年前
        1
  •  1
  •   Shantanu Sharma    3 年前

    只需靠近按钮引用对象即可

        show("System message 1");
        show("System message 2");
        show("System message 3");
        show("System message 4");
        show("System message 5");
    
    [].forEach.call(document.querySelectorAll("#notification-silo button.close-wrapper"),function(el){
          el.addEventListener("click",function(ev){
                var targetElement = ev.target || ev.srcElement;
                console.log(targetElement); //reference of button... 
          });
        });
    

    <div class="close-wrapper">
         <button onClick="Close(this)">X</button>
    </div>
    

    或者完美作为一种标准方法,不要使用静态html模板字符串,使用基于动态纯JavaScript的元素创建方法

    例子:

    let mainDiv = document.querySelector("#notification-silo");
    let aTag = document.createElement('a');
    aTag.innerHTML = "CLOSE TEXT....";
    aTag.addEventListener("click", (ev) => {
            console.log("click is fired");
    });
    mainDiv.appendChild(aTag);
    
        2
  •  0
  •   P.Petkov    3 年前

    引用ProGu:

    我猜 siloElement.innerHTML += notification_template.trim() 抹布 关闭html内容并重新分配,因此之前的事件 远离的。