面试题答案
一键面试自定义懒加载策略思路
- 监听用户操作习惯:
- 通过监听滚动事件、点击事件等获取用户行为。例如,用户频繁滚动页面说明其对内容获取较为急切,可提前触发懒加载。
- 利用
window.addEventListener('scroll', callback)
监听滚动事件,在callback
中判断滚动位置与元素位置关系。
- 结合页面布局:
- 分析页面元素布局结构,对于靠近视口中心或者重要区域(如首屏、用户经常交互区域)的元素提前加载。
- 可以通过计算元素与视口的距离和位置关系来判断,使用
element.getBoundingClientRect()
方法获取元素在视口的位置信息。
- 动态调整懒加载时机和方式:
- 根据用户操作习惯和页面布局分析结果,改变懒加载的触发条件。比如,对于经常滚动的用户,当元素距离视口一定距离(如200px)时就开始加载;对于不常滚动的用户,当元素进入视口才加载。
- 可以使用节流或防抖技术优化事件处理,避免频繁触发加载操作。例如使用
lodash
库的throttle
或debounce
方法。
核心代码框架
- HTML部分:
<template> <div> <div v-for="(item, index) in items" :key="index"> <img v-if="loadedIndexes.includes(index)" :src="item.src" alt=""> <img v-else data-src="item.src" @click="loadImage(index)" @scroll="checkScroll(index)" class="lazy-load-img"> </div> </div> </template>
- JavaScript部分:
import _ from 'lodash'; export default { data() { return { items: [ { src: 'image1.jpg' }, { src: 'image2.jpg' }, // 更多图片数据 ], loadedIndexes: [], scrollThrottle: null }; }, methods: { loadImage(index) { this.loadedIndexes.push(index); }, checkScroll: _.throttle(function(index) { const img = this.$el.querySelector(`.lazy-load-img[data-src="${this.items[index].src}"]`); const rect = img.getBoundingClientRect(); if (rect.top < window.innerHeight && rect.bottom >= 0) { this.loadImage(index); } }, 200) }, mounted() { window.addEventListener('scroll', this.checkScroll); window.addEventListener('click', this.handleClick); }, beforeDestroy() { window.removeEventListener('scroll', this.checkScroll); window.removeEventListener('click', this.handleClick); if (this.scrollThrottle) { this.scrollThrottle.cancel(); } } };
关键技术点
- 元素位置获取:
element.getBoundingClientRect()
方法用于获取元素相对于视口的位置,通过判断其top
、bottom
等属性与视口高度的关系,确定元素是否在视口内或接近视口。 - 事件监听与优化:使用
window.addEventListener
监听滚动和点击等事件,同时利用throttle
或debounce
技术优化事件处理,防止因频繁触发事件导致性能问题。 - 数据状态管理:在Vue组件中,通过
data
中的数组(如loadedIndexes
)来记录已经加载的元素索引,控制元素的显示与加载。