[JS30] Day27: Click and Drag to Scroll
這一天的實作是要做像是 slider 的東西,可以在滑鼠按下時,左右拖拉移動元素。
HTML
有 25 個.item的 div 元素
<div class="items">
<div class="item item1">01</div>
<div class="item item2">02</div>
<div class="item item3">03</div>
// ...
<div class="item item25">25</div>
</div>
CSS
透過overflow-x: scroll達到左右捲動,perspective: 500px為上帝視角
.items {
height: 800px;
padding: 100px;
width: 100%;
border: 1px solid white;
overflow-x: scroll;
overflow-y: hidden;
white-space: nowrap;
user-select: none;
cursor: pointer;
transition: all 0.2s;
transform: scale(0.98);
will-change: transform;
position: relative;
background: rgba(255, 255, 255, 0.1);
font-size: 0;
perspective: 500px;
}
JS
重點是在滑鼠按下時,要知道當下的 x 座標(startX = e.pageX - slider.offsetLeft),隨著滑鼠移動(mousemove),slider 的 x 座標也要跟著移動,walk 就是要移動的距離(x - startX),最後設定 slider 的左側推移(slider.scrollLeft = scrollLeft - walk)。
註: 可以將 walk 乘以倍數,會加速 slider 的左右移動
const slider = document.querySelector(".items");
let isDown = false;
let startX;
let scrollLeft;
slider.addEventListener("mousedown", (e) => {
isDown = true;
slider.classList.add("active");
startX = e.pageX - slider.offsetLeft;
scrollLeft = slider.scrollLeft;
});
slider.addEventListener("mouseleave", () => {
isDown = false;
slider.classList.remove("active");
});
slider.addEventListener("mouseup", () => {
isDown = false;
slider.classList.remove("active");
});
slider.addEventListener("mousemove", (e) => {
if (!isDown) return; // stop the fn from running
e.preventDefault(); // prevent triggering other events
const x = e.pageX - slider.offsetLeft;
const walk = x - startX;
slider.scrollLeft = scrollLeft - walk;
});