Andaikan terdapat keperluan fungsi animasi sedemikian: tukar lebar div daripada 100px kepada 200px. Kod yang ditulis mungkin kelihatan seperti ini:
animate1(document.getElementById('test1'), 200, 1000);
Adakah cara yang lebih baik? Mari kita lihat masalah matematik sekolah rendah:
Inspirasi yang dibawakan oleh soalan ini ialah jarak pada saat tertentu boleh dikira melalui formula tertentu. Dengan cara yang sama, nilai pada masa tertentu semasa proses animasi juga boleh dikira melalui formula dan bukannya terkumpul:
var timerId = setInterval(function() {
peratusan var = (Tarikh baharu - Masa mula) / tempoh;
var stepValue = startValue (endValue - startValue) * peratusan;
element.style.width = stepValue 'px';
jika (peratusan >= 1) {
clear Interval(timerId);
element.innerHTML = Tarikh baharu - Masa mula;
}
}, 13);
}
animate2(document.getElementById('test2'), 200, 1000);
Selepas penambahbaikan ini, anda dapat melihat bahawa masa pelaksanaan animasi hanya akan mempunyai ralat paling banyak 10 ms. Tetapi masalahnya belum selesai sepenuhnya. Memeriksa elemen test2 dalam alat pembangunan penyemak imbas menunjukkan bahawa lebar akhir test2 mungkin lebih daripada 200px. Pemeriksaan teliti kod fungsi animate2 mendedahkan:
Nilai 1.peratusan mungkin lebih besar daripada 1, yang boleh diselesaikan dengan mengehadkan nilai maksimum melalui Math.min.
2. Walaupun ia dijamin bahawa nilai peratusan tidak lebih daripada 1, selagi endValue atau startValue ialah perpuluhan, nilai (endValue - startValue) * peratusan mungkin masih menghasilkan ralat kerana ketepatan operasi perpuluhan Javascript adalah tak cukup. Sebenarnya, apa yang kita ingin pastikan ialah ketepatan nilai akhir, jadi apabila peratusannya adalah 1, gunakan sahaja endValue secara langsung.
Jadi, kod fungsi animate2 diubah suai kepada:
var timerId = setInterval(function() {
// Pastikan peratusan tidak melebihi 1
peratusan var = Math.min(1, (Tarikh baharu - Masa mula) / tempoh);
var stepValue;
Jika (peratusan >= 1) {
// Pastikan ketepatan nilai akhir
stepValue = endValue;
} lain {
stepValue = startValue (endValue - startValue) * peratusan;
}
element.style.width = stepValue 'px';
jika (peratusan >= 1) {
clear Interval(timerId);
element.innerHTML = Tarikh baharu - Masa mula;
}
}, 13);
}
Terdapat satu soalan terakhir: Mengapa selang setInterval ditetapkan kepada 13ms? Sebabnya ialah kadar penyegaran semula monitor semasa secara amnya tidak melebihi 75Hz (iaitu, disegarkan 75 kali sesaat, iaitu, disegarkan setiap kira-kira 13ms. Adalah lebih baik untuk menyegerakkan selang dengan kadar penyegaran).