JS DOM编程笔记 - 详解鼠标事件(十六)

JS DOM编程笔记 - 详解鼠标事件(十六)

今天我们来学习 JavaScript 中的基本鼠标事件及其属性,包括9个鼠标事件和一些有用的事件对象的属性。

Mouse 鼠标事件介绍

当我们使用鼠标与页面上的元素进行交互时就会触发鼠标事件,DOM 3级定义了九个鼠标事件。

mousedown , mouseup click

当我们点击一个元素时,会按照下面顺序触发至少3个鼠标事件

  1. 当我们在元素上按下鼠标时, mousedown 会触发
  2. 当我们在元素上松开鼠标时, mouseup 会触发。
  3. 当元素触发了一个 mousedown 和一个 mouseup ,就会触发 click 事件

如果在元素上按下鼠标并将鼠标移开该元素,然后松开鼠标,那么 mousedown 事件会触发。

同样,如果按下鼠标,然后将鼠标移动到元素上,然后松开鼠标,则元素将触发唯一的 mouseup 事件。

在这两种情况下, click 事件都不会触发。

dblclick

在实际项目中,很少会用到 dblclick 事件, dblclick 事件会在双击一个元素时触发。

触发 dblclick 事件需要两个点击事件,将按以下顺序触发事件:

  1. mousedown
  2. mouseup
  3. click
  4. mousedown
  5. mouseup
  6. click
  7. dblclick

从上面的顺序可以看到, click 事件总是在 dblclick 事件之前触发。

mousemove

当我们在元素周围移动鼠标光标时, mousemove 事件会重复触发。哪怕只移动一个像素, mousemove 事件仍然会触发。它会导致页面变慢,因此,仅在需要时才去监听 mousemove 事件,并在不再使用时立即删除该事件,如下:

element.onmousemove = mouseMoveEventHandler;
// ...
//  不再使用, 清除事件处理程序
element.onmousemove = null;

mouseover / mouseout

mouseover 在鼠标光标位于元素外然后移动到元素内时触发。

mouseout 在鼠标光标悬停在一个元素上然后移动另一个元素时触发。

mouseenter / mouseleave

mouseenter 在鼠标光标位于元素外部时触发,然后移动到元素内部。

mouseleave 在鼠标光标悬停在元素上时触发,然后移动到元素的外部。

mouseenter mouseleave 都不会冒泡,也不会在鼠标光标移动到后代元素上时触发。

监听鼠标事件

要监听鼠标事件:

  • 首先,使用 querySelector() getElementById() 方法选择元素。
  • 然后,使用 addEventListener() 方法来绑定鼠标事件。

比如为下面的按钮来绑定事件:

<button id="btn">点我点我!</




    
button>
<script>
  let btn = document.querySelector('#btn');
  btn.addEventListener('click',(event) => {
    console.log('点击了');
</script>

同样也可以使用DOM属性绑定事件处理程序

let btn = document.querySelector('#btn');
btn.onclick = (event) => {
  console.log('点击了');

在一些老项目中,也会直接在HTML属性上绑定事件处理程序

<button id="btn" onclick="console.log('点击了')">点我点我!</button>

最佳实践是我们要使用 addEventListener() 方法来绑定事件

检测鼠标按钮

鼠标事件处理程序的事件对象有一个 button 属性,它表示在鼠标上按下哪个鼠标按钮来触发事件。

鼠标按钮由一个数字表示:

  • 0:按下鼠标左键。
  • 1:按下中键或滚轮键。
  • 2:按下右键。
  • 3:按下第四个按钮,通常是浏览器返回按钮。
  • 4:按下第五个按钮,通常是浏览器前进按钮。

看下面的例子:

<!DOCTYPE html>
  <title>JS Mouse事件例子</title>
</head>
  <button id="btn">用任何鼠标按钮单击我,左、中、右键。</button>
  <p id="message"></p>
  <script>
    let btn = document.querySelector('#btn');
    // 点击鼠标右键时禁用上下文菜单
    btn.addEventListener('contextmenu', (e) => {
      e.preventDefault();
    // 展示鼠标事件的信息
    btn.addEventListener('mouseup', (e) => {
      let msg = document.querySelector('#message');
      switch (e.button) {
        case 0:
          msg.textContent = '左键点击.';
          break;
        case 1:
          msg.textContent = '中键点击.';
          break;
        case 2:
          msg.textContent = '右键点击.';
          break;
        default:
          msg.textContent = `未找到button代码: ${event.button}`;
  </script>
</body>
</html>

修饰键

当点击一个元素时,我们可以按下一个或多个修饰键:Shift、Ctrl、Alt 或 Meta。

Meta 键是 Windows 键盘上的 Windows 键或者 Mac 键盘上的 Command 键。

要检测这些修饰键是否被按下,可以使用鼠标事件处理程序的事件对象。

事件对象有四个布尔属性,如果指定键被按下,那么属性就会为 true,如果键没有被按下,则设置为 false。

看下面的例子:

<!DOCTYPE html>
  <title>JS 修饰键例子</title>
</head>
  <button id="btnKeys">按住 Alt、Shift、Ctrl 键点击我</button>
  <p id="messageKeys"></p>
  <script>
    let btnKeys = document.querySelector('#btnKeys');
    btnKeys.addEventListener('click', (e) => {
      let keys = [];
      if (e.shiftKey) keys.push('shift');
      if (e.ctrlKey) keys.push('ctrl');
      if (e.altKey) keys.push('alt');
      if (e.metaKey) keys.push('meta');
      let msg = document.querySelector('#messageKeys');
      msg.textContent = `修饰键: ${keys.join('+')}`;
  </script>
</body>
</html>

获取屏幕坐标

鼠标事件的事件对象的 screenX screenY 属性返回鼠标位置相对于整个屏幕的屏幕坐标。

clientX clientY 属性返回浏览器中鼠标事件发生处的水平和垂直坐标:

看下面的例子:

<!DOCTYPE html>
  <title>JS 获取屏幕坐标</title>
  <style>
    #track {
      background-color: goldenrod;
      height: 200px;
      width: 400px;
  </style>
</head>
  <p>移动鼠标查看其位置</p>
  <div id="track"></div>
  <p id="log"></p>
  <script>
    let track = document.querySelector('#track');
    track.addEventListener('mousemove', (e) => {
      let log = document.querySelector('#log');
      log.innerText = `