recherche

Maison  >  Questions et réponses  >  le corps du texte

javascript - Questions sur les minuteries et la prévention des clics continus



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

Comme ci-dessus, j'ai utilisé vsg pour générer aléatoirement 30 cercles. J'espère que lorsque je clique sur chaque cercle, le cercle deviendra plus grand et plus transparent jusqu'à ce qu'il soit supprimé de l'arborescence DOM. Mon code pourra réaliser cette fonction lentement un par un. , mais une fois double-cliqué rapidement, l'erreur indiquée ci-dessous apparaîtra :

Je suppose qu'il y a quelque chose qui ne va pas avec l'écriture du timer, mais je ne peux pas le résoudre moi-même ; je suis un débutant en front-end, mes bases JS sont trop faibles, je demande gentiment à mes seniors de m'apprendre O(∩_ ∩)O~

高洛峰高洛峰2738 Il y a quelques jours1058

répondre à tous(2)je répondrai

  • 给我你的怀抱

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

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

    Écrivez-le comme ceci, déterminez d'abord si le nœud existe toujours, s'il existe, supprimez-le, s'il n'existe pas, il ne sera pas rmeovechild

    Le monde est si grand, je veux le voir

    répondre
    0
  • 代言

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

    Ce n'est pas un problème avec la minuterie elle-même

    Lors d'un double-clic rapide, le cercle dessiné par svg a deux minuteries définies pour l'exécution. Lorsque la première minuterie atteint o<0,01, le cercle cliqué a été supprimé.
    Lorsque le deuxième minuteur atteint également cette condition, lors de l'exécution de l'action de suppression, DOM constate que l'objet qui doit être supprimé n'existe pas, donc l'erreur que vous voyez se produit.

    La solution est d'ajouter une condition de jugement : si le timer a été réglé pour le cercle en cours, le code suivant ne sera pas exécuté.

        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);
            }
        }

    répondre
    0
  • Annulerrépondre