简体   繁体   English

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

[英]why function called more than once onclick event?

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

You are dynamically adding <li> elements which might get the same id. 您正在动态添加可能获得相同ID的<li>元素。 If this is the case, this is not allowed. 如果是这种情况,则不允许这样做。 Try to use classes instead and the use of JQuery will be helpful for you. 尝试使用类而不是使用JQuery将对您有所帮助。 Will shorten the code (at least on your side ;) ) to a minimum. 将代码(至少在你身边;))缩短到最低限度。

Use this as a starting point: http://plnkr.co/1apBvS 以此为出发点: http//plnkr.co/1apBvS

Also i would separate the button to be in a static place, so you will always see it, even if your <ul> is scrolled because it can get many rows. 此外,我会将按钮分开放在一个静止的位置,所以你总是会看到它,即使你的<ul>被滚动,因为它可以获得很多行。

Once you've added a child element, you have something like this: 一旦你添加了一个子元素,你就会有这样的事情:

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

Since abc is a child of root , clicking abc also clicks root . 由于abcroot的子root ,因此单击abc 也会单击root Sometimes you want this behavior, but not in your case. 有时你想要这种行为,但不是你的情况。 You can stop events from "propagating" to parent elements by calling the .stopPropagation() method on the event object. 您可以通过调用事件对象上的.stopPropagation()方法来阻止事件“传播”到父元素。 The event object is passed to event handlers as an argument. 事件对象作为参数传递给事件处理程序。

When you bind event handlers using HTML attributes, the attribute value becomes the handler function body, and the event argument is named event . 使用HTML属性绑定事件处理程序时,属性值将成为处理函数体,而事件参数将命名为event You can either call event.stopPropagation() in the event handler, or pass the event object to myFunction() . 您可以在事件处理程序中调用event.stopPropagation() ,也可以将事件对象传递给myFunction() Personally, I'd make myFunction() the handler itself (instead of just a function called by the handler). 就个人而言,我将myFunction()作为处理程序本身(而不仅仅是处理程序调用的函数)。 Change the function to accept an event object for it's argument. 更改函数以接受其参数的事件对象。 When you create the child <li> , rather than setting the onclick attribute, set the onclick property and assign it a reference to 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);
    }
}

That works for dynamically created list elements. 这适用于动态创建的列表元素。 To bind that function to your root element in the HTML, use myFunction.call(this, event) : 要将该函数绑定到HTML中的根元素,请使用myFunction.call(this, event)

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

Demo 演示


Note that a benefit of this technique is you have a reference to the <li> element in your function, so you don't need to look up the element by id. 请注意,此技术的一个好处是您可以引用函数中的<li>元素,因此您无需按ID查找元素。 If that is the only reason you were adding an id to each list item, you can omit that completely. 如果这是您为每个列表项添加ID的唯一原因,则可以完全省略。 The resulting function is quite a bit shorter: 结果函数相当短:

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

Events like click bubble up the DOM (propagate) through all parents 像点击这样的事件会通过所有父母冒充DOM(传播)

Because you are nesting a child that has parent with same click handler, the event first fires myFunction on the child, then fires on the parent . 因为您正在嵌套具有相同单击处理程序的父级的子级,所以该事件首先在子级上触发myFunction ,然后在父级上触发。

You can return false from myFunction to prevent the bubbling 您可以从myFunction返回false以防止冒泡

Try wrapping your text inside a <a></a> , like: 尝试将文字包装在<a></a> ,例如:

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

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

I just tried, but I've no idea why <li> with onclick does not work. 我刚试过,但我不知道为什么<li> with onclick不起作用。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM