search

Home  >  Q&A  >  body text

javascript - Questions about timers and preventing continuous clicks



<svg id="s1" width="800" height="500"></svg>
<script>
    var frag=document.createDocumentFragment();
    for(var i=0;i<30;i++){
        var c=document.createElementNS("http://www.w3.org/2000/svg","circle");
        c.setAttribute("r",rn(5,160));
        c.setAttribute("cx",rn(0,800));
        c.setAttribute("cy",rn(0,500));
        c.setAttribute("fill",rc(0,256));
        c.setAttribute("fill-opacity",Math.random());
        frag.appendChild(c);
    }
    s1.appendChild(frag);
    s1.onclick=function(e){
        clearInterval(t);
        var target= e.target;
        if(target.nodeName=="circle"){
            var r=target.getAttribute("r");
            var o=target.getAttribute("fill-opacity");
            var t=setInterval(function(){
                r*=1.05;
                o*=0.9;
                target.setAttribute("r",r);
                target.setAttribute("fill-opacity",o);
                if(o<0.01){
                    clearInterval(t);
                    s1.removeChild(target);
                }
            },10);
        }
    }
    function rn(min,max){
        var n=Math.floor(Math.random()*(max-min)+min);
        return n;
    }
    function rc(min,max){
        var r=rn(min,max);
        var g=rn(min,max);
        var b=rn(min,max);
        return `rgb(${r},${g},${b})`;
    }
</script>

As above, I used vsg to randomly generate 30 circles. I hope that when I click on each circle, the circle will become larger and more transparent until it is deleted from the dom tree; my code can realize this function slowly one by one, but once it is quickly Double-click, and the error as shown below will appear:

I guess there is a problem with the timer writing, but I can't solve it myself; I'm new to the front end, my JS foundation is too weak, I kindly ask my seniors to teach me O(∩_∩)O~

高洛峰高洛峰2738 days ago1059

reply all(2)I'll reply

  • 给我你的怀抱

    给我你的怀抱2017-06-21 10:14:14

                if(o<0.01){
                    clearInterval(t);
                      if(s1.contains(target)){
                          s1.removeChild(target);
                      }
                }
                

    Write it like this, first determine whether the node still exists, if it exists, delete it, if it does not exist, it will not be rmeovechild

    The world is so big, I want to see it

    reply
    0
  • 代言

    代言2017-06-21 10:14:14

    It’s not a problem with the timer itself

    When double-clicking quickly, the circle drawn by svg has two timers set for execution. When the first timer reaches o<0.01, the clicked circle has been deleted.
    When the second timer also reaches this condition, when performing the deletion action, DOM finds that the object that needs to be deleted does not exist, so the error you see occurs.

    The solution is to add a judgment condition: if the timer has been set for the current circle, subsequent code will not be executed.

        s1.onclick=function(e){
            clearInterval(t);
            var target= e.target;
            //判断是否已经设置过了定时器
            if (target.getAttribute("interval") === "1") return;
            
            //在元素上增加设置定时器的标记
            target.setAttribute("interval", "1");
            if(target.nodeName=="circle"){
                var r=target.getAttribute("r");
                var o=target.getAttribute("fill-opacity");
                var t=setInterval(function(){
                    r*=1.05;
                    o*=0.9;
                    target.setAttribute("r",r);
                    target.setAttribute("fill-opacity",o);
                    if(o<0.01){
                        clearInterval(t);
                        s1.removeChild(target);
                    }
                },10);
            }
        }

    reply
    0
  • Cancelreply