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

参考文献

相关推荐
tedcloud1231 小时前
UI-TARS-desktop部署教程:构建AI桌面自动化系统
服务器·前端·人工智能·ui·自动化·github
UXbot4 小时前
AI原型设计工具如何支持团队协作与快速迭代
前端·交互·个人开发·ai编程·原型模式
ZC跨境爬虫5 小时前
跟着MDN学HTML_day_48:(Node接口)
前端·javascript·ui·html·音视频
PieroPc6 小时前
CAMWATCH — 局域网摄像头监控系统 Fastapi + html
前端·python·html·fastapi·监控
巴巴博一7 小时前
2026 最新:Trae / Cursor 一键接入 taste-skill 完整教程(让 AI 前端告别“AI 味”)
前端·ai·ai编程
kyriewen8 小时前
半夜三点线上崩了,AI替我背了锅——用AI排错,五分钟定位三年老bug
前端·javascript·ai编程
kyriewen8 小时前
我让 AI 当了 24 小时全年无休的“毒舌考官”
前端·ci/cd·ai编程
hexu_blog8 小时前
vue+java实现图片批量压缩
java·前端·vue.js
IT_陈寒8 小时前
为什么你应该学习JavaScript?
前端·人工智能·后端