iT邦幫忙

2024 iThome 鐵人賽

DAY 27
0

Click and Drag to Scroll 滑鼠按著拖曳滾動

這效果感覺像是swiper一樣,可以用滑鼠去拖曳滾動整個容器,畢竟滑鼠的滾輪預設行為是上下滾動頁面,遇到這種橫向的scroll,要用滑鼠滾輪滾動就要特別寫JS處理。

https://ithelp.ithome.com.tw/upload/images/20241006/20169174sPRQ23h1WY.png

個人codepen

技巧點

1. pageX

得到相對於整個文件的X軸水平位置,從左側文件的邊距開始算起。並且如果整個window出現水平滾動軸時,還要加上滾動的距離。

也就是從下圖中左側的綠色邊線開始,得到的x軸水平位置。

https://ithelp.ithome.com.tw/upload/images/20241006/20169174ecszDNcMcz.png

當我點擊上面圖中的IT小方塊時,距離左側文件的pageX座標為200。但因為window有出現橫向捲動軸,當我捲動之後,再次點擊IT小方塊,pageX座標不會固定為200,要加上滾動後的距離。範例

https://ithelp.ithome.com.tw/upload/images/20241006/2016917402h6x9Jr5U.png

那這次的練習中,也使用到了pageX。這邊pageX不用考慮到被滾動走的距離。因為有卷軸的不在winodw,而是在內容器中。所以pageX的值在同個位置時,都是固定的,不管內容器滾動了多少橫向距離。

  slider.addEventListener('mousedown', (e) => {
     // 控制是否拖曳的開關
    isDown = true;
    
    // 給予css效果
    slider.classList.add('active
    
    // 按下的起始點,先記錄下來,待會才能知道使用者從哪裡開始拖曳,並且拖曳到哪裡結束。
    startX = e.pageX;
    
    // 紀錄一開始容器的橫向滾動距離,待會才能知道要橫向滾動多少
    scrollLeft = slider.scrollLeft;
  });
  
  
slider.addEventListener('mousemove', (e) => {
    // 確認滑鼠是否開始要拖曳,如果不是則返回,不繼續執行。
    if (!isDown) return;
    
    // mousemove預設行為會是選取文字,因此要停止預設行為。
    e.preventDefault();
    
    // 取得一直拖曳中的pageX位置
    const x = e.pageX;
    
    // 跟一開始mousedown的起始位置做相減,可以得到拖曳了多少距離
    const walk = (x - startX);
    
    // 將容器拖曳到對應的位置
    // 因為從右向左拖曳的時候,walk的值會變為負值,但scrollLeft的值是要增加。所以這邊要用相減才會得到正確的值。
    slider.scrollLeft = scrollLeft - walk;
  });

影片中的寫法為起始的pageX 減掉slider相對於左側文件邊緣的距離。
這是因為slider容器沒有完全貼著文件,中間有一些空隙。這樣得到的x距離是最正確的。
但也因為只計算差距而已,所以不處理這個,也沒差。

startX = e.pageX - slider.offsetLeft;

2. scrollLeft

  • 可以讀取或是設置元素滾動到其相對於容器左邊的距離。預設如果內容排列方向為從左到右,那卷軸一開始會位於最左側,scrollLeft為0。當你開始滾動卷軸時,捲軸會往右邊一直移動,scrollLeft值會一直正增加。
    反之,某些國家的書寫方向是右到左,這時卷軸一開始會位於最右側,你開始滾動後,捲軸開始往左邊跑,scrollLeft的值會一直負增加。(台灣應該是不會遇到這問題啦)
// 直接設置滾動到距離左側100的距離
slider.scrollLeft = 100;

3. scrollTo()

  • 滾動到特定的xy座標,所以除了scrollLeft之外,也可以用這個。但要注意寫法不太一樣
// 第一種寫法,直接代xy座標軸,像我就很常用到要換頁面的時候要滾動到最上面。
slider.scrollTo(0, 0);

// 代入物件,裡面可以最多三個參數,top、left、behavior
slider.scrollTo({
  left: 100,
  top: ??,
  behavior: "smooth", // 平順滾動效果,才不會立即跳到指定位置
});

心得

滑鼠事件的座標值好多,offsetX、clientX、pageX、screenX一拖拉庫,每次都要去翻一下定義或圖解說明。所以我說可不要讓我處理滾動事件了嗎QQ,金魚腦要燒掉了。


上一篇
Stripe Follow Along Dropdown
下一篇
Video Speed Controller UI
系列文
鱷魚帶我練習JavaScript之個人練功坊30
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言