属性/事件(鼠标键盘)
元素
ts
/* 设置自定义属性 */
1. 元素.setAttribute((属性名), (属性值));
/* insertBefore ---> 把li插入到ul的ul.children[0]之前 */
2. ul.insertBefore(li, ul.children[0]);
3. document.documentElement.clientWidth ---> 获取可视窗口的宽度
document.documentElement.clientHeight ---> 获取可视窗口的高度window
ts
1. 获取滚动条滚动的距离
1). document.documentElement.scrollTop 或 document.querySelector("div").scrollTop
2). window.pageYoffset ---> Y轴滚动条
3). window.pageXoffset ---> X轴滚动条
2. window.close() --- 关闭当前页面鼠标
核心鼠标事件类型
| 事件类型 | 触发时机 | 常用场景 |
|---|---|---|
| 点击类 | ||
| dblclick | 鼠标左键双击触发 | 双击编辑、文件打开 |
| mousedown | 鼠标任意按键按下时触发(左 / 中 / 右) | 拖拽开始、按住操作 |
| mouseup | 鼠标任意按键松开时触发(左 / 中 / 右) | 拖拽结束、释放操作 |
| contextmenu | 鼠标右键单击(触发上下文菜单) | 自定义右键菜单 |
| 移动类 | ||
| mousemove | 鼠标在元素内移动时持续触发 | 拖拽跟踪、鼠标位置监听 |
| mouseover | 鼠标移入元素(含子元素)时触发 | 悬浮提示(会冒泡) |
| mouseenter | 鼠标移入元素(不含子元素)时触发 | 悬浮样式(不冒泡,推荐) |
| mouseout | 鼠标移出元素(含子元素)时触发 | 悬浮恢复(会冒泡) |
| mouseleave | 鼠标移出元素(不含子元素)时触发 | 悬浮恢复(不冒泡,推荐) |
| 滚动类 | ||
| wheel | 鼠标滚轮滚动时触发(上下 / 左右) | 自定义滚动逻辑、防滚动穿透 |
| 其他 | ||
| drag | 元素被拖拽时持续触发 | 拖拽过程跟踪 |
| dragstart | 元素开始被拖拽时触发 | 拖拽初始化 |
| dragend | 元素拖拽结束时触发 | 拖拽收尾 |
| drop | 拖拽元素释放到目标元素时触发 | 拖拽放置逻辑 |
🔑 关键区别
mouseenter/mouseleave 不冒泡;
mouseover/mouseout 会冒泡(子元素触发会传递到父元素)
因此做悬浮交互时优先用 mouseenter/mouseleave。
鼠标事件对象核心属性
| 属性 | 作用 |
|---|---|
e.clientX/e.clientY | 鼠标相对于可视窗口的坐标(不含滚动条偏移) |
e.pageX/e.pageY | 鼠标相对于文档的坐标(含滚动条偏移,常用) |
e.screenX/e.screenY | 鼠标相对于电脑屏幕的坐标 |
e.offsetX/e.offsetY | 鼠标相对于触发元素的内部坐标(元素左上角为 0) |
| e.button | 按下的鼠标按键:0 = 左键,1 = 中键,2 = 右键(mousedown/mouseup 有效) |
e.ctrlKey/e.shiftKey/e.altKey | 按下按键时是否按住 Ctrl/Shift/Alt 键(组合操作) |
| e.target | 触发事件的原始元素(事件冒泡时不变) |
| e.currentTarget | 绑定事件的当前元素(事件冒泡时为当前处理元素) |
| e.preventDefault() | 阻止默认行为(如右键菜单、链接跳转) |
| e.stopPropagation() | 阻止事件冒泡(如子元素点击不触发父元素事件) |
常见示例
获取鼠标位置
vue
<template>
<div id="box" style="width: 300px; height: 200px; border: 1px solid #000;"></div>
<p id="pos"></p>
</template>
<script>
const box = document.getElementById('box');
const pos = document.getElementById('pos');
box.addEventListener('mousemove', (e) => {
pos.innerHTML = `
相对于文档:${e.pageX}, ${e.pageY}<br>
相对于元素:${e.offsetX}, ${e.offsetY}<br>
相对于窗口:${e.clientX}, ${e.clientY}
`;
});
</script>自定义右键菜单
vue
<template>
<div id="customMenu" style="display: none; position: absolute; width: 120px; background: #fff; border: 1px solid #ccc; padding: 5px;">
<div>复制</div>
<div>粘贴</div>
<div>删除</div>
</div>
</template>
<script>
const menu = document.getElementById('customMenu');
// 禁用默认右键菜单
document.addEventListener('contextmenu', (e) => {
e.preventDefault();
// 定位自定义菜单到鼠标位置
menu.style.left = `${e.pageX}px`;
menu.style.top = `${e.pageY}px`;
menu.style.display = 'block';
});
// 点击空白处关闭菜单
document.addEventListener('click', () => {
menu.style.display = 'none';
});
</script>鼠标拖拽元素
核心
mousedown 记录初始位置 → mousemove 计算偏移 → mouseup 停止监听
vue
<template>
<div id="dragBox" style="width: 100px; height: 100px; background: red; position: absolute; cursor: move;"></div>
</template>
<script>
const dragBox = document.getElementById('dragBox');
let isDragging = false;
let startX, startY;
// 按下鼠标:开始拖拽
dragBox.addEventListener('mousedown', (e) => {
isDragging = true;
// 记录鼠标相对于元素的初始位置
startX = e.offsetX;
startY = e.offsetY;
dragBox.style.opacity = '0.8'; // 视觉反馈
});
// 移动鼠标:更新位置(绑定到document,避免鼠标移出元素中断)
document.addEventListener('mousemove', (e) => {
if (!isDragging) return;
// 计算元素新位置:鼠标文档坐标 - 初始偏移
const x = e.pageX - startX;
const y = e.pageY - startY;
dragBox.style.left = `${x}px`;
dragBox.style.top = `${y}px`;
});
// 松开鼠标:结束拖拽
document.addEventListener('mouseup', () => {
if (isDragging) {
isDragging = false;
dragBox.style.opacity = '1';
}
});
</script>监听鼠标滚轮方向
ts
/* 鼠标滚轮事件 */
window.onwheel = (e) => {
if(e.wheelDeltaY > 0){
console.log("往上滚动");
} else {
console.log("往下滚动");
}
}
--------- 或 ---------
document.addEventListener('wheel', (e) => {
// e.deltaY > 0 向下滚动,< 0 向上滚动
if (e.deltaY > 0) {
console.log('滚轮向下');
} else {
console.log('滚轮向上');
}
// 阻止默认滚动(如页面不跟随滚轮滚动)
// e.preventDefault();
});区分左键 / 右键 / 中键点击
ts
document.addEventListener('mousedown', (e) => {
switch(e.button) {
case 0:
console.log('左键按下');
break;
case 1:
console.log('中键按下(滚轮点击)');
break;
case 2:
console.log('右键按下');
break;
}
});注意事项
事件冒泡
提示
click、mousedown 等事件会冒泡到父元素,如需阻止可调用 e.stopPropagation()。
ts
// 示例:子元素点击不触发父元素事件
const parent = document.getElementById('parent');
const child = document.getElementById('child');
parent.addEventListener('click', () => console.log('父元素点击'));
child.addEventListener('click', (e) => {
e.stopPropagation(); // 阻止冒泡
console.log('子元素点击');
});拖拽事件的兼容性
提示
原生拖拽(drag/drop)需给元素设置 draggable="true",且 drop 事件触发前需阻止 dragover 的默认行为:
ts
const dropTarget = document.getElementById('dropTarget');
dropTarget.addEventListener('dragover', (e) => {
e.preventDefault(); // 必须阻止默认行为,否则drop不触发
});
dropTarget.addEventListener('drop', (e) => {
console.log('元素拖入目标');
});鼠标位置的兼容性
提示
pageX/pageY 在 IE 低版本中需兼容(可通过 clientX + document.documentElement.scrollLeft 计算)。
ts
let timer = null;
document.addEventListener('mousemove', (e) => {
if (timer) clearTimeout(timer);
timer = setTimeout(() => {
// 执行复杂逻辑(如更新DOM)
console.log('鼠标位置:', e.pageX, e.pageY);
}, 16); // 约60帧/秒
});性能优化
提示
mousemove 触发频率极高,如需复杂逻辑,可通过「节流」减少触发次数
ts
let timer = null;
document.addEventListener('mousemove', (e) => {
if (timer) clearTimeout(timer);
timer = setTimeout(() => {
// 执行复杂逻辑(如更新DOM)
console.log('鼠标位置:', e.pageX, e.pageY);
}, 16); // 约60帧/秒
});键盘
ts
// 方式1:addEventListener(推荐,支持多事件绑定)
document.addEventListener('keydown', handleKeyDown);
document.addEventListener('keyup', handleKeyUp);
// 方式2:直接赋值(仅能绑定一个事件)
// document.onkeydown = handleKeyDown;
// 事件处理函数
function handleKeyDown(e) {
console.log('按键按下:', {
key: e.key, // 按键名称(如 'a'、'Enter'、'ArrowUp')
code: e.code, // 按键编码(如 'KeyA'、'Enter'、'ArrowUp')
keyCode: e.keyCode,// 按键ASCII码(已废弃,如 65 对应 A,13 对应 Enter)
altKey: e.altKey, // 是否按住 Alt
ctrlKey: e.ctrlKey,// 是否按住 Ctrl
shiftKey: e.shiftKey,// 是否按住 Shift
metaKey: e.metaKey // 是否按住 Windows/Command 键
});
// 阻止默认行为(如禁用回车提交表单、禁用方向键滚动)
// e.preventDefault();
}
function handleKeyUp(e) {
console.log('按键松开:', e.key);
}
// 移除事件监听(需保留函数引用)
// document.removeEventListener('keydown', handleKeyDown);表单
ts
监听滚动条移动事件 ---> scroll
获取焦点 ---> focus
失去焦点 ---> blur
监听表单值发生变化 ---> change