iT邦幫忙

2022 iThome 鐵人賽

DAY 27
0

27 - Click and Drag

tags: JavaScript30

專案簡介

第二十七天要實作的專案是偵測滑鼠在範圍內的拖曳,而帶動 HTML 元素的橫向滾動軸

課程影片:JS30 27
導讀影片:Alex

初始文件

Github 檔案位置:27 - Click and Drag

網站初始的樣子

可以先看看最後的成果

正式製作

首先,首先,每次都是首先(誤,一樣是先選取好 DOM 元素再設監聽事件,並加入已經寫好的 active class,最後在 console 查看功能是否正常(在範圍內按住才會跳 ouob,以及使畫面凸顯)

const slider = document.querySelector('.items');
let isDown = false; // 偵測滑鼠是否在範圍內被按下

slider.addEventListener('mousedown', (e) => {
  isDown = true;
  slider.classList.add('active');
});

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;
  // e.preventDefault(); // 取消正常情況滑鼠拖曳的預設行為
  console.log('ouob')
});

接下來要做的事情就是在觸發拖曳事件時,計算出滑鼠點擊的座標到滑鼠滑動位置的距離,加權後設定為 slider.scrollLeft 使他橫向移動

變數介紹

按下時

  1. e.pageX:滑鼠在整份網頁中的 X 座標位置
  2. startX:鼠標相對於 slider 最左側的 x 軸位置
  3. scrollLeft:slider 橫向滾動軸的實時位置

拖曳時

  1. x:鼠標相對於 slider 最左側的 x 軸位置,將在拖曳時持續更新
  2. walk:以持續更新的 x 減掉觸發 mousedown 事件時原先位置的 startX 即可獲得座標差,乘三是常數,決定了拖曳時 DOM 元素滾動的速率

以上述這些變數的邏輯綜合起來,即可在滑鼠按下時偵測起始點,並在拖曳時持續的抓取鼠標的 x 座標,只要減去起始位置的 x 座標值,再賦值給 slider.scrollLeft 即可完成專案目標

let startX;
let scrollLeft;

slider.addEventListener('mousedown', (e) => {
  startX = e.pageX - slider.offsetLeft;
  scrollLeft = slider.scrollLeft;
});

slider.addEventListener('mousemove', (e) => {
  const x = e.pageX - slider.offsetLeft; 
  const walk = (x - startX) * 3;
  slider.scrollLeft = scrollLeft - walk;
});

最後程式碼

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;
  console.log('ouob')
  const x = e.pageX - slider.offsetLeft; 
  const walk = (x - startX) * 3;
  slider.scrollLeft = scrollLeft - walk;
});

完成結果

最後的成品

結語

以上是第二十七天的製作紀錄,如有錯誤或不足的地方還請多多指教 >.<

JavaScript Interface Challenge: Click and Drag to Scroll - #JavaScript30 27/30
[ Alex 宅幹嘛 ] ?‍? 深入淺出 Javascript30 快速導覽 | Day 27:Click and Drag
MDN Web Docs


上一篇
JS30 -> 27 - Click and Drag
下一篇
JS30 -> 29 - Countdown Timer
系列文
剛接觸前端一個月的小白 - JavaScript30 挑戰筆記30
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

1 則留言

0
Oo_花之舞__oO
iT邦新手 1 級 ‧ 2023-02-07 05:01:10

哈囉你怎麼漏掉這篇了XD 直接貼前一天ㄉ耶

我要留言

立即登入留言