最近在做一些前端页面,设计师给的效果图比较炫丽,为了达到页面的高还原度,不得不用js来控制页面的展示细节了。
现在的需求是,当渲染页面中那些需要加载外部地址数据的节点元素时,比如图片,在移动端往往需要自适应格局,而一些其他的页面元素,可能需要根据相关图片自适应后的大小后,来调整其自身的大小。
先是在网上搜了下解决方案,给的无非都是onload事件和complete状态判断,这两种解决方法我都试过,并不能很完美的解决我的需求。我先说说他们存在的问题,以下都用图片元素来做案例,调试环境是chrome浏览器,或许我研究的不够深入,若有不对的,欢迎大家一定要留言指正。共同学习。
1、onload方法。(图片加载完成后的触发事件)
浏览器对这个事件并不总是执行。只有在图片没有被缓存过时,才会执行。如果要用这个方法,是不是要配合页面头部no-cache呢,这点我没试,因为我觉得得不偿失。
(ps,当我本地开发,服务器和客户端在同一台机器上,onload事件却总是执行的。这点会不会是浏览器自身的策越就不得而知了。毕竟不能为了这个去研究浏览器的内核吧,还是得去找通用的兼容方案。)
接下来肯定有人会想到 new Image() 方法来让浏览器每次都去加载一下图片,但这个方法引入了另一个问题,new Image() 加载进来的图片是原图片的尺寸,而不是适应了页面大小之后的尺寸,已经违背了初衷。
2、complete状态判断(IE专属值)
这个不多说了,其实和上面是一路的。
不论我是在页面底部,在全局onload事件下,还是在全局onreday事件下,都不能完全命中自适应后的图片尺寸。
也就说图片缓存的情况,网络的情况,不同浏览器的情况,页面被调整大小的情况,都对自适应后的图片尺寸抓取时机会有影响。
与其纠结于寻找图片到底何时完整显示的事件或状态值,不如换个角度,用野蛮一点的方案来解决。
我的方案如下,先上代码。
//根据奖池外壳图片大小计算奖池元素高度
var show_prize_pool = function() {
var pool_light_h = $('img.pool_light').height();
//console.log(pool_light_h);
$('.prize_pool_item').css('height', pool_light_h / 3.5);
$('.prize_pool_item img').css('height', pool_light_h / 3.5 * 0.6);
$('.prize_pool_item p.prize_title').css('height', pool_light_h / 3.5 * 0.2);
$('.prize_pool_item p.prize_price').css('height', pool_light_h / 3.5 * 0.2);
$('.prize_pool_item .prize_pool_doButton img').css('height', pool_light_h / 3.5);
$('.prize_pool_item .prize_pool_doButton span').css('bottom', pool_light_h / 3.5 * 0.15);
$('.prize_pool_item').show();
if(pool_light_h>0){
clearInterval(global_timename4pool);
}
}
//由于无法判断图片显示完整的时机,只好用定时器来做,计算完成后再关掉定时器。
global_timename4pool = setInterval("show_prize_pool()",1500);
//页面大小改变后,要再次计算奖池元素的高度。
$(window).resize(function(){
show_prize_pool();
});
简单说明下:
1、$('img.pool_light')这个是一个图片,作为一个背景框,类似相框。
2、$('.prize_pool_item')这个是相框内的元素。
由于页面的尺寸不固定,相框的图片要根据宽度100%,高度自适应来不变形的展示相框图片。
但是相框内的元素在不知道相框高度的时候,是无法设置自身高度为一个合适的值,来很好的填充相框。
这种情况只能依靠js来动态计算。所有就有了上面的需求。
我的解决方案,就是用定时器间隔一段时间就去查找图片的高度是否出来了。直到得到想要的数据后,关掉定制器。在页面被改变大小后,再去执行一次。
经过测试,这个方案牺牲一点点页面性能,但是完美的解决了我的需求。若大家觉得适用,也试试吧。