js图片懒加载,在不做分页的情况下的解决方案
1.前端url取参数以对象展示2.el-tree在vue3中全选和展开3.瀑布流4.瀑布流——前端流行网页布局方式5.vue中v-bind和v-model的区别是什么6.Vue中key的作用7.在Vue 3中,与Vue 2相比,有一些改进和优化的diff算法。8.浏览器解析html9.浏览器渲染HTML10.Object.entries()11.vue实现虚拟dom转换成真是dom的原理12.全局封装组件处理并发请求不连续的loading13.为什么vue数组下标修改监听不到14.Vue 3 在某些场景下可能表现出比 Vue 2 更低的性能15.vue里表单验证的v-model.number的坑16.有意思的css17.js原生语音转文字18.js手写一个call19.js手写一个apply20. 手写一个 bind 方法21.js寄生组合式继承22.react中的useState修改状态获取最新状态值23.函数柯里化js24.axios请求中断_下载中断和下载进度25.axios请求重试_核心原理26.axios请求重试_axios-retry插件27.虚拟列表-渲染 10 万条数据28.vue-office 组件29.threejs30.把原生 DOM 标签转换后加入到 3D 场景空间中显示31.three.js 物体要使用光线投射技术,计算是否点击位置与物体有交叉32.threejs基本函数33.二分查找算法34.js判断字符串是否连贯35.世界坐标系和模型坐标系36.设置车模型中每个小物体 castShadow = true37.Vue3 echarts 组件化使用 resizeObserver38.网页验证码的作用 *网页中几种常见验证码39.多个装饰器一起es6装饰器40.flex属性41.移动端兼容问题42.那什么是URL、URI、URN?43.threejs的坐标渲染和着色44.渲染管线45.着色器46.基于 three.js 加载器分别加载模型47.echarts自适应大屏方案 亲测有用48.js中关于class类的继承49.有趣的工具50.关于threejs中鼠标左右移动,左动看右边,右动看左边51.有趣的知识点threejs52.uniapp底层跨端原理53.防止XSS(跨站脚本攻击)漏洞54.启动vite和electron项目配置多个主进程55.九宫格css56.css伪类选择器57.uniapp关于uni.getUserProfile的使用58.uniapp有意思的api之openSetting59.处理flex布局60.uniapp登录板块封装(旧接口getUserInfo)61.uniapp获取用户信息62.在项目中使用UEditor碰到的几个问题63.一维数组转二位数组64.使用此函数对数组进行分块,并在最后一组添加特定的值65.如果win报错无法加载文件 C:\Users\xx\AppData\Roaming\npm\pnpm.ps1,因为在此系统上禁止运行脚本66.win系统执行脚本报错策略更改无法加载文件 C:\Users\xx\AppData\Roaming\npm\pnpm.ps1,因为在此系统上禁止运行脚本67.阅读时间缓存(快应用)68.uniapp去除button的边框69.uniapp中OnShow获取缓存
70.js图片懒加载,在不做分页的情况下的解决方案
71.width:100%与width:auto区别72.leetcode1047字符串反复去重(栈)73.记录一次uniapp使用scrollview74.微前端(矩阵项目)代码将单个文件合并到指定分支75.自适应高度的过渡76.实现下划线动画77.js不同类型比较78.登录后继续浏览之前的页面79.sse80.关于小说阅读前端翻页插件推荐turn.js81.数组扁平化82.好玩的vue组件83.DOMRect对象84.前端三大系列图解释85.js中关于return和if条件处理86.关于文心一言不能打开F12开发者工具87.js文字处理两端展示中间省略号88.[popover, select] el-popover内有select的时候在选择后会自动关闭89.说一下flex的属性90.vue3中404路由匹配规则91.shape-outside92.createRange表示文档中的一个范围——用于js判断文字添加省略号情况93.uniapp清除指定key缓存94.vue3+uniapp关于button的open-type无法生效95.uniapp+vue3 使用list触底+下拉96.diff算法vue97.动态修改manifest.json98.记录一下大小写导致的问题Intersection Observer API
1.注意点 一般都是后端返回数据,
用
this.$nextTick(() => {
this.handleScroll();
});
确保dom加载完成触发我们定制的handleScroll
handleScroll() {
const containerRect = this.$refs.container.getBoundingClientRect();
const observer = new IntersectionObserver((entries) => {
entries.forEach((entry) => {
if (entry.isIntersecting) {
const img = entry.target;
img.src = img.dataset.src;
observer.unobserve(img);
}
});
});
const imgs = this.$refs.container.querySelectorAll('img');
imgs.forEach((img) => {
observer.observe(img);
});
},
<template>
<view ref="container" @scroll="handleScroll">
<image v-for="image in images" :key="image.id" :src="image.src" data-src="加载时的占位图" lazy />
</view>
</template>
<style>
.container {
height: 100vh;
overflow-y: scroll;
}
</style>
Scroll Event
this.$nextTick(() => {
this.handleScroll();
});
handleScroll() {
const containerRect = this.$refs.container.getBoundingClientRect();
const imgs = this.$refs.container.querySelectorAll('img');
imgs.forEach((img) => {
const imgRect = img.getBoundingClientRect();
if (imgRect.top >= containerRect.top && imgRect.bottom <= containerRect.bottom) {
img.src = img.dataset.src;
}
});
},
<template>
<view ref="container" @scroll="handleScroll">
<image v-for="image in images" :key="image.id" :src="image.src" data-src="加载时的占位图" lazy />
</view>
</template>
<style>
.container {
height: 100vh;
overflow-y: scroll;
}
</style>
uni.createSelectorQuery
this.$nextTick(() => {
this.handleScroll();
});
handleScroll() {
const containerRect = uni.createSelectorQuery().select('.container').boundingClientRect();
const imgs = uni.createSelectorQuery().selectAll('.container image');
containerRect.exec((rect) => {
imgs.exec((nodes) => {
nodes.forEach((node, index) => {
const imgRect = node.boundingClientRect;
if (imgRect.top >= rect.top && imgRect.bottom <= rect.bottom) {
this.images[index].src = this.images[index].src; // 触发图片加载
}
});
});
});
},
注册全局指令
import lazyImg from './lazyImg';
Vue.directive('lazy-img', lazyImg);
// lazyImg.js
export default {
mounted(el, binding) {
const options = {
root: null,
rootMargin: '0px',
threshold: 0.1,
};
let hasLoaded = false; // 标记图片是否已加载
const observer = new IntersectionObserver((entries) => {
entries.forEach((entry) => {
if (entry.isIntersecting && !hasLoaded) { // 添加判断,当图片未加载时触发
const img = new Image();
img.src = binding.value;
img.onload = () => {
el.setAttribute('src', binding.value);
observer.unobserve(el);
hasLoaded = true; // 标记图片已加载
};
}
});
}, options);
observer.observe(el);
},
};
本文来自博客园,作者:jialiangzai,转载请注明原文链接:https://www.cnblogs.com/zsnhweb/p/17959817
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· TypeScript + Deepseek 打造卜卦网站:技术与玄学的结合
· Manus的开源复刻OpenManus初探
· AI 智能体引爆开源社区「GitHub 热点速览」
· C#/.NET/.NET Core技术前沿周刊 | 第 29 期(2025年3.1-3.9)
· 从HTTP原因短语缺失研究HTTP/2和HTTP/3的设计差异