JS30 進入倒數第四天,在今天的課題中,我們的目標是做出可以拖曳的目錄效果。[1]
實作連結
要做出拖曳的功能,我們要結合目前為止學過的幾種技能:
我們要在滑鼠按下的時候,內容可以隨著鼠標移動的多寡而捲動,並讓放開滑鼠的時候停止。除此之外,我們也要避免滑鼠移出捲動目標的時候還持續捲動,因此我們監聽了四個事件:
const items = document.querySelector('.items');
items.addEventListener('mousedown', startToDrag);
items.addEventListener('mousemove', Dragging);
items.addEventListener('mouseup', stopDragging);
items.addEventListener('mouseleave', stopDragging);
這邊特別比較一下 onmouseenter
及 onmouseleave
與 onmouseover
及 onmouseout
,這些為滑鼠移入移出時觸發的事件種類:
onmouseenter
:當滑鼠移入指定的元素,此事件會被觸發。onmouseleave
:當滑鼠移出指定的元素,此事件會被觸發。onmouseover
:當滑鼠移入指定的元素或其子元素們,此事件會被觸發。onmouseout
:當滑鼠移出指定的元素或其子元素們,此事件會被觸發。從作者給的草稿當中,我們可以看到這次捲動的頁面,是由一容器包含許多子元素組合而成。因此經由前面的經驗判斷,這邊我們會使用 clientX
這個屬性,而不是使用 offsetX
這個屬性。可以參考第十六天的內容JS30-Day16-Mouse Move Shadow,了解這兩種屬性的差異。
在第十三天的課題JS30-Day13-Slide in on Scroll當中,我們也介紹了 onscroll
事件與其相關屬性,在今天的課題中,我們要使用到元素 X軸的捲動量,因此使用的方法為 element.scrollLeft
。
在 onmousedown
觸發的函示中,我們要取得滑鼠當下的位置,並打開元素隨著滑鼠移動而捲動的開關,並且透過加上 class
來產生特效:
const items = document.querySelector('.items');
//給定一變數代表目前滑鼠在X軸上的位置
let xCoord = 0;
//給定一變數代表捲動開關
let mouseSwitch = false;
function startToDrag (event) {
//啟動元素捲動的開關
mouseSwitch = true;
//取得滑鼠點擊時在頁面上的位置並加上先前的捲動量
xCoord = event.clientX + items.scrollLeft;
//將元素加上含有 CSS 特效屬性的 class
items.classList.add('active');
};
而在 onmousemove
觸發的函示中,當捲動的開關為開啟時,元素內容捲動的量,就要跟我們滑鼠移動的量相同。而滑鼠後來總共捲動的量為原本的座標,減去後來移動到的位置:
function Dragging (event) {
//當捲動開關開啟時
if (mouseSwitch === true) {
//元素內容捲動的量為原本的位置減去後來的位置
items.scrollLeft = xCoord - event.clientX;
};
};
當我們放開滑鼠時,則要關掉捲動開關,並移除特效 class
:
function stopDragging () {
mouseSwitch = false;
items.classList.remove('active');
};
在今天的課題中,我們複習了之前課題中所使用的技能,並透過組合這些功能,做出能夠拖曳捲動的效果,相信大家也對這些技能的使用越來越得心應手囉!