目標
點擊滑鼠後左右拖曳移動内容
mousedown
:當滑鼠點擊時被觸發。
onmousemove
:當滑鼠移動時被觸發。
mouseleave
:當滑鼠移出指定的元素時被觸發。
onmouseup
:當滑鼠的按鍵放開時被觸發。
step 1 : 取得 HTML 頁面元素,設置變數并且建立監聽事件
const slider = document.querySelector('.items');
let isDown = false;
let startX;
let scrollLeft;
slider.addEventListener('mousedown',e=>{
})
slider.addEventListener('mousemove',(e)=>{
})
slider.addEventListener('mouseup',()=>{
})
slider.addEventListener('mouseleave',()=>{
})
step 2 : mousedown 事件被觸發時
slider.addEventListener('mousedown',e=>{
isDown = true
// 添加 css 樣式 active,設定放大效果:scale(0.98)->scale(1)
slider.classList.add('active')
// 元素移動的初始值 = 點擊當下的頁面距離 - 當前 items 的左邊距
startX = e.pageX - slider.offsetLeft
// 點擊當下捲軸的左距
scrollLeft = slider.scrollLeft
})
step 3 : mousemove 事件被觸發時
slider.addEventListener('mousemove',(e)=>{
// 如果不是滑鼠按下後的拖曳,不進行任何動作
if(!isDown) return
// 避免觸發任何預設事件
e.preventDefault()
// 元素當前位置 = 當下的頁面距離 - 當前 items 的左邊距
const x = e.pageX - slider.offsetLeft
console.log(e.pageX, startX)
// 移動的距離 = 元素當前位置 - 元素初始位置
const walk = x - startX
// 水平卷軸的移動距離 = 元素初始的捲軸左距 - 移動的距離
slider.scrollLeft = scrollLeft - walk
})
step 4 : mouseleave、mouseup 事件被觸發時,移除 active css 樣式
slider.addEventListener('mouseleave', () => {
// 將按下的flag與樣式移除
isDown = false;
slider.classList.remove('active');
});
slider.addEventListener('mouseup', () => {
// 將按下的flag與樣式移除
isDown = false;
slider.classList.remove('active');
});
參考資料:
- JavaScript Interface Challenge: Click and Drag to Scroll - #JavaScript30 27/30 @Wes Bos
- [ Alex 宅幹嘛 ] 👨💻 深入淺出 Javascript30 快速導覽 | Day 27:Click and Drag @Alex 宅幹嘛
- 27 - Click and Drag @guahsu
- [JS30] Day27: Click and Drag@PJChen
- Element.scrollLeft@MDN
- JS一秒區分clientX,offsetX,screenX,pageX之間關係
- CSS沒有極限 - CSS transform-3D的透視(perspective)@卡斯伯