为什么函数不止一次调用onclick事件?

时间:2013-11-12 22:29:07

标签: javascript

<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>

4 个答案:

答案 0 :(得分:1)

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

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

此外,我会将按钮分开放在一个静止的位置,所以即使你的<ul>被滚动也会看到它,因为它可以获得很多行。

答案 1 :(得分:1)

添加子元素后,您会遇到以下情况:

<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>

Demo


请注意,此技术的一个好处是您可以引用函数中的<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);
    }
}

Demo

答案 2 :(得分:0)

像点击这样的事件(通过所有父母传播)(传播)

因为您正在嵌套具有相同点击处理程序的父级的子级,所以该事件首先在子级上触发myFunction,然后在父级上触发。

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

答案 3 :(得分:0)

尝试将文字包裹在<a></a>内,例如:

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

请参阅此jsfiddle:http://jsfiddle.net/gongzhitaao/k4UEE/3/

我刚试过,但我不知道为什么<li> onclick无效。