来学拖拉事件自己组汉堡包~~
拖拉事件 Drag Event 指的是使用者按住滑鼠不放,移动物体到另一个位置,再放开滑鼠将物体放置他处。
按住滑鼠的事件称为 drag,放开滑鼠的事件称为 drop。
draggable
设定才可以拖拉<div draggable='true'></div>
<div ondragover="event.preventDefault()">
drag
:拖拉过程会持续触发dragstart
:拖拉时在被拖拉的节点上触发,事件的 target 指向被拖拉的节点dragend
:拖拉结束时(松开滑鼠或按下 escape 键),在被拖拉的节点上触发,事件的 target 是被拖拉的节点,与 dragstart
在同一个节点上触发。dragenter
:拖拉进当前节点时,在当前节点上触发,事件的 target 指向当前节点。dragover
:拖拉到当前节点时,在当前节点持续触发,事件的 target 为当前节点。dragleave
:拖拉离开当前节点范围时,在当前节点上触发,事件 target 为当前节点drop
:被拖拉的节点释放到目标节点时,在目标节点上触发,但若是目标节点不允许 drop 行为,即时在目标节点上松开滑鼠,也不会触发 drop 事件。由於大部分的网页区域预设不允许 drop,若要使用 drop 须取消预设行为,使用语法 event.preventDefault()
。
设定方式是使用 dragenter
和 dragover
,当侦测到物体拖拉到范围时,在监听函数内加上 event.preventDefault()
就可以允许物体 drop 到目标范围。
拖拉再 drop 有两种情况:
先来看看第二种情况,要将目标物从 a 点复制到 b 点,从 createElement
改用 Node.cloneNode()
更方便!可以完全复制目标物的 css 设定,再用 appendChild
放置到 b 的节点下就完成拷贝行为罗~
node.cloneNode(deep); // deep 参数若为 true 表示连同子节点一起复制,false 则复制自己本身
做出来的画面像这样:
codepen drop 玩玩看
那麽如果是情况一:移动目标位置呢?
发挥想像力看看,是不是很适合来个大侠自组汉堡!
汉堡包实作连结
设计想法:使用者可以依照想要的食材,自己组装汉堡。
<body>
<h1>BURGER</h1>
<div class="ingredient">
<img src='url' alt='汉堡上盖' class="target" draggable="true">
<img src='url' alt='肉' class="target" draggable="true">
<img src='url' alt='肉' class="target" draggable="true">
<img src='url' alt='番茄' class="target" draggable="true">
<img src='url' alt='汉堡下盖' class="target" draggable="true">
<img src='url' alt='青菜' class="target vagie" draggable="true">
<img src='url' alt='起司' class="target cheese" draggable="true">
</div>
<div class="assembly"></div>
</body>
JavaScript 实作:
在 document 下设定 dragstart
监听事件,每次抓取的 event.target
会指向滑鼠拖拉的元素,将元素移动到桌布范围时,使用 drop
将元素添加到桌布的节点下!
// 取节点
let get = (tag) => document.querySelector(tag);
let draggedTarget = null; // 宣告被抓取的目标物变数
// 设定抓取时的监听事件
document.addEventListener("dragstart", function (event) {
console.log("抓到目标"); // test code
draggedTarget = event.target; // 将抓取时的目标物存入变数中
});
// 设定汉堡放置区的监听事件
get(".assembly").addEventListener("drop", function (event) {
let previousIngredient = this.children[0]; // 取目前汉堡最上层材料
// 用 insertBefore ,将新抓取的材料叠在目前最上层的材料前,才可以制造汉堡往上堆叠的效果,否则用 appendChild 是变成往下叠唷!
this.insertBefore(draggedTarget, previousIngredient);
});
// 取消预设行为,才能使用 drop
document.addEventListener("dragover", function (event) {
event.preventDefault();
});
// 当没有材料时拔掉材料区
document.body.addEventListener("drop", function (event) {
if (get(".ingredient").childElementCount === 0) {
let emptyBox = get(".ingredient");
this.removeChild(emptyBox);
}
});
随着 Web API 知识增加可以玩得操作越来越多了~~~ 但碰到 css 都不小心太入迷,汉堡实作的 css 美化时间应该是写逻辑的 2 倍以上 ...
<<: [Day 27]从零开始学习 JS 的连续-30 Days---BOM-浏览器物件模型(上)
既然可以在 local 执行 E2E 了,与其占用一个 terminal 并让电脑跑,不如就交给 g...
拍手换图案 ( 二代板 ) 教学原文参考:拍手换图案 ( V2 ) 这篇文章是针对 micro:bi...
这一题题目会给我们两个Linked Lists,分别代表两个非负整数。题目要我们把两个数相加後回传一...
前言 其实分享我写题目的过程也算是一种自我检讨,所以使用的方法可能不会是最完美的,还请各读者多多包涵...
好的,昨天的星飨道是5点起床,温莎就更拚了,4点半XD 今天还是用早餐跟大家道声早安呦~~ 由於台中...