【问题标题】:Cannot add click events to list items无法将点击事件添加到列表项
【发布时间】:2021-06-21 20:20:34
【问题描述】:

这是我第一次尝试将 Javascript 与 HTML 结合使用。我正在尝试将点击事件添加到有序列表中的列表项中,但是我这样做的方式不起作用。有人可以为我解释一下吗?

我在head 中创建了一个函数,该函数应该将指定列表的列表项上的所有点击事件委托给给定函数,并且在该给定函数中,我尝试使用列表项的文本发出简单的警报.最终我想做更多,但我只是想让简单的点击事件首先工作。

<html>
    <head>
    <script type="text/javascript">
      // Attach an event handler to the 'topfriends' list to handle click events.
      function attachEventHandlerToList() {
          document.getElementById("#top4list").delegate("li", "click", function(clickEvent) {
              alert(this.innerHTML());
          });
        }
    </script>
</head>

<body>

    <div id="topfriends">
        <h3>Top 4 Most Friendable Friends</h3>
        <ol id="top4list" onload="attachEventHandlerToList()">
            <li>Brady</li>
            <li>Graham</li>
            <li>Josh</li>
            <li>Sean</li>
        </ol>
    </div>
</body>

【问题讨论】:

    标签: javascript html dom-events


    【解决方案1】:

    让我们做这样的事情

    <ul id="parent-list">
        <li id="a">Item A</li>
        <li id="b">Item B</li>
        <li id="c">Item C</li>
        <li id="d">Item D</li>
        <li id="e">Item E</li>
        <li id="f">Item F</li>
    </ul>
    

    现在为此编写 javascript

    <script type="text/javascript">
        // locate your element and add the Click Event Listener
        document.getElementById("parent-list").addEventListener("click",function(e) {
            // e.target is our targetted element.
                        // try doing console.log(e.target.nodeName), it will result LI
            if(e.target && e.target.nodeName == "LI") {
                console.log(e.target.id + " was clicked");
            }
        });
    </script>
    

    请参阅这篇关于 Javascript Event Delegates 的文章 http://davidwalsh.name/event-delegate

    另外,下面的链接是我创建的小提琴 http://jsfiddle.net/REtHT/

    希望这会有所帮助!

    【讨论】:

    • 啊,这也有效!而且我敢打赌,这比将单个点击事件分配给每个列表项更有效,这是我试图通过使用 'delegate()' 来避免的。
    • 但是等等!如何获取列表项中的文本?使用e.target.id 得到li 的ID,对吧?我最终会生成这个列表,e.target.innerHTML 不会打印出任何东西。
    • 没关系,innerHTML 完全有效。我想我要么拼错了,要么没有保存更改,哈哈。我的错!
    • 只有在绑定事件处理程序时效率更高,之后每次有人点击父OL时每次点击检查目标时效率较低。
    【解决方案2】:

    delegate() 是一个废弃的 jQuery 方法,在普通 JS 中不存在这样的方法。
    要在 JS 中附加事件处理程序,您需要使用 addEventListener,而对于旧版本的 IE,您还需要 attachEvent,这就是跨浏览器事件处理程序有点棘手的原因。
    onclick, onmouseenter 等可以在所有浏览器中使用,但使用 addEventListener / attachEvent 是一种更好的做法。

    此外,您必须在将元素添加到 DOM 后运行脚本,否则它们将不可用。通常的方法是在元素之后插入脚本,或者使用 DOM 就绪事件处理程序。

    <html>
    <head>
        <title>test</title>
    </head>
    
    <body>
    
    <div id="topfriends">
      <h3>Top 4 Most Friendable Friends</h3>
      <ol id="top4list">
        <li>Brady</li>
        <li>Graham</li>
        <li>Josh</li>
        <li>Sean</li>
      </ol>
    </div>
    
    <script type="text/javascript">
        var lis = document.getElementById("top4list").getElementsByTagName('li');
    
        for (var i=0; i<lis.length; i++) {
            lis[i].addEventListener('click', doStuff, false);
        }
    
        function doStuff() {
            alert( this.innerHTML );
        }
    </script>
    </body>
    

    FIDDLE

    【讨论】:

    • 感谢您的建议!我会试试这个。这真的是我第一次在我的 HTML 中添加行为,所以我对事件处理不太了解。另外,我正在测试的项目使用JQuery,所以我认为delegate() 方法会很好,但我想我在使用它时需要库或其他东西?我也是 JS 新手。
    【解决方案3】:

    试试这个。它也适用于子节点和父节点。

     var visitorList = document.getElementById("visitor");
            visitorList.addEventListener("click", function (e) {
                var visitorId;
                if (e.target && e.target.nodeName == "LI") {
                    visitorId = e.target.id;
                    console.log(e.target.id);
                }
                if(e.target && e.target.nodeName == "H1") {
                    visitorId = e.srcElement.parentElement.id;
                    console.log(e.srcElement.parentElement.id);
                }
                //console.log(visitorId);
            });
    <ul id="visitor">
            <li id="a" style="background: #CCCCCC; padding: 10px;"><h1 style="background: #437ba9;">Visitor A</h1></li>
            <li id="b"><h1>Visitor B</h1></li>
            <li id="c"><h1>Visitor C</h1></li>
            <li id="d"><h1>Visitor D</h1></li>
            <li id="e"><h1>Visitor E</h1></li>
            <li id="f"><h1>Visitor F</h1></li>
        </ul>

    【讨论】:

      【解决方案4】:

      你也可以使用querySelectorAll来做到这一点

        <ul class="stuffList">
          <li>Stuff 1</li>
          <li>Stuff 2</li>
          <li>Stuff 3</li>
          <li>Stuff 4</li>
          <li>Stuff 5</li>
        </ul>
          
      <script type="text/javascript">
          document.querySelectorAll('ul.stuffList li').forEach((item) => {
              item.addEventListener('click', (e) => {
                  console.log(e.target)
              })
          });
      </script>
      

      【讨论】:

        【解决方案5】:

        您好,为什么不通过 onClick 直接替换 onLoad 来更轻松

        <script type="text/javascript">
        function olClicked(){
        alert(this.innerHTML());
        }
        </script>
        <ol id="top4list" onClick="olClicked()">
        

        【讨论】:

        • 我在尝试这个时遇到类型错误。 'this' 显然是窗口,而不是列表项。我使用委托的原因是因为我需要为每个列表项指定不同的行为。
        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2017-08-14
        • 1970-01-01
        • 2018-12-16
        • 2014-12-10
        • 2015-06-15
        • 2013-02-11
        相关资源
        最近更新 更多