网上大部分主流的瀑布流应用基本都是由后端在提供图片地址的同时提供图片宽高,这样,前端不必等待图片渲染完成,可以根据图片的宽高先把装载图片的容器或父节点先放上页面,完成基础性的布局,再让图片以渐变或其他方式逐步呈现。但如果前端在获取图片数据的同时无法得知其宽高,势必要遭遇很多尴尬的状况。
本文记述一些笔者在照片墙项目中,未知图片宽高的情况下,处理瀑布流的加载与阻止加载的一些方法。不知道是否有同道中人遇到过类似的情况,希望抛砖引玉,听取各位的想法和意见。
如果前端在图片渲染前不知道宽高,首先就意味着必须监听图片onload。onload 后才能知道图片宽高,onload callback才能把图片放上页面。这样一来,由于每张照片都要监听 onload , 瀑布加载的性能与效率就等于输在起跑线上,但貌似也只能监听onload。
监听onload 带来的麻烦:
由于 onload 的 callback函数是异步执行的,在切换照片的搜索条件,比如 性别,年龄,城市等,有可能会造成上一轮的照片还在加载,就会造成类似明明切换了女性的照片,但仍能看到几张男性照片的局面。如此一来,必须要在每次切换条件时,先阻止上一轮的图片加载,再开始加载新一轮。以下是兼容 ie 的阻止图片加载(下载)的代码:
参考:
http://stackoverflow.com/questions/3146200/stop-loading-of-images-on-a-hashchange-event-via-javascript-or-jquery
红色字体的请求代表被阻止下载的图片请求,Status 显示为 canceled。图片加载地越快,切换条件时需要停止的未加载的图片的数量就越少。
因 imgs 的 onload 做了如此多的麻烦事后,瀑布流加载在性能上也损失不少,是否有办法从别处弥补回一些损失。一般的照片墙,初始时向后端请求1屏,随着用户拉动滚动条至屏幕出现空白区域后,再向后端请求新一屏的照片数据,如此一来,尤其是当图片及ajax数据请求缓慢的情况下,势必会让用户的视觉在屏幕的空白区域停留过久,影响体验。那么是不是可以减少 http 请求数,比如后端一次性传 5 屏的数据,而前端 append 图片还是随着用户拉动滚动条,一屏一屏地来,其实就是图片的“懒加载”,即需即取,代码大略如下:
——获取数据时,可先将后端返回的每一张图片的地址保存在一个自建的图片属性中, 如:tmpsrc
——当用户拉动滚动条至屏幕出现空白区域后,再将一屏地图片附上正式的src,开始下载:
完!