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 事件触发。

参考文献

相关推荐
passerby60616 小时前
完成前端时间处理的另一块版图
前端·github·web components
掘了6 小时前
「2025 年终总结」在所有失去的人中,我最怀念我自己
前端·后端·年终总结
崔庆才丨静觅6 小时前
实用免费的 Short URL 短链接 API 对接说明
前端
崔庆才丨静觅6 小时前
5分钟快速搭建 AI 平台并用它赚钱!
前端
崔庆才丨静觅7 小时前
比官方便宜一半以上!Midjourney API 申请及使用
前端
Moment7 小时前
富文本编辑器在 AI 时代为什么这么受欢迎
前端·javascript·后端
崔庆才丨静觅7 小时前
刷屏全网的“nano-banana”API接入指南!0.1元/张量产高清创意图,开发者必藏
前端
剪刀石头布啊7 小时前
jwt介绍
前端
爱敲代码的小鱼7 小时前
AJAX(异步交互的技术来实现从服务端中获取数据):
前端·javascript·ajax
Cobyte7 小时前
AI全栈实战:使用 Python+LangChain+Vue3 构建一个 LLM 聊天应用
前端·后端·aigc