9. 複数の属性の同時移動
前の例では、各属性が独立して移動します。複数の属性を同時に移動したい場合はどうすればよいでしょうか。たとえば、onmouseover イベントで div の幅と高さを同時に変更したいとします。次の関数は、幅を独立して変更します:
window.onload=function(){ var ob1=document.getElementById('div1'); ob1.onmouseover=function(){ startMove(ob1,'width',400); } }
1 つのアイデアは、startMove の下に startMove を追加することです:
window.onload=function(){ var ob1=document.getElementById('div1'); ob1.onmouseover=function(){ startMove(ob1,'width',400); startMove(ob1,'height',400); } }
このアイデアは高さだけが変更され、幅は変更されないことがわかります。なぜ? startMove 関数は最初にタイマーを閉じるため、最初の startMove 関数が実行を開始したばかりのとき、2 番目の startMove はすでに実行を開始しており、2 番目の startMove のクローズ タイマー関数は最初の startMove のタイマーを上書きします。オブジェクトは変更できず、高さのみが変更されます。では、どうすれば解決できるでしょうか?ここでは json を使用する必要があります:
var json={a:12,b:13}; for(var i in json){ alert(i); alert(json[i]); }
json 内の値はペアで表示され、各ペアは変数と変数の値です。 for in ループを使用して、変数の各ペアと対応する値を取得できます。上記のプログラムでは、a、12、b、13 が順にポップアップ表示されます。
stareMove フレームワークを見て、パラメータの「属性」と「ターゲット値」が値のペアであることを確認しましょう。これは、1 つの startMove が 1 つの値のペアの変更のみを達成できることを意味します。複数の値のペアに対する変更を実装するにはどうすればよいですか?次のような startMove を見てみましょう:
startMove(obj,{attr1:target1,attr2:target2},fn)、青い部分は json 形式なので、元の startMove に基づいて、青い部分を次のように置き換えます。 json ;プログラム内のターゲットを json[attr] (どの属性がその属性のターゲット値であるか) に置き換えます。変更された startMove 関数は次のとおりです: (行 1、4、13、および 16 が変更されています)
function startMove(obj,json,fn) {//元素,改变的样式属性,达到的目标值,回调函数 clearInterval(obj.timer); obj.timer=setInterval(function(){ for(var attr in json){ //1.取当前值 var icur=0;//icur返回物体样式属性值的大小 if (attr=='opacity') {//如果属性是透明度,透明度的返回值是零点几的小数 icur=Math.round(parseFloat(getStyle(obj,attr))*100);//round函数避免透明度值在小数之间来回跳动 } else { icur=parseInt(getStyle(obj,attr)); } //2.算速度 var speed=(json[attr]-icur)/8;//分母为比例系数K,可调 speed=speed>0?Math.ceil(speed):Math.floor(speed);//缓冲速度要取整,不然移动不到终点就停止 //3.检测运动是否停止 if (icur==json[attr]) { clearInterval(obj.timer); if(fn){//上一个运动停止后判断一下是否还有下一个运动 fn(); } } else { if (attr=='opacity') { obj.style.filter='alpha(opacity:'+(icur+speed)+')';//IE浏览器 obj.style.opacity=(icur+speed)/100;//火狐浏览器 } else { obj.style[attr]=icur+speed+'px'; } } } },30) }
以下は、幅と高さを同時に変更するために startMove 関数を呼び出す div の効果です:
<style type="text/css"> #div1{ width: 200px; height: 200px; background: red; border: 2px solid black; filter: alpha(opacity:30); opacity: 0.3; } </style>
<script type="text/javascript"> window.onload=function(){ var ob1=document.getElementById('div1'); ob1.onmouseover=function(){ startMove(ob1,{width:400,height:400});//json格式 } } </script>
You透明度のペアを追加して、幅、高さ、透明度の変更を同時に実現できます:
<script type="text/javascript"> window.onload=function(){ var ob1=document.getElementById('div1'); ob1.onmouseover=function(){ startMove(ob1,{width:400,height:400,opacity:100}); } } </script>
このフレームワークの問題点: 幅を 201 に、高さを 400 に、透明度を 100 に変更したい場合、問題が発生します。幅は 201 になりますが、高さと透明度の目標値に達するどころか、動きが停止してしまいます。理由は、17 行目でタイマーをオフにしているためです。本来のプログラムでは、1 つの属性値が目標値に達していれば、各属性が目標値に達しているかどうかの判定は行われません。したがって、幅が目標値に達し、高さと透明度が目標値に達していない場合、タイマーはオフになります。解決策: タイマーを閉じる前に、すべての属性が目標値に達していることを確認する必要があります。 (2 行目と 17 行目以降に変更があります)
function startMove(obj,json,fn) {//元素,改变的样式属性,达到的目标值,回调函数 var flag=true;//定义一个标杆,假设所有运动都达到了目标值 clearInterval(obj.timer); obj.timer=setInterval(function(){ for(var attr in json){ //1.取当前值 var icur=0;//icur返回物体样式属性值的大小 if (attr=='opacity') {//如果属性是透明度,透明度的返回值是零点几的小数 icur=Math.round(parseFloat(getStyle(obj,attr))*100);//round函数避免透明度值在小数之间来回跳动 } else { icur=parseInt(getStyle(obj,attr)); } //2.算速度 var speed=(json[attr]-icur)/8;//分母为比例系数K,可调 speed=speed>0?Math.ceil(speed):Math.floor(speed);//缓冲速度要取整,不然移动不到终点就停止 //3.检测运动是否停止 if (icur!=json[attr]) {//如果不是所有的运动都达到目标值 flag=false; } if (attr=='opacity') {//没达到目标值的继续运动 obj.style.filter='alpha(opacity:'+(icur+speed)+')';//IE浏览器 obj.style.opacity=(icur+speed)/100;//火狐浏览器 } else { obj.style[attr]=icur+speed+'px'; } if(flag){//如果所有的运动都达到了目标值,再关闭定时器,然后看看有没有链式运动 clearInterval(obj.timer); if(fn){ fn(); } } } },30) }
これで、この修正されたフレームワークは、Web サイトで一般的に使用されるいくつかの小さなアニメーションをこのフレームワークを使用して実装できます。
上記は js アニメーション学習 (5) の内容です。その他の関連コンテンツについては、PHP 中国語 Web サイト (www.php.cn) に注目してください。