# 該如何手刻達到拖曳的效果?(draggable slider) ###### tags: `前端筆記` `特別效果` 因為自己在做的專案有需要使用這個效果,所以找到了 [Vanilla JavaScript: Create A Draggable Slider](https://www.youtube.com/watch?v=KHGc7eZyxKY&list=LL&index=4&t=27s) 這部教學影片,看完影片還花一段時間才理解,此篇是我看完影片的學習筆記。 ## 達成效果需要的要素 1. 需要滑動「卡片」 - 一層負責整個卡片的容器 - 單獨卡片的容器 - 整個卡片的容器之外還要有一個包覆的區塊(用來固定整個卡片容器) ### 事件(也就是 JavaScript) 2. 滑動的動作解析 - 保持點擊狀態 - 代表目前正在「抓」的狀態 - `mousedown event` => 不是 `click event`,因為 `click` 係點擊而已 - 狀態開關設定(`true`) - 保持點擊的狀態下拖移 - 代表移動 `mousemove event` - 因為沒有一個 `event` 是同時代表移動 + 抓取的,所以就要設定開關,用來判定現在是不是在抓的狀態 - 如果開關是開的才可以搭配移動拖曳卡片 - 關閉開關 - 什麼時候要關閉? - 非「抓」的情況,所以是滑鼠不是點擊狀態了 `mouseup` - 關閉開關(`false`) ## 操控 電腦需要知道「移動多少」以及「如何移動」。 1. 如何移動的話就可以用 CSS `position: absoulte` 來控制方位移動,此例起始只能左滑,所以使用 `left` 控制移動 2. 移動多少就比較麻煩了 - 需要起始點以及移動多少的數字 ### 起始點 因為是由整個卡片容器移動行程移動的效果,不過有要考慮到目前是否在抓取的狀態(要不然使用者就可以隨意移動了),觸發現在是抓的狀態是由 `mousedown event` 判斷,所以開始抓 = 可以移動 = 需要起始點,因此起始點也在 `mousedown event` 更新。 起始點需要由兩個數字結合,第一個是 `offestX` 知道目前滑鼠在事件元素內的 x 軸坐標為何,第二個則是 `sliderInner.offsetLeft`(`ele.offsetLeft` 會回傳一個值,代表該元素和父層元素的 x 座標相差多少)。 ### 移動多少點 在是「抓」(也就是開關為 `true`)的情況中才可以移動,移動就是 `mousemove event` 所以移動的點自然是要在 `mousemove event` 中更新。因為是用 `left` 來控制移動,`left` 如果為負數,就會造成畫面像左滑的效果了(之後右滑只是減少負數的值而已,到 0 就是不能滑,因為是起始值)。 移動多少點就要是移動的數字減掉起始點,為什麼呢?因為 `mousemove event` 是滑鼠移動就會觸發的,所以當使用者向左滑,代表移動的數字會變小,但起始點是 `mousedown event` 觸發的,在觸發時更新,所以在移動的時候起始點並不會更新(但是移動點會一直更新)。最後起始點就會 > 移動點,這個時候就會得到負數,`left` 值就會時負數,達到視覺左移的效果。 ### 起始點更新 因為左滑到最後滑鼠就會超出範圍,所以就不會有 `event` 了,此時使用者就會把滑鼠放開(關閉 `false`),移動到區塊,抓取(開 `true`),更新起始點(要加上移動多少)。 ### 設定無法再移動 1. 由左滑開始,所以一開始不能右滑,所以當卡片容器的 `left` > 0 的時候就不能右滑了(到底了)。 2. 設定左滑到底的點,電腦要知道哪裡不能再左滑了,必須提供元素之間的數字,這個時候可以使用 `ele.getBoundingClientRect()` 得到元素屬性。 - 裡面有 `right` 的屬性,代表元素右下角的座標 - 因為整個卡片容器的 `width` > 外層包覆區塊的 `width`,所以當卡片容器的 `right` < 外層包覆區塊的 `right`,最後一個卡片就會繼續移動(因為卡片容器持續向左移動) - 這個時候就可以判別卡片容器的 `right` 是不是 < 區塊的 `right`。如果是,就不要繼續移動,所以卡片容器的 `left` 就會是卡片容器的 `width` - 外層的區塊,得到的值就是 `left` 最多能為多少了(記得要變成負數)   ### 成果 [拖曳卡片](https://codepen.io/lun0223/pen/rNzoozy) [粗略地實作按鈕滑動](https://codepen.io/lun0223/pen/MWvLjVj) 後來還找到 [Swiper](https://swiperjs.com/demos)。不過我覺得至少知道實作的觀念再用套件才會心安,現在知道原理後,就可以用這個套件來快速開發了。 ## 2021/12/30 更新 結果今天上班的時候做這個東西又忘記了 XDDD,回去看同一位作者的另一套教學,實際的程式碼可以參考 [draggable scrollbar](https://codepen.io/lun0223/pen/vYedrbe?editors=0010)。 - 兩層 slider,主要是外層的 slider 移動產生移動的視覺效果 - 可以移動的區塊是初始化之外的地方,所以要求出最多可以移動多少:ele.scrollWidth - ele.clientWidth - 手刻的 scrollbar 寬度 = 顯示的寬度,所以要知道最多可以移動多少(ele.clientWidth - scrollbar 本身的寬度) - 接下來就算 slider 可以移動的地方為 scrollbar 可以移動的地方之幾倍大小,再回推 slider 移動多少才是 scrollbar 移動 1 即可  ## 參考資料 1. [Vanilla JavaScript: Create A Draggable Slider](https://www.youtube.com/watch?v=KHGc7eZyxKY&list=LL&index=4&t=27s) 2. [Element offsetLeft Property](https://www.w3schools.com/jsref/prop_element_offsetleft.asp) 3. [Element offsetParent Property](https://www.w3schools.com/jsref/prop_element_offsetparent.asp) 4. [[教學] Element.getBoundingClientRect()](https://shubo.io/get-bounding-client-rect/) 5.
×
Sign in
Email
Password
Forgot password
or
By clicking below, you agree to our
terms of service
.
Sign in via Facebook
Sign in via Twitter
Sign in via GitHub
Sign in via Dropbox
Sign in with Wallet
Wallet (
)
Connect another wallet
New to HackMD?
Sign up