唯品秀前端博客
当前位置: 前端开发 > JavaScript > 认识IntersectionObserver交叉口观察者(懒加载、预加载)

认识IntersectionObserver交叉口观察者(懒加载、预加载)

2020-03-07 分类:JavaScript 作者:管理员 阅读(468)

IntersectionObserver是个异步方法,使用者不必过多的关注它内部具体计算过程,应用场景如:以前我们在做图片懒加载时候需要借助插件,或者手动去计算元素是否在视窗内,反正我是记不住具体怎么算,每次都是百度一遍套公式,自从发现了IntersectionObserver,一切是变得如此的简单,不单单是通过它可以进行懒加载图片,例如很多公司需要做元素进屏展示统计等等,它都将能胜任。

api基本格式

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
var io = new IntersectionObserver(changes => {
    for (const change of changes) {
        console.log(change.time);
        // 当可视状态变化时,状态发送改变的时间戳
        // 对比时间为,实例化的时间,
        // 比如,值为1000时,表示在IntersectionObserver实例化的1秒钟之后,触发该元素的可视性变化

        console.log(change.rootBounds);
        // 根元素的矩形区域信息,即为getBoundingClientRect方法返回的值

        console.log(change.boundingClientRect);
        // 目标元素的矩形区域的信息

        console.log(change.intersectionRect);
        // 目标元素与视口(或根元素)的交叉区域的信息

        console.log(change.intersectionRatio);
        // 目标元素的可见比例,即intersectionRect占boundingClientRect的比例,
        // 完全可见时为1,完全不可见时小于等于0

        console.log(change.target);
        // 被观察的目标元素,是一个 DOM 节点对象
        // 当前可视区域正在变化的元素

    }
}, {}); //{}为可选,其中为配置参数

// 对元素target添加监听,当target元素变化时,就会触发上述的回调
io.observe(target);

// 移除一个监听,移除之后,target元素的可视区域变化,将不再触发前面的回调函数
io.unobserve(target);

// 停止所有的监听
io.disconnect();

兼容性

最好的教程莫过于一个小demo

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
<!DOCTYPE html>
<html lang="en">

<head>
  <meta charset="UTF-8">
  <title>淘宝女郎</title>
</head>
<style>
  .girls-list-wrap {
    min-height: 400px;
    width: 100%;
    margin-top: 10px;
    overflow: hidden
  }

  .girls-list-wrap .girls-list {
    width: 1155px;
    margin: 0 auto;
    list-style: none
  }

  .girls-list-wrap .girls-list .item {
    width: 230px;
    height: 288px;
    float: left;
    position: relative;
    *display: inline;
    margin: -1px 0 0 -1px
  }

  .girls-list-wrap .girls-list .item a {
    display: block;
    text-decoration: none;
    height: 100%;
    width: 100%
  }

  .girls-list-wrap .girls-list .item a:hover .item-wrap {
    width: 246px;
    height: 304px;
    border: 2px solid #282828;
   background-color: #282828;
   margin: -10px 0 0 -10px;
    z-index: 1
  }

  .girls-list-wrap .girls-list .item a:hover .info {
    color: #fff
 }

  .girls-list-wrap .girls-list .item a:hover .info .city,
  .girls-list-wrap .girls-list .item a:hover .info .name {
    color: #fff
 }

  .girls-list-wrap .girls-list .item a:hover img {
    height: 246px
  }

  .girls-list-wrap .girls-list .item img {
    width: 100%;
    height: 228px;
    -webkit-transition-property: height;
    -webkit-transition-duration: .2s;
    -webkit-transition-timing-function: ease-in-out;
    -moz-transition-property: height;
    -moz-transition-duration: .2s;
    -moz-transition-timing-function: ease-in-out;
    -ms-transition-property: height;
    -ms-transition-duration: .2s;
    -ms-transition-timing-function: ease-in-out;
    -o-transition-property: height;
    -o-transition-duration: .2s;
    -o-transition-timing-function: ease-in-out;
    transition-property: height;
    transition-duration: .2s;
    transition-timing-function: ease-in-out
  }

  .girls-list-wrap .girls-list .item .info {
    padding-left: 10px
  }

  .girls-list-wrap .girls-list .item .info .name {
    color: #666;
   margin-right: 5px
  }

  .girls-list-wrap .girls-list .item .info .city {
    color: #a9a9a9;
   font-size: 12px;
    vertical-align: top
  }

  .girls-list-wrap .girls-list .item .row2 {
    color: #a9a9a9;
   font-size: 12px;
    margin-top: 3px
  }

  .girls-list-wrap .girls-list .item .row2 .fr {
    float: right;
    margin-right: 10px
  }

  .girls-list-wrap .girls-list .item .row2 .iconfont {
    margin-right: 5px
  }

  .girls-list-wrap .girls-list .item-wrap {
    width: 228px;
    height: 288px;
    position: absolute;
    float: left;
    border: 1px solid #a0a0a0;
   background-color: #fff;
   -webkit-transition-property: width height border margin z-index;
    -webkit-transition-duration: .2s;
    -webkit-transition-timing-function: ease-in-out;
    -moz-transition-property: width height border margin z-index;
    -moz-transition-duration: .2s;
    -moz-transition-timing-function: ease-in-out;
    -ms-transition-property: width height border margin z-index;
    -ms-transition-duration: .2s;
    -ms-transition-timing-function: ease-in-out;
    -o-transition-property: width height border margin z-index;
    -o-transition-duration: .2s;
    -o-transition-timing-function: ease-in-out;
    transition-property: width height border margin z-index;
    transition-duration: .2s;
    transition-timing-function: ease-in-out
  }
</style>

<body>
  <div class="girls-list-wrap">
    <ul class="girls-list clearfix" id="J_GirlsList">
      <li class="item">
        <a href="#">
          <div class="item-wrap">
            <div class="img"><img
                data-src="https://gtd.alicdn.com/sns_logo/i6/TB1fVJJQFXXXXcyXpXXSutbFXXX.jpg_240x240xz.jpg"
                src="https://img.alicdn.com/tps/i3/T1QYOyXqRaXXaY1rfd-32-32.gif"></div>
            <div class="info">
              <span class="name">模特雪梨</span>
              <span class="city">杭州市</span>
            </div>
            <div class="info row2">

              <span>165CM&nbsp;/&nbsp;47KG</span>

              <span class="fr"><i class="iconfont">&#x1f44d;</i>201566</span>
           </div>
          </div>
        </a>
      </li>
     <!-- 为代码简洁在此省略亿万张图片 -->
    </ul>
  </div>
</body>

</html>

js部分

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
<script>
  const io = new IntersectionObserver(callback, {
    root: null, //用于观察的根元素,默认是浏览器的视口,也可以指定具体元素,指定元素的时候用于观察的元素必须是指定元素的子元素
    //threshold: [0, 0.5, 1], //指定了交叉比例为0,0.5,1,当观察元素img0%、50%、100%时候就会触发回调函数
    rootMargin: '0px 0px -100px'//这个参数非常有用,用来扩大或者缩小视窗的的大小,使用css的定义方法,10px 10px 30px 20px表示top、right、bottom 和 left的值
  });
  let imgs = document.querySelectorAll('[data-src]');
  function callback(entries) {
    entries.forEach((item) => {
      if (item.isIntersecting) {
        item.target.src = item.target.dataset.src
        io.unobserve(item.target)
      }
    })
  }

  imgs.forEach((item) => {
    io.observe(item)
  })
</script>

小结

截止目前兼容性已达到90%+,我相信在实际项目中你是可以值得一试的。温馨提示:为了更好的体验下面demo图片懒加载技术效果了解它的工作过程,你应该将浏览器网速降低到至3G等模式,具体可百度。

在线一览

「三年博客,如果觉得我的文章对您有用,请帮助本站成长」

赞(6) 打赏

谢谢你请我吃鸡腿*^_^*

支付宝
微信
6

谢谢你请我吃鸡腿*^_^*

支付宝
微信

上一篇:

下一篇:

你可能感兴趣

0 条评论关于"认识IntersectionObserver交叉口观察者(懒加载、预加载)"

博客简介

唯品秀博客: weipxiu.com,一个关注Web前端开发技术、关注用户体验、坚持更多原创实战教程的个人网站,愿景:成为宇宙中最具有代表性的前端博客,期待您的参与,主题源码 

精彩评论

  • 江吟辞(2周前 (06-29))

    好难坚持啊,我还没毕业,不知道啥时候才能像您一样厉害

    评:碎言碎语
  • 和我、恋爱吧(2周前 (06-29))

    怎么没见你更新呢,比较忙吗

    评:碎言碎语
  • 游离(2周前 (06-29))

    站主,你好!请教一下,前台的pc 端和移动端,你是怎么实现响应式的呢?媒体查询的同时写两套样...

    评:碎言碎语
  • 권지용(2周前 (06-29))

    最近在学习前端,看了博主很多文章,收益匪浅,感谢大佬

    评:碎言碎语
  • 白君也(2周前 (06-28))

    哇 自己制作的吗 在哪学的技术啊 好厉害

    评:碎言碎语
  • 管理员(4周前 (06-16))

    时间区间问题,因为目前是2020年,你所选不可能超出这个时间吧,当然,代码是根据你的业务来,...

    评:js时间戳完美转换成阴历农历格式

友情链接

他们同样是一群网虫,却不是每天泡在网上游走在淘宝和网游之间、刷着本来就快要透支的信用卡。他们或许没有踏出国门一步,但同学却不局限在一国一校,而是遍及全球!申请交换友链

站点统计

  • 文章总数: 258 篇
  • 草稿数目: 0 篇
  • 分类数目: 16 个
  • 独立页面: 6 个
  • 评论总数: 906 条
  • 链接总数: 17 个
  • 标签总数: 459 个
  • 注册用户: 8220 人
  • 访问总量: 9222447 次
  • 最近更新: 2020年7月3日
服务热线:
 173xxxx7240

 QQ在线交流

 旺旺在线