iT邦幫忙

2018 iT 邦幫忙鐵人賽
DAY 27
0

Day27-課題內容

JS30 進入倒數第四天,在今天的課題中,我們的目標是做出可以拖曳的目錄效果。[1]
實作連結

進入課題

要做出拖曳的功能,我們要結合目前為止學過的幾種技能:

  1. 滑鼠事件
  2. 滑鼠位置
  3. 元素捲動

滑鼠事件

我們要在滑鼠按下的時候,內容可以隨著鼠標移動的多寡而捲動,並讓放開滑鼠的時候停止。除此之外,我們也要避免滑鼠移出捲動目標的時候還持續捲動,因此我們監聽了四個事件:

const items = document.querySelector('.items');
items.addEventListener('mousedown', startToDrag);
items.addEventListener('mousemove', Dragging);
items.addEventListener('mouseup', stopDragging);
items.addEventListener('mouseleave', stopDragging);

這邊特別比較一下 onmouseenteronmouseleaveonmouseoveronmouseout ,這些為滑鼠移入移出時觸發的事件種類:

  1. onmouseenter:當滑鼠移入指定的元素,此事件會被觸發。
  2. onmouseleave:當滑鼠移出指定的元素,此事件會被觸發。
  3. onmouseover:當滑鼠移入指定的元素或其子元素們,此事件會被觸發。
  4. 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');
};

總結

在今天的課題中,我們複習了之前課題中所使用的技能,並透過組合這些功能,做出能夠拖曳捲動的效果,相信大家也對這些技能的使用越來越得心應手囉!

參考資料

  1. javascript30

上一篇
JS30-Day26-Stripe Follow Along Nav
下一篇
JS30-Day28-Video Speed Controller
系列文
新手也能懂的JS3030
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言