简言
dom常用事件介绍。
事件
Document: scroll event
文档视图或者一个元素在滚动时,会触发元素的 scroll 事件。由于 scroll 事件可被高频触发,事件处理程序不应该执行高性能消耗的操作,如 DOM 操作。而更推荐的做法是使用 requestAnimationFrame()、setTimeout()节流。
示例:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
</head>
<style>
* {
margin: 0;
padding: 0;
}
</style>
<body>
<div style="height: 200vh;"></div>
<script>
let last_known_scroll_position = 0;
let isCan = true
function doSomething(scroll_pos) {
// 根据滚动位置做的事
if (window.innerHeight === scroll_pos) {
alert('到底啦')
}
isCan = true
}
window.addEventListener('scroll', function (e) {
last_known_scroll_position = window.scrollY;
console.log(window);
if (isCan) {
window.requestAnimationFrame(function () {
isCan = false
doSomething(last_known_scroll_position);
});
}
});
</script>
</body>
</html>
Element: wheel event
滚轮(wheel)事件会在滚动鼠标滚轮或操作其它类似输入设备时触发。滚轮事件取代了已被弃用的非标准 mousewheel 事件。
语法
addEventListener('wheel', (event) => {});
onwheel = (event) => { };
示例:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>滚轮</title>
</head>
<body>
<div id="div" style="height:200vh">
</div>
<script>
let divDom = document.querySelector('#div')
divDom.addEventListener('wheel', (event) => {
console.log(event);
if (event.deltaY > 0) {
console.log('向下滚动');
} else {
console.log('向上滚动');
}
}, {
passive: true
})
</script>
</body>
</html>
fullscreenchange
fullscreenchange 事件当浏览器进入或离开全屏时触发。
Document.onfullscreenerror
Document.onfullscreenerror 属性是一个事件处理器用于处理 fullscreenchange 事件,在当前文档不能进入全屏模式,即使它被请求时触发。
示例:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
</head>
<style>
/* 全屏样式 */
body:fullscreen::backdrop {
width: 100vw;
height: 100vh;
background-color: skyblue;
color: #fff;
}
#id {
width: 100px;
height: 100px;
background-color: #fff;
}
</style>
<body>
<div id="div">
123
</div>
<button id="btn">全屏</button>
<script>
let flag = true
// 全屏改变
document.addEventListener("fullscreenchange", function (event) {
if (document.fullscreenElement !== null) {
console.log(document.fullscreenElement);
}
});
document.addEventListener('fulscreenerror', (e) => {
console.log('error:', e);
})
function click() {
let btnDom = document.getElementById('btn')
if (flag) {
// 全屏
flag = !flag
btnDom.textContent = '退出全屏'
document.body.requestFullscreen()
} else {
flag = !flag
btnDom.textContent = '全屏'
// 退出全屏
document.exitFullscreen()
}
}
document.getElementById('btn').addEventListener('click', click)
</script>
</body>
</html>
拖动事件
事件 | 描述 |
---|---|
drag | 在用户拖动元素或选择的文本时每几百毫秒触发一次。 |
dragend | 在拖动操作结束(通过释放鼠标按钮或按下退出键))时触发。 |
dragenter | 在拖动的元素或选择的文本进入有效的放置目标时触发。 |
dragleave | 在拖动的元素或选择的文本离开有效的放置目标时触发。 |
dragover | 在拖动的元素或选择的文本在有效的放置目标时触发(每几百毫秒)。 |
dragstart | 在用户开始拖动元素或选择的文本时触发。 |
drop | 在元素或选择的文本被放置在有效的放置目标时触发。 |
示例:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
</head>
<style>
#list {
display: flex
}
#list img {
width: 100px;
height: 150px;
margin: 0 10px;
}
#del_box {
margin-top: 200px;
width: 600px;
height: 300px;
line-height: 300px;
border: 1px dotted skyblue;
text-align: center;
vertical-align: middle;
color: #ccc;
}
</style>
<body>
<div>
<input id="file" type="file" accept="image/*">
<div>
<h4>文件列表</h4>
<div id="list">
</div>
</div>
<div id="del_box">
删除区域
</div>
</div>
<script>
// 添加图片
const fileDOM = document.getElementById('file')
const listDOM = document.getElementById('list')
fileDOM.addEventListener('change', () => {
let file = fileDOM.files[0]
const item = document.createElement('div')
const img = document.createElement('img')
// 转换成blob流
img.src = URL.createObjectURL(file)
img.draggable = true
item.appendChild(img)
listDOM.appendChild(item)
})
// 拖动删除
let isDel = false
const delDOM = document.getElementById('del_box')
listDOM.addEventListener('drop', (e) => {
e.preventDefault();
})
delDOM.addEventListener('dragover', (e) => {
e.preventDefault()
// console.log('在拖动的元素或选择的文本在有效的放置目标时触发');
})
delDOM.addEventListener('dragleave', (e) => {
e.preventDefault()
if (isDel) isDel = false
})
delDOM.addEventListener('dragenter', (e) => {
e.preventDefault()
if (!isDel) {
isDel = true
}
})
// 绑定在祖先元素就行,利用冒泡捕获机制 (事件委托)
listDOM.addEventListener('dragend', (e) => {
console.log('拖动结束');
if (isDel) {
listDOM.removeChild(e.target.parentNode)
isDel = false
}
})
listDOM.addEventListener('drag', (e) => {
console.log('drag,在拖动');
})
</script>
</body>
</html>
键盘事件
** Element: keydown event**
在某个键被按下时触发。
Element: keyup event
keyup 事件在按键被松开时触发。
keydown 和 keyup 事件提供指出哪个键被按下的代码,而 keypress 指出哪些字符被输入。例如,小写字母“a”在 keydown 和 keyup 时会被报告为 65,但在 keypress 时为 97。所有事件均将大写字母“A”报告为 65。
示例:
<input placeholder="Click here, then press and release a key." size="40">
<p id="log"></p>
const input = document.querySelector('input');
const log = document.getElementById('log');
input.addEventListener('keyup', logKey);
function logKey(e) {
log.textContent += ` ${e.code}`;
}
指针事件
事件 | 描述 |
---|---|
gotpointercapture | 在使用 setPointerCapture() 捕获元素时触发。gotpointercapture 事件是 GlobalEventHandlers 的属性,这个事件返回 gotpointercapture 类型的事件操作。 |
lostpointercapture | 在捕获指针释放时触发。 |
pointercancel | 在指针事件取消时触发。 |
pointerdown | 在指针变为活动状态时触发。 |
pointerenter | 在指针移入到元素或其子元素之一的命中测试边界时触发。 |
pointerleave | 在指针移出元素的命中测试边界时触发。 |
pointerlockchange | 在指针被锁定或解锁时触发。 |
pointerlockerror | 在指针锁定失败时触发。 |
pointermove | 在指针坐标改变时触发。 |
pointerout | 在指针移出元素的命中测试边界(或其它原因)时触发。 |
pointerover | 在指针移入元素的命中测试边界时触发。 |
pointerup | 在指针不再活动时触发。 |
示例: |
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
</head>
<body>
<div>
<p id="p">这是一段文字!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!</p>
<button onclick="clickBtn2()">锁定指针</button>
</div>
<script>
const para = document.querySelector('p');
para.addEventListener('gotpointercapture', () => {
console.log('锁定!')
});
document.addEventListener('lostpointercapture', () => {
console.log('释放!')
});
para.addEventListener('pointerdown', (event) => {
console.log('按下', event);
event.pointerId && para.setPointerCapture(event.pointerId);
});
para.addEventListener('pointermove', (event) => {
console.log('指针移动');
});
para.addEventListener('pointerup', (event) => {
console.log('指针不活动,抬起');
document.exitPointerLock();
});
para.addEventListener('pointerover', (e) => {
console.log('移入', e);
})
para.addEventListener('pointerleave', (e) => {
console.log('移出pointerleave', e);
})
para.addEventListener('pointerout', (e) => {
console.log('移出pointerout', e);
})
para.addEventListener('pointercancel', (event) => {
console.log('取消指针');
});
document.addEventListener('pointerlockchange', () => {
console.log('在指针被锁定或解锁时触发');
})
document.addEventListener('pointerlockerror', () => {
console.log('锁定失败触发');
})
// 锁定指针
function clickBtn2() {
para.requestPointerLock();
}
</script>
</body>
</html>
触摸事件
事件 | 描述 |
---|---|
touchcancel | 在一个或多个接触点以特定于实现的方式中断(例如,创建了太多的接触点)时触发。 |
touchend | 在从接触面移除一个或多个接触点时触发。 |
touchmove | 在一个或多个接触点沿接触面移动时触发。 |
touchstart | 在向接触面放置一个或多个接触点时触发。 |
示例:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>触摸事件</title>
<style>
#div {
width: 100%;
height: 100px;
background-color: skyblue;
}
</style>
</head>
<body>
<div id="div">
</div>
<script>
const divDOM = document.getElementById('div')
divDOM.addEventListener('touchcancel', (e) => {
console.log('在一个或多个接触点以特定于实现的方式中断(例如,创建了太多的接触点)时触发。', e);
})
divDOM.addEventListener('touchstart', (e) => {
console.log('在向接触面放置一个或多个接触点时触发。', e);
})
divDOM.addEventListener('touchmove', (e) => {
console.log('在一个或多个接触点沿接触面移动时触发。', e);
})
divDOM.addEventListener('touchend', (e) => {
console.log('在从接触面移除一个或多个接触点时触发。', e);
})
</script>
</body>
</html>
利用canvas和触摸事件实现移动端练字帖案例:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>触摸事件</title>
<style>
#handler {
margin: 16px;
}
#canvas {
width: 100%;
height: 80vh;
background-color: skyblue;
touch-action: none;
}
</style>
</head>
<body>
<h1 style="text-align: center;">练字帖</h1>
<div id="handler">
<button onclick="clearCanvas()">置空</button>
</div>
<canvas id="canvas">
</canvas>
<script>
const canvasDOM = document.getElementById('canvas')
// 获取canvas上下文对象
const canvas = canvasDOM.getContext('2d')
// 定义宽高
canvasDOM.width = canvasDOM.clientWidth
canvasDOM.height = canvasDOM.clientHeight
// 线宽
canvas.lineWidth = 5
// 线连接类型
canvas.lineJoin = 'round'
// 触摸开始,
canvasDOM.addEventListener('touchstart', (e) => {
// 开启新路径
canvas.beginPath()
// 获取开始点
const { clientX, clientY } = e.changedTouches[0]
const { offsetLeft, offsetTop } = e.target
const { x, y } = getXY(clientX, offsetLeft, clientY, offsetTop)
// 开始画路径
canvas.moveTo(x, y)
})
canvasDOM.addEventListener('touchmove', (e) => {
// 获取移动点
const { clientX, clientY } = e.changedTouches[0]
const { offsetLeft, offsetTop } = e.target
const { x, y } = getXY(clientX, offsetLeft, clientY, offsetTop)
// 绘制
canvas.lineTo(x, y)
canvas.stroke();
})
canvasDOM.addEventListener('touchend', (e) => {
// 获取结束点
const { clientX, clientY } = e.changedTouches[0]
const { offsetLeft, offsetTop } = e.target
const { x, y } = getXY(clientX, offsetLeft, clientY, offsetTop)
canvas.stroke();
})
function getXY(cx = 0, ol = 0, cy = 0, ot = 0) {
return {
x: cx - ol,
y: cy - ot
}
}
// 置空
const clearCanvas = () => {
canvas.clearRect(0, 0, canvasDOM.clientWidth, canvasDOM.clientHeight)
}
</script>
</body>
</html>
效果:
结语
结束了。