Skip to content

DOM注册事件

事件是编程语言中的术语,它是用来描述程序的行为或状态的,一旦行为或状态发生改变,便立即调用一个函数。

例如:用户使用【鼠标点击】网页中的一个按钮、用户使用【鼠标拖拽】网页中的一张图片

事件监听版本

事件处理程序分为:

  1. HTML事件处理
  2. DOM0级事件处理
  3. DOM2级事件处理

HTML事件

缺点:HTML和JS没有分开

html
<body>
    <button onclick="clickHandle()">按钮</button>
    <script>
        function clickHandle(){
            console.log('点击了按钮');
        }
    </script>
</body>

DOM0级事件处理

优点:HTML和JS是分离的

缺点:无法同时生效多个事件,后添加的事件会覆盖前面的

html
<body>
    <button id="btn">按钮</button>
    <script>
        var btn = document.getElementById("btn");
        btn.onclick = function(){
            console.log('被点击了');
        }
    </script>
</body>

DOM2级事件处理

优点:事件不会被覆盖,可以同时添加多个事件 (推荐使用)

缺点:写起来麻烦

语法:

js
addEventListener(type, listener);
addEventListener(type, listener, options);
addEventListener(type, listener, useCapture);

参数:

  1. typre:表示监听事件类型的大小写敏感的字符串。
  2. listener:执行的函数
  3. options(可选):一个指定有关 listener 属性的可选参数对象
    • capture:一个布尔值,表示 listener 会在该类型的事件捕获阶段传播到该 EventTarget 时触发。
    • once:一个布尔值,表示 listener 在添加之后最多只调用一次。如果为 truelistener 会在其被调用之后自动移除。
    • passive:一个布尔值,设置为 true 时,表示 listener 永远不会调用 preventDefault()。如果 listener 仍然调用了这个函数,客户端将会忽略它并抛出一个控制台警告。
    • signalAbortSignal,该 AbortSignalabort() 方法被调用时,监听器会被移除。
  4. useCapture(可选):一个布尔值,当 useCapture(设为 true)时,沿着 DOM 树向上冒泡的事件不会触发 listener
html
<body>
    <button id="btn">按钮</button>
    <script>
        var btn = document.getElementById("btn");
        btn.addEventListener("click",function(){
            console.log("被点击了");
        })
    </script>
</body>

事件

事件监听

结合 DOM 使用事件时,需要为 DOM 对象添加事件监听,等待事件发生(触发)时,便立即调用一个函数。

addEventListener 是 DOM 对象专门用来添加事件监听的方法,它的两个参数分别为【事件类型】和【事件回调】。

html
<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>事件监听</title>
</head>
<body>
  <h3>事件监听</h3>
  <p id="text">为 DOM 元素添加事件监听,等待事件发生,便立即执行一个函数。</p>
  <button id="btn">点击改变文字颜色</button>
  <script>
    // 1. 获取 button 对应的 DOM 对象
    const btn = document.querySelector('#btn')

    // 2. 添加事件监听
    btn.addEventListener('click', function () {
      console.log('等待事件被触发...')
      // 改变 p 标签的文字颜色
      let text = document.getElementById('text')
      text.style.color = 'red'
    })

    // 3. 只要用户点击了按钮,事件便触发了!!!
  </script>
</body>
</html>

完成事件监听分成3个步骤:

  1. 获取 DOM 元素
  2. 通过 addEventListener 方法为 DOM 节点添加事件监听
  3. 等待事件触发,如用户点击了某个按钮时便会触发 click 事件类型
  4. 事件触发后,相对应的回调函数会被执行

大白话描述:所谓的事件无非就是找个机会(事件触发)调用一个函数(回调函数)。

事件类型

click 译成中文是【点击】的意思,它的含义是监听(等着)用户鼠标的单击操作,除了【单击】还有【双击】dblclick

html
<script>
  // 双击事件类型
  btn.addEventListener('dblclick', function () {
    console.log('等待事件被触发...');
    // 改变 p 标签的文字颜色
    const text = document.querySelector('.text')
    text.style.color = 'red'
  })

  // 只要用户双击击了按钮,事件便触发了!!!
</script>

结论:【事件类型】决定了事件被触发的方式,如 click 代表鼠标单击,dblclick 代表鼠标双击。

事件处理程序

addEventListener 的第2个参数是函数,这个函数会在事件被触发时立即被调用,在这个函数中可以编写任意逻辑的代码,如改变 DOM 文本颜色、文本内容等。

html
<script>
  // 双击事件类型
  btn.addEventListener('dblclick', function () {
    console.log('等待事件被触发...')
    
    const text = document.querySelector('.text')
    // 改变 p 标签的文字颜色
    text.style.color = 'red'
    // 改变 p 标签的文本内容
    text.style.fontSize = '20px'
  })
</script>

结论:【事件处理程序】决定了事件触发后应该执行的逻辑。

事件类型

将众多的事件类型分类可分为:鼠标事件、键盘事件、表单事件、焦点事件等,我们逐一展开学习。

鼠标事件

鼠标事件是指跟鼠标操作相关的事件,如单击、双击、移动等。mouseovermouseout也是进入和离开事件,但是会有冒泡效果,只有当事件委托时需要冒泡才使用。

  • event.clientXevent.clientY:鼠标指针相对于浏览器窗口可视区域的坐标。
  • event.pageXevent.pageY:鼠标指针相对于整个文档的坐标,包括可滚动部分。
  • event.screenXevent.screenY:鼠标指针相对于屏幕的坐标
  1. mouseenter 监听鼠标是否移入 DOM 元素
html
<body>
  <h3>鼠标事件</h3>
  <p>监听与鼠标相关的操作</p>
  <hr>
  <div class="box"></div>
  <script>
    // 需要事件监听的 DOM 元素
    const box = document.querySelector('.box');

    // 监听鼠标是移入当前 DOM 元素
    box.addEventListener('mouseenter', function () {
      // 修改文本内容
      this.innerText = '鼠标移入了...';
      // 修改光标的风格
      this.style.cursor = 'move';
    })
  </script>
</body>
  1. mouseleave 监听鼠标是否移出 DOM 元素
html
<body>
  <h3>鼠标事件</h3>
  <p>监听与鼠标相关的操作</p>
  <hr>
  <div class="box"></div>
  <script>
    // 需要事件监听的 DOM 元素
    const box = document.querySelector('.box');

    // 监听鼠标是移出当前 DOM 元素
    box.addEventListener('mouseleave', function () {
      // 修改文本内容
      this.innerText = '鼠标移出了...';
    })
  </script>
</body>
  1. mousemove监听鼠标是否在DOM 元素移动
js
const box = document.querySelector('.box')
box.addEventListener('mousemove', function(e) { 
  // 在这里处理鼠标移动事件  
  console.log(e.clientX, e.clientY);  
});

键盘事件

keydown 键盘按下触发

keyup 键盘抬起触发

焦点事件

focus 获得焦点

blur 失去焦点

文本框输入事件

input

html
<body>
  <input type="text">
  <script>
    // 需要事件监听的 DOM 元素
    const input = document.querySelector('input');

    // 监听输入事件
    box.addEventListener('input', function () {
    // 输出文本
      console.log("input.value");
    })
  </script>
</body>

视频事件

timeupdate 用于监视时间的变化。它在 HTML <audio><video> 元素上特别有用,因为这些元素的时间可能会随着播放的进行而改变。

loadeddata 通常用于处理媒体元素(如 <video><audio>)的数据已加载完成的情况。当媒体元素的数据被完全加载后,loadeddata 事件会被触发。

事件对象

任意事件类型被触发时与事件相关的信息会被以对象的形式记录下来,我们称这个对象为事件对象。

html
<body>
  <h3>事件对象</h3>
  <p>任意事件类型被触发时与事件相关的信息会被以对象的形式记录下来,我们称这个对象为事件对象。</p>
  <hr>
  <div class="box"></div>
  <script>
    // 获取 .box 元素
    const box = document.querySelector('.box')

    // 添加事件监听
    box.addEventListener('click', function (e) {
      console.log('任意事件类型被触发后,相关信息会以对象形式被记录下来...');

      // 事件回调函数的第1个参数即所谓的事件对象
      console.log(e)
    })
  </script>
</body>

事件回调函数的【第1个参数】即所谓的事件对象,通常习惯性的将这个对数命名为 eventeve

接下来简单看一下事件对象中包含了哪些有用的信息:

  1. e.type 当前事件的类型
  2. e.clientX/Y 光标相对浏览器窗口的位置
  3. e.offsetX/Y 光标相于当前 DOM 元素的位置
  4. e.key 用户按下的键盘键的值,现在不提倡使用keyCode

注:在事件回调函数内部通过 window.event 同样可以获取事件对象。

环境对象

能够分析判断函数运行在不同环境中 this 所指代的对象。

环境对象指的是函数内部特殊的变量 this ,它代表着当前函数运行时所处的环境。

html
<script>
  // 声明函数
  function sayHi() {
    // this 是一个变量
    console.log(this);
  }

  // 声明一个对象
  let user = {
    name: '张三',
    sayHi: sayHi // 此处把 sayHi 函数,赋值给 sayHi 属性
  }
  
  let person = {
    name: '李四',
    sayHi: sayHi
  }

  // 直接调用
  sayHi() // window
  window.sayHi() // window

  // 做为对象方法调用
  user.sayHi()// user
  person.sayHi()// person
</script>

结论:

  1. this 本质上是一个变量,数据类型为对象
  2. 函数的调用方式不同 this 变量的值也不同
  3. 【谁调用 this 就是谁】是判断 this 值的粗略规则
  4. 函数直接调用时实际上 window.sayHi() 所以 this 的值为 window

回调函数

如果将函数 A 做为参数传递给函数 B 时,我们称函数 A 为回调函数。

html
<script>
  // 声明 foo 函数
  function foo(arg) {
    console.log(arg);
  }

  // 普通的值做为参数
  foo(10);
  foo('hello world!');
  foo(['html', 'css', 'javascript']);

  function bar() {
    console.log('函数也能当参数...');
  }
  // 函数也可以做为参数!!!!
  foo(bar);
</script>

函数 bar 做参数传给了 foo 函数,bar 就是所谓的回调函数了!!!

我们回顾一下间歇函数 setInterval

html
<script>
	function fn() {
    console.log('我是回调函数...');
  }
  // 调用定时器
  setInterval(fn, 1000);
</script>

fn 函数做为参数传给了 setInterval ,这便是回调函数的实际应用了,结合刚刚学习的函数表达式上述代码还有另一种更常见写法。

html
<script>
  // 调用定时器,匿名函数做为参数
  setInterval(function () {
    console.log('我是回调函数...');
  }, 1000);
</script>

结论:

  1. 回调函数本质还是函数,只不过把它当成参数使用
  2. 使用匿名函数做为回调函数比较常见