使用 jQuery animate() 時,回調函數帶參數會出現各種錯誤,通常是變量作用域污染或閉包陷阱導致。
// 錯誤示例
var index = 0;
$('.item').each(function() {
$(this).animate({left: '100px'}, 500, function() {
callback(index); // 所有回調都拿到最後的 index 值
});
index++;
});
// 或者全局變量被污染
var globalData = {};
function animateWithCallback(param) {
globalData.param = param; // 污染全局
$('#elem').animate({opacity: 0.5}, 300, function() {
handle(globalData.param);
});
}
var 無塊級作用域,回調捕獲的是同一個變量引用animate(params, speed, easing, callback) 回調不接受額外參數$('.item').each(function(i) {
(function(index) {
$(this).animate({left: '100px'}, 500, function() {
callback(index); // 正確捕獲當前 index
});
})(i);
});
for (let i = 0; i < items.length; i++) {
$(items[i]).animate({left: '100px'}, 500, function() {
callback(i); // 每次循環 i 都是獨立綁定
});
}
$('.item').each(function(i) {
$(this).data('callback-index', i)
.animate({left: '100px'}, 500, function() {
var index = $(this).data('callback-index');
callback(index);
});
});
function animatePromise($elem, props, duration) {
return new Promise(resolve => {
$elem.animate(props, duration, resolve);
});
}
// 使用
async function runAnimations() {
for (let i = 0; i < items.length; i++) {
await animatePromise($(items[i]), {left: '100px'}, 500);
callback(i); // 同步寫法,無閉包煩惱
}
}
let/const 避免變量提升問題.data() 或 .attr() 在 DOM 上攜帶上下文