Heim  >  Artikel  >  Web-Frontend  >  Wie wird der JavaScript-Rebound-Animationseffekt implementiert?

Wie wird der JavaScript-Rebound-Animationseffekt implementiert?

零下一度
零下一度Original
2017-07-16 15:25:181178Durchsuche

JavaScriptWie erzielt man den Rebound-Animationseffekt? Lassen Sie mich es Ihnen anhand des Codes im Detail vorstellen.

Der Code lautet wie folgt:

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <title>Document</title>
  <style>
    #box{
      width:200px;
      height:200px;
      position: absolute;
      top:0;
      left:200px;
      background:lightblue;
    }
    .btn{
      position:absolute;
      top:200px;
      left:100px;
      height:50px;
    }
    .btn input{
      display:inline-block;
      margin-left:50px;
      outline: none;
      width:100px;
      height:50px;
      border:1px solid green;
      cursor:pointer;
    }
  </style>
</head>
<body>
  <p id=&#39;box&#39;></p>
  <p class=&#39;btn&#39;>
    <input type="button" value=&#39;向左&#39; id=&#39;btnLeft&#39;>
    <input type="button" value=&#39;向右&#39; id=&#39;btnRight&#39;>
  </p>
  <script>
    var oBox = document.getElementById("box");
    var minLeft = 0;
    var maxLeft = utils.win(&#39;clientWidth&#39;)-oBox.offsetWidth;
    var step = 5;
    var timer = null;
    function move(target){
      //target:告诉我要运动的目标位置
      window.clearTimeout(timer);
      var curLeft = utils.css(oBox,"left");
      if(curLeft<target){//向右走
        if(curLeft+step>target){//边界
          utils.css(oBox,"left",target);
          return;
        }
        curLeft+=step;
        utils.css(oBox,"left",curLeft)
      }else if(curLeft>target){//向左走
        if(curLeft-step<target){//边界
          utils.css(oBox,"left",target);
          return;
        }
        curLeft-=step;
        utils.css(oBox,"left",curLeft)
      }else{//不需要运动
        return;
      }
      // timer = window.setTimeout(move,10)//这里有一个问题,点击按钮第一次target的值是有的,但是第二次通过setTimeout执行的时候没有给target进行传值。是undefined
      timer = window.setTimeout(function(){
        move(target);
      },10)//这样使用匿名函数包裹一下,就解决了上面的问题,但是这样写性能不好,因为每一次到达时间的时候,都需要执行一次匿名函数(形成一个私有的作用域),在匿名函数中再执行move,但是move中需要用到的数据值在第一次执行的move方法中,需要把匿名函数形成的这个私有的作用域作为跳板找到之前的,这样就导致了匿名函数形成的这个私有的作用域不能销毁
    }
    document.getElementById(&#39;btnLeft&#39;).onclick = function(){
      move(minLeft)
    }
    document.getElementById(&#39;btnRight&#39;).onclick = function(){
      move(maxLeft)
    }
  </script>
</body>
</html>

Um das oben genannte Problem der schlechten Leistung zu lösen, ist der folgende optimierte Code: Darin wird ein Funktionspaket verwendet, sodass dort ist nur einer, der durch die Move-Funktion erstellt wurde. Der private Bereich wird nicht zerstört. Wenn _move ausgeführt wird, wird der Move natürlich zerstört.

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <title>Document</title>
  <style>
    #box{
      width:200px;
      height:200px;
      position: absolute;
      top:0;
      left:200px;
      background:lightblue;
    }
    .btn{
      position:absolute;
      top:200px;
      left:100px;
      height:50px;
    }
    .btn input{
      display:inline-block;
      margin-left:50px;
      outline: none;
      width:100px;
      height:50px;
      border:1px solid green;
      cursor:pointer;
    }
  </style>
</head>
<body>
  <p id=&#39;box&#39;></p>
  <p class=&#39;btn&#39;>
    <input type="button" value=&#39;向左&#39; id=&#39;btnLeft&#39;>
    <input type="button" value=&#39;向右&#39; id=&#39;btnRight&#39;>
  </p>
  <script>
    var oBox = document.getElementById("box");
    var minLeft = 0;
    var maxLeft = utils.win(&#39;clientWidth&#39;)-oBox.offsetWidth;
    var step = 5;
    var timer = null;
    function move(target){
      //target:告诉我要运动的目标位置
      _move();
      function _move(){
        window.clearTimeout(timer);
        var curLeft = utils.css(oBox,"left");
        if(curLeft<target){//向右走
          if(curLeft+step>target){//边界
            utils.css(oBox,"left",target);
            return;
          }
          curLeft+=step;
          utils.css(oBox,"left",curLeft)
        }else if(curLeft>target){//向左走
          if(curLeft-step<target){//边界
            utils.css(oBox,"left",target);
            return;
          }
          curLeft-=step;
          utils.css(oBox,"left",curLeft)
        }else{//不需要运动
          return;
        }
        timer = window.setTimeout(_move,10);
      }
    }
    document.getElementById(&#39;btnLeft&#39;).onclick = function(){
      move(minLeft)
    }
    document.getElementById(&#39;btnRight&#39;).onclick = function(){
      move(maxLeft)
    }
  </script>
</body>
</html>

Hinweis: Damit das aktuelle Element nur eine Animation gleichzeitig ausführen kann (wenn die nächste Animation startet, löschen Sie zuerst den Timer der vorherigen Animation): Stellen Sie sicher, dass die Variable, die den Timer-Rückgabewert für alle Animationen des Elements empfängt, gemeinsam genutzt werden muss. Es gibt zwei Möglichkeiten: 1. Globaler Empfang (z. B. der obige Code var timer = null) 2. Fügen Sie benutzerdefinierte Attribute hinzu das Element (wie in der Abbildung unten gezeigt)

Zusammenfassung: Aus dem Obigen können wir vier Regeln für die Animationsoptimierung ziehen:

1. Grenzbeurteilung und Schrittgröße

2. Beseitigen Sie nutzlose Timer

3. Wenn die äußere Funktion Parameter übergeben muss, können Sie eine Ebene von Funktionen darin verschachteln, um die Anhäufung von Bereichen zu vermeiden.

4. Speichern Sie den Rückgabewert des Timers im benutzerdefinierten Attribut des Elements, um globale Variablenkonflikte und mehrere Animationsausführungen gleichzeitig zu verhindern

Das obige ist der detaillierte Inhalt vonWie wird der JavaScript-Rebound-Animationseffekt implementiert?. Für weitere Informationen folgen Sie bitte anderen verwandten Artikeln auf der PHP chinesischen Website!

Stellungnahme:
Der Inhalt dieses Artikels wird freiwillig von Internetnutzern beigesteuert und das Urheberrecht liegt beim ursprünglichen Autor. Diese Website übernimmt keine entsprechende rechtliche Verantwortung. Wenn Sie Inhalte finden, bei denen der Verdacht eines Plagiats oder einer Rechtsverletzung besteht, wenden Sie sich bitte an admin@php.cn