使用 jQuery `animate()` 控制圖片左右移動時,連續點擊按鈕動畫不執行或行為異常,原因是動畫隊列堆疊與 `left`/`right` 屬性混用導致邏輯衝突。
// 錯誤示例:混用 left 和 right
$("#L").click(function(){
$("span").animate({ right: '+=500px' }, 3000);
});
$("#R").click(function(){
$("span").animate({ left: '+=500px' }, 3000);
});
核心問題:同時操作 `left` 和 `right` 會導致元素定位邏輯衝突。CSS 盒模型中,若元素同時有 `left` 和 `right` 值,瀏覽器按特定規則計算寬度,動畫過程中兩屬性值同時變化會產生不可預期結果。
<style>
#container { position: relative; width: 5000px; height: 200px; }
#image { position: absolute; left: 0; top: 0; }
</style>
<button id="btnLeft">← 左移</button>
<button id="btnRight">右移 →</button>
<div id="container">
<img id="image" src="demo.jpg" alt="演示圖片">
</div>
<script>
$(function() {
var $img = $("#image");
var step = 500; // 每次移動像素
var maxLeft = 0; // 最左邊界
var minLeft = -3000; // 最右邊界 (根據容器寬度 - 可視區寬度)
$("#btnLeft").click(function() {
var currentLeft = parseInt($img.css("left")) || 0;
var targetLeft = Math.min(currentLeft + step, maxLeft);
$img.stop(true, true).animate({ left: targetLeft }, 500);
});
$("#btnRight").click(function() {
var currentLeft = parseInt($img.css("left")) || 0;
var targetLeft = Math.max(currentLeft - step, minLeft);
$img.stop(true, true).animate({ left: targetLeft }, 500);
});
});
</script>
<style>
#image {
position: absolute;
left: 0; top: 0;
transition: transform 0.5s ease-out;
will-change: transform; /* 提示瀏覽器優化 */
}
</style>
<script>
var currentX = 0;
var step = 500;
$("#btnLeft").click(function() {
currentX = Math.min(currentX + step, 0);
$("#image").css("transform", "translateX(" + currentX + "px)");
});
$("#btnRight").click(function() {
currentX = Math.max(currentX - step, -3000);
$("#image").css("transform", "translateX(" + currentX + "px)");
});
</script>
優勢:GPU 加速、不觸發重排、動畫更流暢、代碼更簡潔。
var itemWidth = 500;
var visibleCount = 3;
var totalItems = 6;
var currentIndex = 0;
function moveTo(index) {
var targetX = -index * itemWidth;
$img.stop(true, true).animate({ left: targetX }, 500, function() {
// 無縫循環邏輯
if (index >= totalItems - visibleCount) {
$img.css("left", 0);
currentIndex = 0;
} else if (index < 0) {
$img.css("left", -(totalItems - visibleCount) * itemWidth);
currentIndex = totalItems - visibleCount;
}
});
currentIndex = index;
}
$("#btnLeft").click(function() { moveTo(currentIndex - 1); });
$("#btnRight").click(function() { moveTo(currentIndex + 1); });