JavaScript | 事件对象—滚动事件与加载事件

原文:JavaScript | 事件对象---滚动事件与加载事件

滚动事件与加载事件是前端中常见的事件类型,今天对这两个知识点进行下整理

滚动事件(scroll)

滚动事件顾名思义就是滚动页面或者说是某个元素滚动的时候就会触发的事件,可以使用以下几种方式触发滚动事件:

  • 鼠标滚轮滚动
  • 使用页面右侧的滚动条
  • 使用描点跳转
  • 调用JavaScript函数

如何添加滚动事件

  • DOM Level 2 中的写法(推荐使用):

    javascript 复制代码
    eventTarget.addEventListener('scroll', function(){
      console.log('触发了滚动事件');
    }); 
  • DHTML(DOM Level 0)的写法:

    javascript 复制代码
    EventTarget.onscroll = function () {
      console.log('触发了滚动事件');
    }

如何监听整个页面的滚动

如果想要监听整个网页的滚动,给window对象添加scroll事件即可

javascript 复制代码
window.addEventListener('scroll', function(){
  console.log('触发了滚动事件');
});

DHTML(DOM Level 0)的写法:

javascript 复制代码
window.onscroll = function () {
  console.log('触发了滚动事件');
}

事件节流

之前一篇博客有提到,如果在事件处理的回调函数调用了下面这些属性的话,就会引起回流与重绘(因为这些属性是实时读取的),而大量的回流与重绘就会造成浏览器的卡顿。

offsetTop、offsetLeft、 offsetWidth、offsetHeight、scrollTop、scrollLeft、scrollWidth、scrollHeight、clientTop、clientLeft、clientWidth、clientHeight

所以可以使用节流的方式来缓解这个问题,先来了解下节流是什么:

节流:高频事件触发,但在n秒内只会执行一次,所以节流会稀释函数的执行频率

实现方式:每次触发事件时,如果当前有等待执行的延时函数,则直接return终止此次事件的执行

代码:

JS:

javascript 复制代码
// 初始化 滚动标记 默认为false
let scrolling = false;

// 如果当前有滚动,则将滚动标记设置为true
window.addEventListener('scroll', function () {
  scrolling = true;
});

// 如果滚动事件触发,则每个300毫秒调用依次事件处理回调函数
setInterval(() => {
  console.log(scrolling);
  // 每次触发事件时,如果当前有等待执行的延时函数,则直接return
  if (!scrolling) {
    return;
  } else{
    // 立即设置为false
    scrolling = false
    // 处理逻辑
    window.scrollHandLer();
  }
}, 300);

function scrollHandLer() {
  // 滚动处理回调函数
  console.log('保护大籽然,不杀生');
}

加载事件(load)

加载事件,当外部资源(如图片、CSS、JavaScript文件等)加载完毕的时候触发的事件。

事件名:load

页面所有资源加载完毕后触发:

javascript 复制代码
window.addEventListener('load', function(){
  console.log('外部资源加载完毕');
});

DHTML(DOM Level 0)的写法:

javascript 复制代码
window.onload = function (){
  console.log('外部资源加载完毕');
}

使用场景:

在一些比较老的代码中会看到把script写在header中的写法,但是这样写会遇到一个问题

比如现在进入一个页面,会出现dom元素获取不到的问题,比如下面这种情况:

HTML:

html 复制代码
<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>
  <script>
    let div = document.querySelector('div');
    console.log(div); //null
  </script>
</head>
<body>
  <div></div>
</body>

控制台输出:null

所以就可以通过load事件来解决这个问题,代码如下

javascript 复制代码
window.addEventListener('load', function(){
  let div = document.querySelector('div');
  console.log(div);
});

控制台输出:<div></div>

当然,load事件不仅仅可以监听整个页面的资源加载,还可以针对某个资源绑定load事件

比如可以监听图片加载好之后给div元素放入文字

javascript 复制代码
let img = document.querySelector('img');
img.addEventListener('load', function () {
  let div = document.querySelector('div');
  div.innerHTML = 'test';
})

补充:DOMContentLoaded

当纯 HTML 被完全加载以及解析时,DOMContentLoaded事件会被触发,而不必等待样式表,图片或者子框架完成加载

------MDN-Document: DOMContentLoaded 事件

简单理解以下就是,页面的dom树加载完成后就会触发 ,也就是说这个事件的触发顺序实在load事件前面的。

事件名:DOMContentLoaded

监听页面的DOM加载完成------给document添加DOMContentLoaded事件即可

javascript 复制代码
document.addEventListener('DOMContentLoaded', (event) => {
  console.log('DOM fully loaded and parsed');
});

案例:

HTML:

html 复制代码
<div class="controls">
  <button id="reload" type="button">Reload</button>
</div>

<div class="event-log">
  <label>Event log:</label>
  <textarea readonly class="event-log-contents" rows="8" cols="30"></textarea>
</div>

JS:

javascript 复制代码
const log = document.querySelector('.event-log-contents');
const reload = document.querySelector('#reload');

reload.addEventListener('click', () => {
  log.textContent ='';
  window.setTimeout(() => {
      window.location.reload(true);
  }, 200);
});

window.addEventListener('load', (event) => {
    log.textContent = log.textContent + 'load\n';
});

document.addEventListener('readystatechange', (event) => {
    log.textContent = log.textContent + `readystate: ${document.readyState}\n`;
});

document.addEventListener('DOMContentLoaded', (event) => {
    log.textContent = log.textContent + `DOMContentLoaded\n`;
});

一些注意事项

  • DOMContentLoaded 事件在 html 文档加载完毕,并且 html 所引用的内联 js、以及外链 js 的同步代码都执行完毕后触发

  • 页面中引用的js 代码如果有异步加载的 js、css、图片,是会影响 load 事件触发的。

  • video、audio、flash 不会影响 load 事件触发。

参考文献

相关推荐
开开心心就好1 小时前
竖式除法出题工具,整除余数混合模式
运维·服务器·前端·javascript·ocr·perl·1024程序员节
起个名字费劲死了2 小时前
Halcon学习一:骰子识别
前端·python·学习
大江东去浪淘尽千古风流人物2 小时前
【HexVIO】DSP卸载双目惯性VIO:Hexagon向量化前端与单帧融合调度深度解析
前端·状态模式·slam·dsp·vio·hexagon·移动端加速
এ慕ོ冬℘゜2 小时前
JS 事件循环、宏任务微任务:单线程底层原理 + 执行顺序
开发语言·javascript·ecmascript
其实防守也摸鱼2 小时前
Chrome 扩展安全攻防实录:从攻击面到防御实践
开发语言·前端·网络·chrome·安全·web安全·php
web打印社区2 小时前
Lodop排障总纲-常见报错一张表
开发语言·前端·javascript·chrome·websocket
李剑一2 小时前
为什么几乎所有的知名开源项目都是外国人写的?
前端·ai编程·deepseek
小郎君6582 小时前
(一)为什么表单需要第三种状态:disabled、readonly 与纯文本展示
前端·vue.js
计算机魔术师2 小时前
1.4万亿没人接,OpenAI自己砍了1500亿
前端
程序员大阳2 小时前
副队长JavaScript教程(56)-DOM之表单操作
javascript·dom·表单操作