已知兩個 `
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>DIV 位置互換動畫</title>
<script src="https://code.jquery.com/jquery-3.6.0.min.js"></script>
<style>
#div1, #div2 {
width: 100px; height: 100px;
border: 2px solid #333;
background: #eee;
position: absolute; /* 關鍵:啟用 top/left 定位 */
text-align: center; line-height: 100px;
font-weight: bold;
transition: none; /* 關閉 CSS transition,避免與 jQuery animate 衝突 */
}
#div1 { top: 100px; left: 100px; background: #ffe0e0; }
#div2 { top: 300px; left: 300px; background: #e0ffe0; }
button { position: fixed; top: 20px; right: 20px; padding: 10px 20px; font-size: 16px; }
</style>
</head>
<body>
<button onclick="swapDivs()">交換位置</button>
<div id="div1">DIV 1</div>
<div id="div2">DIV 2</div>
<script>
function swapDivs() {
var $div1 = $('#div1'), $div2 = $('#div2');
// 1. 獲取當前座標
var pos1 = $div1.offset();
var pos2 = $div2.offset();
// 2. 交換動畫(同時啟動)
$div1.animate(pos2, 800, 'swing'); // 800ms, 緩動函數 swing/linear
$div2.animate(pos1, 800, 'swing');
}
</script>
</body>
</html>
| 場景 | 處理方式 |
|---|---|
| 元素原本 `static` 定位 | 動畫前臨時改為 `relative`,記錄原 `margin`,動畫後恢復;或改用 `transform: translate()` 動畫(需計算相對位移)。 |
| 防止連續點擊動畫排隊 | 加鎖標誌:`if ($div1.is(':animated')) return;` |
| 動畫完成後回調 | `$div1.animate(pos2, 800, function() { console.log('完成'); });` |
| 多元素排序/打亂 | 收集所有座標 → 打亂/排序 → 批次 `.animate()`,配合 `$.when().done()` 統一回調。 |
| 性能優化 | 使用 `transform: translate3d()` + `requestAnimationFrame` 或 CSS `transition` 替代 jQuery `animate`(避免佈局抖動、啟用 GPU 加速)。 |
function swapDivsModern() {
var $div1 = $('#div1'), $div2 = $('#div2');
var pos1 = $div1.offset(), pos2 = $div2.offset();
// 計算相對位移
var dx1 = pos2.left - pos1.left, dy1 = pos2.top - pos1.top;
var dx2 = -dx1, dy2 = -dy1;
// 使用 CSS transition + transform
$div1.css({transition: 'transform 0.8s cubic-bezier(0.4,0,0.2,1)', transform: `translate(${dx1}px, ${dy1}px)`});
$div2.css({transition: 'transform 0.8s cubic-bezier(0.4,0,0.2,1)', transform: `translate(${dx2}px, ${dy2}px)`});
// 動畫結束後同步真實位置、清理 transform
setTimeout(function() {
$div1.css({left: pos2.left, top: pos2.top, transform: '', transition: ''});
$div2.css({left: pos1.left, top: pos1.top, transform: '', transition: ''});
}, 800);
}
jQuery `offset()` + `animate()` 實現 DIV 互換動畫簡單直觀,適合簡單交互。追求高性能、流暢度、避免佈局抖動的現代專案,建議改用 **CSS Transform + Transition** 方案,核心邏輯同樣是「計算目標位置 → 套用位移動畫 → 同步最終座標」。