js实现简单功能合集(二)

962 阅读2分钟

持续创作,加速成长!这是我参与「掘金日新计划 · 6 月更文挑战」的第4天,点击查看活动详情

1. 点击返回顶部按钮,返回页面顶部

a. 监听页面滚动事件,获取滚动的距离,当该值大于一定值,让返回按钮显示,反之隐藏

window.onscroll = function(){
  let distance =  document.documentElement.scrollTop || document.body.scrollTop;
  if( distance >= 300 ){
    backTop.style.display = 'block';
  }else{
    backTop.style.display = 'none';
  }
} 

b. 点击返回按钮,通过设置定时器,让滚动距离减小慢慢回到页面顶部。滚动距离减小到0,需要清除定时器

backTop.onclick = function(){
  let distance =  document.documentElement.scrollTop || document.body.scrollTop;
  let timer = setInterval(() => {
    distance -= 10;
    document.documentElement.scrollTop = document.body.scrollTop = distance;
    if(distance <= 0){
      clearInterval(timer)
    }
  });
}

遇到的疑问:为什么需要定义两次滚动距离?

因为不能全局定义滚动距离,页面滚动的时候,滚动距离会实时变化。如果在全局一开始定义,滚动距离始终为0。并且返回按钮点击时,需要获取当前位置滚动过的距离

简单实现返回: 点击返回按钮,执行页面滚动事件并平滑滚动

window.scroll({
  top: 0,
  behavior: 'smooth'
})

2.实现图片的懒加载

方法一

a. 判断图片元素是不是出现在窗口(视野),为真就加载图片

Element.getBoundingClientRect()方法返回元素的大小及其相对于视口的位置。通过此方法获取图片到视口顶部的距离是否小于视口高度,小于则说明图片出现在窗口;设置图片元素的自定义属性data-src,加载时使用 src 代替 data-src

const images = document.querySelectorAll('img')
function lazy () {
    images.forEach((elem) => {
      if (elem.getBoundingClientRect().top < document.documentElement.clientHeight) {
        if (elem.dataset.src && elem.src == '') {
          elem.src = elem.dataset.src
        }
      }
    })
  }
lazy()

b. 滚动事件

监听页面滚动事件,执行图片加载方法。(加个节流,提高性能;节流的实现方法可以看下最近写的这篇文章《浅谈函数节流、函数防抖》

window.addEventListener('scroll', throttle(500, lazy))
方法二

IntersectionObserver API,能够监听元素是否到了当前视口

IntersectionObserver是浏览器原生提供的构造函数,接受两个参数:

callback是可见性变化时的回调函数。事件回调函数的参数是 IntersectionObserverEntry的集合,提供在可见视口的目标元素的一系列值。

option是配置对象(该参数可选)

IntersectionObserverEntry.isIntersecting 返回一个布尔值,为true代表目标元素可见

IntersectionObserverEntry.target:被观察的目标元素,是一个 DOM 节点对象

构造函数的返回值是一个观察器实例,实例的observe方法可以指定观察哪个 DOM 节点。

const io = new IntersectionObserver(callback, option); 
// 开始观察 
io.observe(document.getElementById('example'));  
// 停止观察 
io.unobserve(element);  
// 关闭观察器 
io.disconnect();

使用IntersectionObserver监听图片元素是否可见,为真使用 src 代替 图片的自定义属性data-src

const images = document.querySelectorAll('img')
const observer = new IntersectionObserver((changes) => {
  // changes: 目标元素集合
  changes.forEach((change) => {
    if (change.isIntersecting) {
      const img = change.target;
      if (img.dataset.src && img.src == "") {
        img.src = img.dataset.src
      }
      observer.unobserve(img);
    }
  });
});

images.forEach(img => observer.observe(img));