封裝一個簡單的動畫函式
描述:使傳進來的元素緩慢移動到指定位置(前提此物件必須有定位)
// 簡單動畫函式封裝obj目標物件 target 目標位置
function animate(obj, target) {
var timer = setInterval(function() {
if (obj.offsetLeft >= target) {
// 停止動畫 本質是停止定時器
clearInterval(timer);
}
obj.style.left = obj.offsetLeft + 1 + 'px';
}, 30);
}
var div = document.querySelector('div');
var span = document.querySelector('span');
// 呼叫函式
animate(div, 300);
animate(span, 200);
但是這樣我們很多物件新增了多個定時器,影響記憶體,因此我們可以把定時器作為每一個物件的屬性
// 簡單動畫函式封裝obj目標物件 target 目標位置
// 給不同的元素指定了不同的定時器
function animate(obj, target) {
obj.timer = setInterval(function() {
if (obj.offsetLeft >= target) {
// 停止動畫 本質是停止定時器
clearInterval(obj.timer);
}
obj.style.left = obj.offsetLeft + 1 + 'px';
}, 30);
}
此處還有一個問題,如果我們通過點選,給一個物件新增多個定時器,會讓元素移動越來越快,因此我們可以每次都清除一下定時器
function animate(obj, target) {
// 當我們不斷的點選按鈕,這個元素的速度會越來越快,因為開啟了太多的定時器
// 解決方案就是 讓我們元素只有一個定時器執行
// 先清除以前的定時器,只保留當前的一個定時器執行
clearInterval(obj.timer);
obj.timer = setInterval(function() {
if (obj.offsetLeft >= target) {
// 停止動畫 本質是停止定時器
clearInterval(obj.timer);
}
obj.style.left = obj.offsetLeft + 1 + 'px';
}, 30);
}
var div = document.querySelector('div');
var span = document.querySelector('span');
var btn = document.querySelector('button');
// 呼叫函式
animate(div, 300);
btn.addEventListener('click', function() {
animate(span, 200);
})
在此,我們可以給動畫新增緩動效果(移動速度慢慢減小)
給元素移動的距離為一個變化的步長值,而不是1這個定值,步長值=(目標值-現在位置)/10
var step = (target - obj.offsetLeft) / 10;
obj.style.left = obj.offsetLeft + step + 'px';
但是,當盒子移動完之後,可能與目標距離不準,因為我們涉及到除法了,需要取整,同時,我們如果讓盒子移動到800px,再回來500px,也會不準,因此我們根據步長的值來確定向上還是向下取整
完整程式碼:
// 思路:
// 1. 讓盒子每次移動的距離慢慢變小, 速度就會慢慢落下來。
// 2. 核心演算法:(目標值 - 現在的位置) / 10 做為每次移動的距離 步長
// 3. 停止的條件是: 讓當前盒子位置等於目標位置就停止定時器
function animate(obj, target) {
// 先清除以前的定時器,只保留當前的一個定時器執行
clearInterval(obj.timer);
obj.timer = setInterval(function() {
// 步長值寫到定時器的裡面
// 把我們步長值改為整數 不要出現小數的問題
// var step = Math.ceil((target - obj.offsetLeft) / 10);
var step = (target - obj.offsetLeft) / 10;
step = step > 0 ? Math.ceil(step) : Math.floor(step);
if (obj.offsetLeft == target) {
// 停止動畫 本質是停止定時器
clearInterval(obj.timer);
}
// 把每次加1 這個步長值改為一個慢慢變小的值,步長公式:(目標值 - 現在的位置) / 10
obj.style.left = obj.offsetLeft + step + 'px';
}, 15);
}
var span = document.querySelector('span');
var btn500 = document.querySelector('.btn500');
var btn800 = document.querySelector('.btn800');
btn500.addEventListener('click', function() {
// 呼叫函式
animate(span, 500);
})
btn800.addEventListener('click', function() {
// 呼叫函式
animate(span, 800);
})
// 勻速動畫 就是 盒子是當前的位置 + 固定的值 10
// 緩動動畫就是 盒子當前的位置 + 變化的值(目標值 - 現在的位置) / 10)
補充:為動畫函式新增回撥
回撥原理:把一個函式作為一個引數傳遞給另一個函式,當這個函式執行完之後,再執行傳遞過來的函式
btn800.addEventListener('click', function() {
// 傳遞給animate的第三個引數,是一個函式
animate(span, 800, function() {
// alert('你好嗎');
span.style.backgroundColor = 'red';
});
})
//當需要停止定時器的時候呼叫這個函式
if (obj.offsetLeft == target) {
// 停止動畫 本質是停止定時器
clearInterval(obj.timer);
// 回撥函式寫到定時器結束裡面
if (callback) {
// 呼叫函式
callback();
}
}
相關文章
- 一個簡單的 Amqp 封裝MQ封裝
- 關於緩動動畫函式的封裝動畫函式封裝
- 封裝一個簡單的日曆元件封裝元件
- 一個最簡單的類JQuery封裝jQuery封裝
- 一個封裝簡單使用簡單的雷達檢視封裝
- javascript封裝動畫函式(勻速、變速)JavaScript封裝動畫函式
- jQuery常用的動畫函式簡單介紹jQuery動畫函式
- WebAPIs-06:動畫函式封裝 + 觸屏事件WebAPI動畫函式封裝事件
- Python函式:一個簡單的迭代Python函式
- 一個閉包函式的簡單例子函式單例
- javascript原生封裝一個淡入淡出效果的函式JavaScript封裝函式
- 一個簡單的載入動畫(一)動畫
- Retrofit的簡單封裝封裝
- IQueryable的簡單封裝封裝
- ProgressFragment的簡單封裝Fragment封裝
- 一個簡單的載入動畫(二)動畫
- jq封裝函式封裝函式
- php函式封裝PHP函式封裝
- 【JavaScript框架封裝】實現一個類似於JQuery的動畫框架的封裝JavaScript框架封裝jQuery動畫
- 在 vue-cil 裡封裝一個簡單的 axiosVue封裝iOS
- 程式碼改變世界 | 如何封裝一個簡單的 Koa封裝
- canvas簡單封裝一個echarts實現不了的餅圖Canvas封裝Echarts
- 封裝一個元件 + 函式惰性思想(重寫應用)封裝元件函式
- 一些簡單的函式函式
- 一個簡單的oracle函式返回陣列的例子Oracle函式陣列
- 【封裝小技巧】列表處理函式的封裝封裝函式
- Android 一起來封裝一個簡單易用的AdapterAndroid封裝APT
- 前端簡潔並實用的工具類函式封裝前端函式封裝
- 基於Vue.js封裝一個簡單的select元件Vue.js封裝元件
- 封裝一個簡單的樂觀鎖方法 -基於Laravel 8封裝Laravel
- Vue封裝一個簡單輕量的上傳檔案元件Vue封裝元件
- Golang(Go語言)封裝一個簡單的控制檯輸出包Golang封裝
- 一個簡單vue.config.js配置和axios簡單封裝VueJSiOS封裝
- golang封裝一個bash函式,用於執行bash命令Golang封裝函式
- 前端常用函式封裝前端函式封裝
- 常用js函式封裝JS函式封裝
- 【封裝小技巧】數字處理函式的封裝封裝函式
- 封裝帶引數的函式封裝函式