text: (window.webpackJsonp=window.webpackJsonp||[]).push([[15],{664:function(e,t,n){"use strict";n.r(t);var r=n(7),s=Object(r.a)({},(function(){var e=this,t=e.$createElement,n=e._self._c||t;return n("ContentSlotsDistributor",{attrs:{"slot-key":e.$parent.slotKey}},[n("blockquote",[n("p",[e._v("在论坛上，看到一个做懒加载很方便的api IntersectionObserver，记录下")])]),e._v(" "),n("p",[e._v("官方介绍如下"),n("br"),e._v("\nIntersectionObserver接口 (从属于Intersection Observer API) 提供了一种异步观察目标元素与其祖先元素或顶级文档视窗(viewport)交叉状态的方法。祖先元素与视窗(viewport)被称为根(root)。"),n("br"),e._v("\n当一个IntersectionObserver对象被创建时，其被配置为监听根中一段给定比例的可见区域。一旦IntersectionObserver被创建，则无法更改其配置，所以一个给定的观察者对象只能用来监听可见区域的特定变化值；然而，你可以在同一个观察者对象中配置监听多个目标元素。")]),e._v(" "),n("p",[n("strong",[e._v("说白了就是用来监听某元素是否在页面的可视范围内")])]),e._v(" "),n("h3",{attrs:{id:"_1、api简要说明"}},[n("a",{staticClass:"header-anchor",attrs:{href:"#_1、api简要说明"}},[e._v("#")]),e._v(" 1、api简要说明")]),e._v(" "),n("p",[e._v("它是一个订阅和观察模式")]),e._v(" "),n("div",{staticClass:"language- extra-class"},[n("pre",{pre:!0,attrs:{class:"language-text"}},[n("code",[e._v("let io = new IntersectionObserver(callback, option)\n// 开始观察\nio.observe(document.getElementById('example'));\n// 停止观察\nio.unobserve(element);\n// 关闭观察器\nio.disconnect();\n")])])]),n("p",[e._v("而在callback中，参数entries为一个数组，callback会在被观察者出现在页面时，以及消失在页面上时触发，entries中的IntersectionObserverEntry对象包含下面这些属性")]),e._v(" "),n("ul",[n("li",[e._v("time：可见性发生变化的时间，是一个高精度时间戳，单位为毫秒")]),e._v(" "),n("li",[e._v("target：被观察的目标元素，是一个 DOM 节点对象")]),e._v(" "),n("li",[e._v("rootBounds：根元素的矩形区域的信息，getBoundingClientRect()方法的返回值，如果没有根元素（即直接相对于视口滚动），则返回null")]),e._v(" "),n("li",[e._v("boundingClientRect：目标元素的矩形区域的信息")]),e._v(" "),n("li",[e._v("intersectionRect：目标元素与视口（或根元素）的交叉区域的信息")]),e._v(" "),n("li",[e._v("intersectionRatio：目标元素的可见比例，即intersectionRect占boundingClientRect的比例，完全可见时为1，完全不可见时小于等于0"),n("br"),e._v("\n而option里面可以配置一些参数，个人认为最重要的就是配置目标元素所在容器，毕竟不是滚动时不一样是在body内滚动")])]),e._v(" "),n("div",{staticClass:"language- extra-class"},[n("pre",{pre:!0,attrs:{class:"language-text"}},[n("code",[e._v("let opts = { \n  root: document.querySelector('.container') \n};\n\nlet observer = new IntersectionObserver(\n  callback,\n  opts\n);\n")])])]),n("h3",{attrs:{id:"_2、使用该api很简单的实现图片懒加载"}},[n("a",{staticClass:"header-anchor",attrs:{href:"#_2、使用该api很简单的实现图片懒加载"}},[e._v("#")]),e._v(" 2、使用该api很简单的实现图片懒加载")]),e._v(" "),n("div",{staticClass:"language- extra-class"},[n("pre",{pre:!0,attrs:{class:"language-text"}},[n("code",[e._v("const imgs = [...document.getElementsByTagName('img')];\n// 当监听的元素进入可视范围内的会触发回调\nif(IntersectionObserver) {\n    let lazyImageObserver = new IntersectionObserver((entries, observer) => {\n        entries.forEach((entry, index) => {\n            let lazyImage = entry.target;\n            // 相交率，默认是相对于浏览器视窗\n            if(entry.intersectionRatio > 0) {\n              lazyImage.src = lazyImage.getAttribute('data-src');\n              // 当前图片加载完之后需要去掉监听\n                lazyImageObserver.unobserve(lazyImage);\n            }\n\n        })\n    })\n    for(let i = 0; i < imgs.length; i++) {\n      lazyImageObserver.observe(imgs[i]);\n    }\n}\n")])])]),n("h3",{attrs:{id:"最后"}},[n("a",{staticClass:"header-anchor",attrs:{href:"#最后"}},[e._v("#")]),e._v(" 最后")]),e._v(" "),n("p",[e._v("通过类似的方法，也可以完成骨架屏的滚动加载~需要注意的是，该方法是一个弱线程方法，只有在浏览器空闲的时候才会触发异步监听")])])}),[],!1,null,null,null);t.default=s.exports}}]);