视频地址,或在bilibili,腾讯视频搜索【冰山工做室】浏览器
看到这个问题,咱们应该先想一下一般是如何处理图片加载失败的
若是图片加载失败时会触发 error 事件,那么就容易了,只要为每一个 img 标签添加上内联事件 onerror 就能够了微信
<img src="aaa.jpg" onerror="this.src='placeholder.jpg'">
可是不是还能够优化一下呢函数
<img src="aaa.jpg" onerror="errorHandler(this, event)"> <script> window.errorHandler = function(target, event){ target.src = 'placeholder.jpg'; } </script>
这彷佛已经知足题目的要求,可是真的没有可优化的地方了么?优化
以上两点在一些严格执行编码规范的团队中是不能接受的this
那么有什么办法呢?编码
由于 error 事件没法冒泡,可是事件传播只有冒泡一种方式么,还有捕获
查规范可知,error 事件是能够捕获的,那么就能够实现以下代码spa
function imgErrorHandler(){ window.addEventListener('error', function(e){ if( e.target.tagName === 'IMG' ){ e.target.src = 'placeholder.jpg'; } }, true); }
这样就能够不用担忧有人在 img 标签上漏写 onerror 内联事件了,由于根本不须要写了,也不会再暴露全局函数,只须要在页面渲染的过程当中执行一下上面的函数就能够了
接下来能够扩展一下功能:3d
必然存在不一样的场景下图片加载失败显示不一样的占位图的需求,那么咱们能够在 img 标签上添加一个 data-placeholder 属性,标明一下当前场景想要显示的占位图是什么
当彻底断网的时候,必然什么图片都没法加载,必然致使错误处理被无限触发,能够标记一个计数器,当达到指望的数值时中止继续请求,改成提供一个 Base64 的图片路径code
这样代码就扩展以下:视频
const PLACE_HOLDER_IMG_LIST = { default: 'placeholder.jpg' , offline: 'data:image/gif;base64,R0lGODlhAQABAIAAAAAAAP///yH5BAEAAAAALAAAAAABAAEAAAIBRAA7' , avatar: 'userAvatar.jpg' , photo: 'photo.jpg' } ; function imgErrorHandler(){ window.addEventListener('error', function(e){ let {target} = e , {placeholder = 'default', timer = 0} = target.dataset ; if( target.tagName === 'IMG' ){ timer = parseInt( timer ); if( timer < 3 ){ target.src = PLACE_HODLDER_IMG_LIST[placeholder]; target.dataset.timer = timer +1; } else{ target.src = PLACE_HOLDER_IMG_LIST.offline; } } }, true); }
扩展阅读
根据规范:Once the propagation path has been determined, the event object passes through one or more event phases. 一旦肯定了传播路径,事件对象就会经过一个或多个事件阶段。即每一个事件都会有捕获阶段,但不必定会有冒泡阶段。好比 focus、blur 事件都是不冒泡的,可是倒是能够被捕获的.随着 IE 浏览器逐渐退出历史舞台,传统的以事件冒泡的开发方式也许会发生改变.尤为在移动端,一些 touch 事件库已经使用捕获的方式来执行.捕获阶段必定会在冒泡阶段以前,因此理论上能更快的响应
同时你也能够关注咱们的微信公众号:冰山工做室
有兴趣的同窗能够破解咱们的二维码来加入社团:二维码破解处?不服来战