今天要來做的是滑鼠拖拉事件,點選笑臉圖片可以把它拖放到空的正方形中,
background-color
會變成灰色,border
為虛線知識點 | 使用說明 |
---|---|
HTML Global Attributes | 加入dragable 屬性,使元素可被拖動 |
知識點 | 使用說明 |
---|---|
@media query | 在此設定較小視窗要直向排列 |
background | 縮寫屬性,設置背景圖片、位置等 |
知識點 | 使用說明 |
---|---|
dragEvent | 定義托放的事件物件 |
querySelectorAll | 回傳nodeList,獲取HTML元素 |
querySelector | 返回第一個符合特定選擇器的元素 |
for of | 在此迭代未被填滿的正方形 |
this | 在一般function和箭頭函式內使用 |
setTimeout | 某段時間後執行某個函式(一次) |
<div>
,其中一個加上一些預設的class="fill hold",draggable
屬性設為true <div class="square">
<div class="fill" draggable="true"></div>
</div>
<div class="square"></div>
<div class="square"></div>
<div class="square"></div>
<div class="square"></div>
* {
box-sizing: border-box;
}
body {
background-color: steelblue;
margin: 0;
padding: 0;
display: flex; /*讓內容水平垂直置中*/
justify-content: center;
align-items: center;
height: 100vh;
overflow: hidden;
}
正方形相關
.square {
background-color: white;
height: 150px;
width: 150px;
margin: 10px;
border: 3px solid black;
}
/* 圖片填滿狀態 */
為了讓圖片不要蓋住邊框,所以寬和高稍微設小一點
.fill {
background: url("...") no-repeat center/ cover black ; /*一般會在最後加入背景色,以防圖片沒顯示*/
cursor: pointer;
width: 145px;
height: 145px;
}
/* 滑鼠按壓不放時的狀態 */
.hold {
border: 3px dashed black;
}
/* 圖片經過正方形時,正方形的狀態 */
.hover {
background-color: gray;
border: 3px dashed white;
}
HTML、CSS設定好,呈現如下圖,圖片加減看XD 因沒辦法截到滑鼠游標,圖片因為draggable
設為true的關係,讓滑鼠游標可拖曳,你可以試試看false和auto(預設,根據瀏覽器的默認行為)會有甚麼效果
dragstart
開始拖動元素或文本選擇時會觸發此事件dragend
拖動操作結束(釋放鼠標按鈕或按下退出鍵)時會觸發此事件dragover
滑鼠拖動元素或文本選擇並經過有效的放置目標上時,會連續觸發此事件dragenter
拖動的元素或文本選擇進入有效的放置目標時會觸發此事件。dragleave
拖動的元素或文本選擇離開有效的放置目標時會觸發此事件。drop
當元素被放置在有效放置目標上時會觸發此事件。注意注意!!以上事件都沒有使用camel case,都是小寫
認識了拖拉事件的類型,為這個賽project畫了一個流程圖,如下:
定義拖拉function
整個行為是我們會在特定的時間觸發拖拉事件,所以先把有關的拖拉事件function寫好,console.log印出來是為了幫助我們理解事件觸發的順序和時間點
// 開始
function dragStart() {
console.log("drag start");
}
// 拖動一個元素
function dragOver() {
console.log("drag over");
}
// 拖動進入某個東西裡
function dragEnter() {
console.log("drag enter");
}
// 拖動離開某個東西
function dragLeave() {
console.log("drag leave");
}
// 放下
function dragDrop() {
console.log("drag drop");
}
// 結束
function dragEnd() {
console.log("drag end");
}
接著,我們看底下這張圖,根據行為區分,我們可以把元素大致上區分為填滿和未填滿,
變數宣告
let fill = document.querySelector(".fill"); //填滿
let square = document.querySelectorAll(".square"); //未填滿
事件監聽
//填滿
fill.addEventListener("dragstart", dragStart);
fill.addEventListener("dragend", dragEnd);
//未填滿
for (let element of squares) {
console.log(element); //squares變數裡的每個元素
element.addEventListener("dragover", dragOver);
element.addEventListener("dragenter", dragEnter);
element.addEventListener("dragleave", dragLeave);
element.addEventListener("drop", dragDrop);
}
了解了事件的觸發點後,我們回到一開始定義拖拉function的地方,稍作修改
// 開始
function dragStart() {
console.log("drag start");
this.className += " hold";
setTimeout(() => (this.className = "invisible"), 0);
}
// 拖動一個元素
function dragOver(e) {
console.log("drag over");
e.preventDefault();
}
// 拖動進入某個東西裡
function dragEnter(e) {
console.log("drag enter");
e.preventDefault();
this.className += " hover";
}
// 拖動離開某個東西
function dragLeave() {
console.log("drag leave");
this.className = "square";
}
// 放下
function dragDrop() {
console.log("drag drop");
this.className = "square";
this.append(fill);
}
// 結束
function dragEnd() {
console.log("drag end");
this.className = "fill";
}
附上codepen連結 https://codepen.io/hangineer/pen/VwxMNom
若有解說不夠詳盡或是錯誤歡迎指教,感激不盡!
50 Projects In 50 Days - HTML, CSS & JavaScript
HTML Drag and Drop API
DragEvent