沃草這哪招 已發佈 2019-11-26
最近時不時的就可以看到 Pokemon GO 的廣告在電視、網路媒體上出現,這波行銷宣傳打的可真兇哪!
回想起小時候那個寶可夢還叫做神奇寶貝的年代(遠目...),為了每週六晚上的寶可夢卡通,客廳必定會上演的遙控器搶奪戰;不然就是在學校上課偷打寶可夢 Game Boy 的美好歲月,那些都是我一去不復返的童年時光啊~(喂喂喂,扯遠了!)
咳咳,回歸正題,為了紀念一下那逝去的美好,於是就用寶可夢最迷人的特點「進化」為題,寫了一個互動操作效果,用滑鼠拖動進化石到伊布身上來進化牠(如圖)
這種可以用拖曳的方式來移動進化石的操作,叫做「拖曳效果」。而以下就簡單的介紹「拖曳效果」是怎麼做出來的吧!
也可以點此「進化吧,寶可夢!」自己操作看看唷
好啦,我知道要進化太陽精靈和月精靈不是用進化石,但這不是重點請忽略它╮(′~‵〞)╭
Ps:除了拖曳外,其他大部分的效果都是偽元素的應用,想更了解偽元素可以點此全都是假的,一起來認識偽元素!
在以前的時候,據說要製作出這種拖曳效果是非常不容易的事,得要有一大堆的語法配合才能實現這種效果。但在現在最新的 HTML5 中,已經有直接的 Drag 與 Drop 機制,讓我們得以用更簡潔的方式來實現出拖曳的效果,真的是瞬間便利了不少啊!
在 HTML5 中提供了多種可用來觸發拖曳的監聽事件,這些事件所監聽的對象大致上可分為 Drag Source 和 Drop Target 兩種。
Drag Source 和 Drop Target 兩種監聽對象的事件有不少,以下列舉這次範例使用到的幾個,也是比較常運用的幾個監聽事件:
好了,關於 Drag 與 Drop 機制的基礎認識就先到這邊,接下來,我們就一步一步地來說明該怎麼運用 Drag 與 Drop 囉!
一般來說,除了 <a>
和 <img>
這兩個元素之外,其他的 HTML 的元素都是預設為不可被拖曳的。但在 HTML5 中只要添加上 draggable="true"
這個屬性之後,它就可以「被拖曳」囉。
因此製作拖曳效果的第一個步驟,便是先對要被拖曳的元素, 加上 draggable="true"
這個屬性,如下:
<div id="element" draggable="true">拖曳對象</div>
<div id="container">放置目標</div>
好了,現在 element 這個元素已經被設定為「可拖曳」的狀態了,那麼接下來的第二個步驟,便是要運用 JavaScript 對 element 這個元素設置監聽事件,如此一來,當 user 在使用滑鼠拖曳時,才能觸發相應的拖曳效果。
dragstart
這個監聽事件:
let el = document.querySelector('#element');
el.addEventListener('dragstart', dragStart);
function dragStart(e) {
e.dataTransfer.setData('text/plain', e.target.id)
};
OK ,有關於「拖曳對象」的設定先到這邊,接下來要進行的是「放置目標」部分的設置。
在正常的狀況下,元素是不能被放置拖曳物的,因此我們得要用 JavaScript 針對要放置拖曳物的元素進行一些設定,好讓這個元素變成可以放置拖曳物的「容器」。
dragenter
、 dragover
和 drop
三個監聽事件:
let container = document.querySelector('#container');
container.addEventListener('drop', dropped);
container.addEventListener('dragenter', cancelDefault);
container.addEventListener('dragover', cancelDefault);
function dropped(e) {
cancelDefault(e)
let id = e.dataTransfer.getData('text/plain');
e.target.appendChild(document.querySelector(`#${id}`));
};
function cancelDefault(e) {
e.preventDefault();
e.stopPropagation();
return false
};
在放置目標的「容器」可以設置很多個,我們甚至可以改用 class 選擇器來做 JavaScript 的設定:
<div class="container"></div>
<div class="container"></div>
<div class="container"></div>
let container = document.querySelectorAll('.container');
// 用 forEach 來做多個 class 的監聽事件綁定
container.forEach(container => {
container.addEventListener('drop', dropped);
container.addEventListener('dragenter', cancelDefault);
container.addEventListener('dragover', cancelDefault);
})
另外一提的是,同一個選擇器是無法設置多個「拖曳物件」的喔,這點要特別要注意!
只要運用上面的語法,再加上一點 CSS 的設定後,就可以做出如下圖的效果囉!
觀看完整程式碼可點擊此處!
在上面範例中有運用到了一些不是很常見的語法,所以在這邊做一個小統整,不過因為這每一個項目都可以再寫一篇文章了,所以這邊只做個簡單介紹,想知道更詳盡的內容的話可以自行 Google 一下囉。
一開始接觸 Drag 與 Drop 機制的時候可能會覺得有點小複雜,但是如果能弄清楚他的各種監聽事件與原理,其實這個效果要實作出來並不算太難。那麼,以上就是有關拖曳效果的簡單介紹囉!
暱稱:沃草這哪招
介紹:沒時間解釋了,快上車!