为什么函数调用多个 onClick 事件

why function called more than once onclick event?

本文关键字:onClick 事件 函数调用 为什么      更新时间:2023-09-26
<body>
<ul><li onClick="myFunction(this.id)" id="root">Root</li></ul>
<script>
function myFunction(myid) //id of clicked li 
{
    var id=prompt("Enter Folder id");
    if (id != '' && id != null)
    {
        var val=prompt("Enter Folder name");
    }
    if (id != '' && id != null && val !='' && val !=null) 
    {
        var ulnode=document.createElement("UL"); //new ul
        var node=document.createElement("LI"); //new li
            node.setAttribute("id",id);//set id of new li 
            node.setAttribute("onclick","myFunction(this.id)");//set onclick event of new li 
        var textnode=document.createTextNode(val);//li value
        node.appendChild(textnode);// new li + li value
        ulnode.appendChild(node);// new li + li value
        document.getElementById(myid).appendChild(ulnode);//old+new
    }
}
</script>
</body>
添加子

元素后,您将得到如下所示的内容:

<ul>
    <li onClick="myFunction(this.id)" id="root">
        Root
        <ul>
            <li onClick="myFunction(this.id)" id="abc">
                Abc
            </li>
        </ul>
    </li>
</ul>

由于abcroot的子代,点击abc也会点击root。 有时你想要这种行为,但不是在你的情况下。 可以通过对事件对象调用 .stopPropagation() 方法来阻止事件"传播"到父元素。 事件对象作为参数传递给事件处理程序。

使用 HTML 属性绑定事件处理程序时,属性值将成为处理程序函数体,事件参数名为 event 。 可以在事件处理程序中调用event.stopPropagation(),也可以将事件对象传递给myFunction() 。 就个人而言,我会myFunction()处理程序本身(而不仅仅是处理程序调用的函数)。 更改函数以接受事件对象的参数。 创建子<li>时,不要设置 onclick 属性,而是设置 onclick 属性并为其分配对 myFunction 的引用。

function myFunction(e)
{
    e.stopPropagation();
    var id=prompt("Enter Folder id");
    if (id != '' && id != null)
    {
        var val=prompt("Enter Folder name");
    }
    if (id != '' && id != null && val !='' && val !=null) 
    {
        var ulnode=document.createElement("UL"); //new ul
        var node=document.createElement("LI"); //new li
        node.id = id;//set id of new li 
        node.onclick = myFunction;//set onclick event of new li 
        var textnode=document.createTextNode(val);//li value
        node.appendChild(textnode);// new li + li value
        ulnode.appendChild(node);// new li + li value
        this.appendChild(ulnode);
    }
}

这适用于动态创建的列表元素。 要将函数绑定到 HTML 中的根元素,请使用 myFunction.call(this, event)

<ul><li onClick="myFunction.call(this, event)" id="root">Root</li></ul>

演示


请注意,此技术的一个好处是您可以在函数中引用<li>元素,因此您无需按 id 查找该元素。 如果这是您向每个列表项添加 id 的唯一原因,则可以完全省略它。 生成的函数要短得多:

function myFunction(e)
{
    e.stopPropagation();
    var val=prompt("Enter Folder name");
    if (val) 
    {
        var ulnode=document.createElement("UL"); //new ul
        var node=document.createElement("LI"); //new li
        node.onclick = myFunction;//set onclick event of new li 
        node.textContent = val;
        ulnode.appendChild(node);// new li + li value
        this.appendChild(ulnode);
    }
}

演示

您正在动态添加可能获得相同 id 的<li>元素。如果是这种情况,则不允许这样做。尝试改用类,使用 JQuery 会对您有所帮助。将代码(至少在你这边;))缩短到最低限度。

以此为起点:http://plnkr.co/1apBvS

此外,我会将按钮分开放在静态位置,因此即使您的<ul>滚动,您也将始终看到它,因为它可以获得许多行。

像点击这样的事件在所有父级中冒泡 DOM(传播)

由于您要嵌套具有相同单击处理程序的父项的子项,因此该事件首先在子项上触发myFunction,然后在父级上触发。

您可以从myFunction返回false以防止冒泡

尝试将文本包装在<a></a>内,例如:

<ul>
  <li><a onclick="return test()">child</a></li>
</ul>

看到这个jsfiddle:http://jsfiddle.net/gongzhitaao/k4UEE/3/

我刚刚尝试过,但我不知道为什么<li> onclick不起作用。