Skip to content

属性/事件(鼠标键盘)

元素

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

Copyright © 2026 Luke