js event
事件的本質是程序的各組成部分之間的一種通信方式,也是異步編程的一種實現
DOM的事件觸發都是定義在EventTarget接口。所有節點對象都部署了這個接口。
該接口主要實現三個方法
addEventListenser 綁定事件的監聽函數
removeEventListener 移除事件的監聽函數
dispatchEvent 觸發事件
------------------------------
EventTarget.addEventListenser()
作用於當前節點或對象上,定義一個特定事件的監聽函數,
一旦這個事件發生,就會執行監聽函數。無返回值
addEventListenser(type, listener [, useCapture]);
三個參數
type: 事件名稱, 大小寫敏感
listener: 監聽函數。 事件發生時,會調用該監聽函數
useCapture: 布爾值,表示監聽函數是否在捕獲階段觸發
默認false(監聽函數只在冒泡階段觸發)
第二個參數除了監聽函數,還可以是一個具有handleEvent方法的對象
第三個參數除了布爾值,還可以是一個屬性配置對象,屬性有一下
{
capture: 布爾值,表示是否在捕獲節點觸發
once: 布爾,表示是否只觸發一次監聽函數,然后就自動移除
passive: 布爾值 表示監聽函數不會調用事件的preventDefult方法
}
------------------------------
EventTarget.removeEventListenser()
該方法用來移除addEventListener方法添加的事件監聽函數
eg:
div.addEventListener('click', listener, false);
div.removeEventListener('click', listener, false);
移除的監聽函數必須是添加的同一個監聽函數,而且必須是在同一個節點元素,】
否在無效
//無效的移除函數 因為部署同一個監聽函數
div.addEventListener('click', function (e) {}, false);
div.removeEventListener('click', function (e) {}, false);
//無效的移除函數 因為第三個參數不一樣,移除的一個是捕獲節點 一個是冒泡階段
element.addEventListener('mousedown', handleMouseDown, true);
element.removeEventListener("mousedown", handleMouseDown, false);
------------------------------
EventTarget.dispatchEvent()
在當前節點觸發指定事件
返回布爾,只有存在一個監聽函數調用了Event.preventDefault(),
則返回值為false, 否則為true
dispatchEvent方法的參數是一個Event對象
<!DOCTYPE html>
<html>
<head>
<meta charset='utf-8'>
<meta http-equiv='X-UA-Compatible' content='IE=edge'>
<title>EventTarget</title>
</head>
<body>
<button id='btn'>事件冒泡觸發</button>
</body>
<script>
function hello1() {
console.log('hello world1');
}
function hello2() {
console.log('hello world2');
}
var hello = {
handleEvent: function(event) {
event.preventDefault();
console.log('hello world');
}
};
var useCapture = {
capture: false
//once: true,
//passive: true
};
// useCapture: 布爾值,表示監聽函數是否在捕獲階段觸發 默認false(監聽函數只在冒泡階段觸發)
var btn = document.getElementById('btn');
// 可以添加多了不同的監聽函數,按照添加順序觸發,
// 但是如果多次添加的是同一個函數,只會觸發一次
// btn.addEventListener('click', hello1, useCapture);
// btn.addEventListener('click', hello1, useCapture);
// btn.addEventListener('click', hello2, useCapture);
btn.removeEventListener('click', hello1, false);
// btn.removeEventListener('click', hello2, false);
//div.removeEventListener('click', function (e) {}, false);
//觸發一次點擊事件
var event = new Event('click');
// btn.dispatchEvent(event);
var canceled = !btn.dispatchEvent({});
if (canceled) {
console.log('事件取消');
} else {
console.log('事件未取消');
}
</script>
</html>
拖拉事件
為了讓元素節點可拖拉,可以將該節點的draggable屬性設為true。
當元素節點或選中的文本被拖拉時,就會持續觸發拖拉事件,包括以下一些事件。
drag:拖拉過程中,在被拖拉的節點上持續觸發(相隔幾百毫秒)。
dragstart:用戶開始拖拉時,在被拖拉的節點上觸發,該事件的target屬性是被拖拉的節點。
通常應該在這個事件的監聽函數中,指定拖拉的數據。
dragend:拖拉結束時(釋放鼠標鍵或按下 ESC 鍵)在被拖拉的節點上觸發,
該事件的target屬性是被拖拉的節點。它與dragstart事件,在同一個節點上觸發。
不管拖拉是否跨窗口,或者中途被取消,dragend事件總是會觸發的。
dragenter:拖拉進入當前節點時,在當前節點上觸發一次,該事件的target屬性是
當前節點。通常應該在這個事件的監聽函數中,指定是否允許在當前節點放下(drop
)拖拉的數據。如果當前節點沒有該事件的監聽函數,或者監聽函數不執行任何操作,
就意味着不允許在當前節點放下數據。在視覺上顯示拖拉進入當前節點,也是在這個
事件的監聽函數中設置。
dragover:拖拉到當前節點上方時,在當前節點上持續觸發(相隔幾百毫秒),
該事件的target屬性是當前節點。該事件與dragenter事件的區別是,dragenter
事件在進入該節點時觸發,然后只要沒有離開這個節點,dragover事件會持續觸發。
dragleave:拖拉操作離開當前節點范圍時,在當前節點上觸發,該事件的target
屬性是當前節點。如果要在視覺上顯示拖拉離開操作當前節點,就在這個事件的監
聽函數中設置。
drop:被拖拉的節點或選中的文本,釋放到目標節點時,在目標節點上觸發。注意,
如果當前節點不允許drop,即使在該節點上方松開鼠標鍵,也不會觸發該事件。如果
用戶按下 ESC 鍵,取消這個操作,也不會觸發該事件。該事件的監聽函數負責取出
拖拉數據,並進行相關處理。
瀏覽器原生提供一個DragEvent()構造函數,用來生成拖拉事件的實例對象。
new DragEvent(type, options)
第一個參數是字符串,表示事件的類型 必須
第二個參數是事件的配置對象 可選
<!DOCTYPE html>
<html>
<head>
<meta charset='utf-8'>
<meta http-equiv='X-UA-Compatible' content='IE=edge'>
<title>EventTarget</title>
</head>
<body>
<div id='nodeDrag' draggable="true" style="background-color: aqua;">
此區域可拖拽
</div>
<div style="background-color: aqua;">
此區域可拖拽
</div>
<div class="dropZone">1
<div id='draggable' draggable="true">
此節點可拖拽
</div>
</div>
<div class="dropZone">2
</div>
<div class="dropZone">3
</div>
<div class="dropZone">4
</div>
</body>
<script>
var node = document.getElementById('nodeDrag');
node.addEventListener('dragstart', function (e) {
this.style.backgroundColor = 'red';
}, false);
node.addEventListener('dragend', function (e) {
this.style.backgroundColor = 'green';
}, false);
// 被拖拉節點
var dragged;
document.addEventListener('dragstart', function(event) {
dragged = event.target;
event.target.style.opacity = 0.5;
}, false);
document.addEventListener('dragend', function(event) {
event.target.style.opacity = 1;
}, false);
document.addEventListener('dragover', function(event) {
event.preventDefault();
}, false);
document.addEventListener('dragenter', function (event) {
// 目標節點的背景色變紫色
// 由於該事件會冒泡,所以要過濾節點
if (event.target.className === 'dropZone') {
event.target.style.background = 'red';
}
}, false);
document.addEventListener('dragleave', function( event ) {
// 目標節點的背景色恢復原樣
if (event.target.className === 'dropZone') {
event.target.style.background = '';
}
}, false);
document.addEventListener('drop', function( event ) {
// 防止事件默認行為(比如某些元素節點上可以打開鏈接),
event.preventDefault();
if (event.target.className === 'dropZone') {
// 恢復目標節點背景色
event.target.style.background = '';
// 將被拖拉節點插入目標節點
dragged.parentNode.removeChild(dragged);
event.target.appendChild( dragged );
}
}, false);
</script>
</html>
