700字范文,内容丰富有趣,生活中的好帮手!
700字范文 > js实现一个回调 在页面内所有图片及后续动态插入的图片加载完成后(onload)执行

js实现一个回调 在页面内所有图片及后续动态插入的图片加载完成后(onload)执行

时间:2023-12-22 18:09:50

相关推荐

js实现一个回调 在页面内所有图片及后续动态插入的图片加载完成后(onload)执行

需求描述

架构:原生js及jQuery

需求:需要根据网页DOM及资源都加载后的布局(高度等)来调整页面

方案:监听图片的load事件,都加载完毕后,执行后续js逻辑

考虑到动态添加的dom中也可能存在图片,对这些图片也需要监听load事件

1 load事件绑定问题

1.1 在img标签中定义onload事件

...<img src="img/img_1_1.png" onload="testLoad()"/>...<script>testLoad = () => {console.log('loaded')}</script>

某些情况下不能稳定触发,尚未复现bug找到原因

另外,此方案需要对每个动态插入的img指定onload方法。

如要实现对 “所有图片加载完毕” 的判断,还需新增:计数、指定error方法等逻辑。代码复杂化,不可取

1.2 直接绑定img事件

...<img src="img/img_1_1.png"/>...<script>$('body').on('load', 'img', function(){console.log('loaded')})</script>

经过测试,无法通过on给img绑定load事件(click等事件可以),在$(document).ready()中绑定也无法生效。

没找到原因

$('img').on('load', testLoad)

只能监听当前DOM树中的img

2 方案

window.onload内执行后续js逻辑,确保dom及资源加载完毕

为动态添加的img逐一绑定load事件

...<img class="test-img" src="img/test.jpg"/>...<script>testLoad = (dom) => {console.log('loaded')}myfunc = () => {const imgList = [{'title': 'test1', 'src': 'img/test1.jpg'},{'title': 'test2', 'src': 'img/test2.jpg'},]imgList.forEach((img, idx) => {let tmpImgDom = $(`<img src="${img.src}"/>`)tmpImgDom.load(() => testLoad(tmpImgDom))$('body').append(tmpImgDom)})}$(window).load(){myfunc()}</script>

由于将逻辑放在window.onload中,可省去1.1.2的过程:原HTML页面中图片资源已经加载完毕,只需监听动态插入的图片资源即可

不利之处在于会延长页面的处理时间。由于动态加载的图片的高度决定着后续页面的处理,所以,准确监听图片加载状态是必须要做到的,没有更好方案的情况下只能在此延长一点时间。

3 代码

demo中的图片自行替换

<!DOCTYPE html><html><head><meta charset="utf-8"><meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1"><meta name="renderer" content="webkit"><meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1, user-scalable=no"><script src="/jquery-2.1.1.min.js"></script><style>img {height: 80px;display: block;margin-bottom:5px;}</style></head><body></body><script>let IMG_NUM = 0let IMG_ERR = false$(window).load(function(){myfunc(laterFunc)})// 动态插入img标签myfunc = (callback) => {const imgList = [{'title': 'test', 'img': 'img/test.jpg'},{'title': 'test1', 'img': 'img/test11.jpg'},{'title': 'test2', 'img': 'img/test2.jpg'},{'title': 'test3', 'img': 'img/test3.jpg'}]if(imgList.length > 0) {addImgDoms(imgList)} else {callback()}// 测试// 动态插入img、设定监听事件都是异步的// 多次动态插入操作之间的时间间隔不会导致countImgNum中IMG_NUM == 0的重复触发// addImgDoms([// {'title': 'test', 'img': 'img/test.jpg'},// {'title': 'test1', 'img': 'img/test1.jpg'},// ])// let tmpDate = new Date()// console.log(tmpDate.getSeconds() + '.' + tmpDate.getMilliseconds())// for(let i = 0; i < 1000000000; i++) {}// tmpDate = new Date()// console.log(tmpDate.getSeconds() + '.' + tmpDate.getMilliseconds())// addImgDoms([// {'title': 'test2', 'img': 'img/test2.jpg'},// {'title': 'test3', 'img': 'img/test3.jpg'},// ])}// 插入img标签addImgDoms = (list) => {list.forEach(img => {let tmpImgDom = $(`<img src="${img.img}" data-title="${img.title}"/>`)dealInsertImgDom(tmpImgDom)$('body').append(tmpImgDom)})}// 处理插入的imgdealInsertImgDom = (dom) => {IMG_NUM++dom.load(() => testLoad(dom))dom.error(() => testError(dom))}// 绑定load事件testLoad = (dom) => {console.log('loaded', dom.attr('data-title'))countImgNum()}// 绑定error事件testError = (dom) => {console.log('load error', dom.attr('data-title'))IMG_ERR = truecountImgNum()}// 倒计数countImgNum = () => {IMG_NUM--if(IMG_NUM == 0) {laterFunc()}}// 后续js逻辑laterFunc = () => {console.log('[end] has error:', IMG_ERR)}</script></html>

本内容不代表本网观点和政治立场,如有侵犯你的权益请联系我们处理。
网友评论
网友评论仅供其表达个人看法,并不表明网站立场。