介绍
css 新属性
content-visibility:控制元素是否渲染其内容,以及强制一组强大的包含,允许用户代理潜在地省略大量布局和渲染工作,直到需要它为止。基本上,它使用户代理能够在需要之前跳过元素的渲染工作(包括布局和绘画)——这使得初始页面加载速度更快。
/* Keyword values */
content-visibility: visible; //没有效果。元素的内容被正常布局和渲染。
content-visibility: hidden; // 该元素跳过其内容。用户代理功能(例如在页面中查找、标签顺序导航等)不能访问跳过的内容,也不能选择或聚焦。这类似于给出内容display: none。
content-visibility: auto; // 该元素打开布局包含、样式包含和绘制包含。如果元素与用户无关,它也会跳过其内容。与隐藏不同,跳过的内容必须仍然对用户代理功能(如在页面中查找、标签顺序导航等)正常可用,并且必须正常可聚焦和可选择。
注意:兼容性差,fireFox,safari不支持
IntersectionObserver
使用场景:图片多、大的情况,防止一次性加载所有图片,在图片未进入可视页面之前,img 表情没有 scr 属性,(如果有 scr,即使为空,也会发送请求)
immediatly:是否立即加载图片,打开页面,默认在可视区域内的需要将其设置成 true
img.complete:图片已经加载过该文件时,此时可以直接显示出来
intersection-observer-polyfill: 可以兼容低版本浏览器
<template>
<img v-if="!immediately" :data-src="src" class="opacity0" ref="imgElement" />
<img v-else :src="src" class="opacity0" ref="imgElement" />
</template>
<script lang="ts">
import { defineComponent, Ref, ref, onMounted } from 'vue';
import IntersectionObserver from 'intersection-observer-polyfill';
export default defineComponent({
name: 'LazyImg',
props: {
src: {
default: '',
required: true,
},
immediately: {
default: false,
},
},
setup(props) {
const imgElement: Ref<HTMLImageElement | null> = ref(null);
const lazyload = (target: HTMLElement) => {
const io = new IntersectionObserver((entries: any[], observer: any) => {
entries.forEach((entry) => {
// isIntersecting 企微不支持(使用了polyfill 也这样)
if (entry?.isIntersecting || entry.intersectionRatio > 0) {
const img = entry.target;
const src = img.getAttribute('data-src');
img.setAttribute('src', src);
img.removeAttribute('data-src');
observer.disconnect();
}
});
});
io.observe(target);
};
onMounted(() => {
const img = imgElement.value;
if (img) {
if (!props.immediately) {
lazyload(img);
}
if (img.complete) {
// 如果图片已经存在于浏览器缓存,直接显示出来
img.classList.remove('opacity0');
img.classList.add('fade');
} else {
img.onload = () => {
img.classList.remove('opacity0');
img.classList.add('fade');
};
}
img.onerror = () =>
setTimeout(() => img.setAttribute('src', props.src), 500);
}
});
return {
imgElement,
};
},
});
</script>