无法向列表项添加点击事件

11
这是我第一次尝试在HTML中使用Javascript。我正在尝试为有序列表中的列表项添加点击事件,但我做的某些事情似乎不起作用。有人能帮我解决一下吗?
我在标签中创建一个函数,该函数应将指定列表中所有点击事件委托给给定函数,在该给定函数中,我尝试使用列表项的文本引发简单的警报。最终我想做更多,但我只是想先让简单的点击事件起作用。
<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>
5个回答

22

我们来做些类似这样的事情

<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事件代理的文章:http://davidwalsh.name/event-delegate。同时,以下链接是我创建的示例代码:http://jsfiddle.net/REtHT/。希望这些能够帮到你!

这个也可以工作!而且我敢打赌,它比为每个列表项分配单独的点击事件更有效率,这也是我试图通过使用 'delegate()' 避免的。 - Daniel Brady
1
但是等等!我如何获取列表项中的文本?使用 e.target.id 获取 li 的id,对吗?最终我将生成此列表,而 e.target.innerHTML 不会打印任何内容。 - Daniel Brady
没事了,innerHTML 完全可以用。我想我可能拼错了或者没有保存更改,哈哈,我的错! - Daniel Brady
只有在绑定事件处理程序后,它才更有效率。之后,在每次单击父级OL时检查目标会变得不那么有效率。 - adeneo

9

delegate()是一个已经被弃用的jQuery方法,在纯JS中不存在这样的方法。
在JS中,您可以使用addEventListener来附加事件处理程序,在旧版本的IE中,您还需要使用attachEvent,因此跨浏览器事件处理程序有点棘手。
onclickonmouseenter等在所有浏览器中都有效,但使用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也很新。 - Daniel Brady

0

你也可以使用 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>

0

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

 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>


-1

你好,为什么不直接用onClick替换onLoad来更简单地实现呢?

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

当我尝试这样做时,我会收到类型错误。 “this” 显然是窗口,而不是列表项。 我使用委托的原因是因为我需要为每个列表项指定不同的行为。 - Daniel Brady

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接