阅读 2162

IntersectionObserver实现图片懒加载(滚动动画)

先简单过下IntersectionObserver的属性跟、方法


var io = new IntersectionObserver(callback, option);

IntersectionObserver是浏览器原生提供的构造函数,这里的callback是回调函数,option是配置对象

属性

  1. root

    所监听对象的具体祖先元素。如果未传入值或值为null,则默认使用顶级文档的视窗。

  2. rootMargin

    rootMargin设置root区域的扩展部分,比如我们做懒加载的时候一般都会有一个预先加载的距离,这个可以通过设置rootMargin:'0px 0px 200px 0px',方向遵从上右下左。这样设置相当于如果一个元素距离底部还有200px就会被检测到。

  1. threshold

    threshold这个参数默认是0,表示当刚发生相交的时候会触发这个方法,但是触发后直到离开都不会再次触发了,所以这个参数的作用就是设置一些特定的相交比例,当到了就会自动触发。

方法

  1. observe(element):监听某个元素,传入要监听的元素作为参数

  2. unobserve(element):停止监听某个元素,传入停止监听的元素作为参数

  3. disconnect():使监听器停止工作

  4. takeRecords():返回所有正在监听的元素的IntersectionObserverEntry对象数组


实现懒加载

效果

懒加载

直接上代码

//html
    <div class="imgWarp">
      <img alt="加载"
           class="lazyload"
           src=""
           data-origin="https://ss0.bdstatic.com/94oJfD_bAAcT8t7mm9GUKT-xh_/timg?image&quality=100&size=b4000_4000&sec=1567391611&di=25036e46ab595855036662439ff9aeff&src=http://b-ssl.duitang.com/uploads/blog/201312/14/20131214145220_QQANN.jpeg">
      <img alt="加载"
           class="lazyload"
           src=""
           data-origin="https://ss0.bdstatic.com/70cFuHSh_Q1YnxGkpoWK1HF6hhy/it/u=3617103641,169754897&fm=26&gp=0.jpg">
      <img alt="加载"
           class="lazyload"
           src=""
           data-origin="https://ss3.bdstatic.com/70cFv8Sh_Q1YnxGkpoWK1HF6hhy/it/u=2942419345,2278127334&fm=26&gp=0.jpg">
    </div>

//js
function Observer () {
      let images = document.querySelectorAll(".lazyload");
      let observer = new IntersectionObserver(entries => {
        entries.forEach(item => {
          if (item.isIntersecting) {
            item.target.src = item.target.dataset.origin; // 开始加载图片,把data-origin的值放到src
            observer.unobserve(item.target); // 停止监听已开始加载的图片
          }
        });
      },
        {
          rootMargin: "0px 0px -100px 0px" // 交叉过视图的100,才开始派发事件
        }
      );
      images.forEach(item => observer.observe(item));
    }

//scss也放上来把
.imgWarp {
    display: flex;
    flex-direction: column;
    margin-top: 1000px;
    .lazyload {
      margin-top: 30px;
      display: inline-block;
      width: 120px;
      height: 120px;
      position: relative;
    }
    .lazyload:after {
      position: absolute;
      content: "";
      top: 0;
      left: 0;
      width: 100%;
      height: 100%;
      display: block;
      background-color: #ccc;
    }
  }
复制代码
  • 该方法还有一个好处,那就是当页面上某个节点存在横向滚动条的时候,一样应对自如:代码就不上了,可以自己试下

横向滚动

需要改动的只有三四行css代码。

实现动画

// html

    <ul>
      <li></li>
      <li></li>
      <li></li>
      <li></li>
    </ul>
    
//js
function onLoad () {
      let list = document.querySelectorAll('ul li');
      let observer = new IntersectionObserver(entries => {
        entries.forEach(element => {
          if (element.isIntersecting) {
            element.target.classList.add("show"); // 增加show类名
            observer.unobserve(element.target); // 移除监听
          }
        });
      })
      list.forEach(item => observer.observe(item));
    }
    
//scss
ul {
    margin-top: 500px;
    display: flex;
    width: 90%;
    justify-content: center;
    align-items: center;
    flex-wrap: wrap;
    text-align: center;
    li {
      width: 40%;
      background-color: aqua;
      width: 150px;
      margin-bottom: 20px;
      height: 150px;
      &:nth-child(2n) {
        margin-left: 20px;
      }
      &.show {
        // 默认从左边进来
        animation: left 1.4s ease;
        // 偶数从右边进来
        &:nth-child(2n) {
          animation: right 1.4s ease;
        }
      }
    }
  }

  @keyframes left {
    from {
      opacity: 0;
      transform: translate(-40px, 20px) rotate(80deg); // right动画改成20px, 20px即可
    }

    to {
      opacity: 1;
    }
  }

  @keyframes right {
    from {
      opacity: 0;
      transform: translate(40px, 20px) rotate(-80deg); // right动画改成20px, 20px即可
    }

    to {
      opacity: 1;
    }
  }
复制代码

总结一波,大概就是这样bye!

文章分类
前端
文章标签