大家都知道懒人加载可以让HTML5页面中的img图片可以在界面可见的时候进行显示,而不是一下子全部显示出来,极大的减缓了页面的加载效率和服务器的请求压力。
那么,在Agile中,通过给img设置data-source即可达到懒人加载的效果,这时候可以给img设置placeholder指明图片在请求完成之前显示的默认图片。
示例一:
<li class="table-view-cell media">
<a class="navigate-right">
<img class="media-object pull-left" data-source="http://yourdomain/test.png" data-type="base64" placeholder="../../image/42x42.gif">
<div class="media-body">
Item 1
<p>eeeeeeeeeeeeeeeeeeeeeeeeee</p>
</div>
</a>
</li>
示例二:
<li class="table-view-cell media">
<a class="navigate-right">
<img class="media-object pull-left" data-source="http://www.ExMobi.cn/images/common/qq-logo-dark.png" placeholder="../../image/42x42.gif">
<div class="media-body">
Item 1
<p>eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee</p>
</div>
</a>
</li>
可以看到上面示例一有个data-type="base64",指明这个data-source返回值需要是一个base64的编码,而示例二没有这个设置,默认是要求返回二进制流。
核心代码实现如下:
/**
* 初始化懒人加载组件
*/
var _init_lazyload = function(el){
var $el = $(el);
var source = $el.data(‘source‘);
if(!source){
$.map(_getMatchElements($el,SELECTOR.lazyload.selector),SELECTOR.lazyload.handler);
return;
}
var placeholder = $el.attr(‘placeholder‘)||A.settings.lazyloadPlaceholder;
if(!$el.attr(‘src‘)&&placeholder) $el.attr(‘src‘, placeholder);
var eTop = $el.offset().top;//元素的位置
var validateDistance = 100;
var winHeight = $(window).height()+validateDistance;
if(eTop<0||eTop>winHeight) return;
var _injectImg = function(data){
if(!$el.data(‘source‘)) return;
A.anim($el,‘fadeOut‘, 200, function(){
$el.attr(‘src‘, data);
$el.removeAttr(‘data-source‘);
_init_scroll($(‘section.active article[data-scroll]‘));
A.anim($el,‘fadeIn‘, 200);
});
};
var type = $el.data(‘type‘);
if(type==‘base64‘){
A.ajax({
url : source,
success : function(data){
_injectImg(data);
},
isBlock : false
});
}else{
var img = new Image();
img.src = source;
if(img.complete) {
_injectImg(source);
img = null;
}else{
img.onload = function(){
_injectImg(source);
img = null;
};
}
}
};
可以看到当data-type="base64"的时候实际上是发起了一个ajax请求得到编码后的信息设置到src里的,而非base64的类型则实例化img后将实例化src给原来的img(如何显示base64格式图片说明http://bbs.exmobi.cn/thread-3271-1-1.html)
这样就达到了图片加载完成后显示的功能。
好了,说到这我们有一个很重要的说明。
在ExMobi里有服务端的概念,即当我们要集成一个内网的系统的时候,经过服务端可以屏蔽内网的网络联接问题,让服务端的JSP去做与内网的交互,而客户端只需要联接到服务端即可。
那么使用webview或者browser控件来显示img就有个问题了。因为这两个控件都是依赖于系统浏览器的,系统浏览器只认系统本身的网络,如果网络是外部网络比如3G、4G,而不是内网,那么img就因网络不通显示不出来。
这时候就可以使用懒人加载来实现,这里就要求必须是data-type="base64",这时候给img设定一个data-source,并且设置ajax走服务端($util.ajax),即
A.launch({
showPageLoading : false,
isAutoRender : true,
crossDomainHandler : $util.ajax
});
这样就给data-source的地址配置mapp路由进到一个jsp,jsp需要请求完图片转换成base64编码,比如:
<%@ page language="java" import="java.util.*,com.fiberhome.bcs.appprocess.common.util.*"
contentType="application/uixml+xml; charset=UTF-8" pageEncoding="UTF-8"%>
<%@ include file="/client/adapt.jsp"%>
<!-- 这里需要传递一个url参数过来,为了示例这里写死了 -->
<aa:http id="img" url="http://www.exmobi.cn/images/common/qq-logo-dark.png"></aa:http>
<%
byte body[] = aa.rsp.getAttachBody("img");
sun.misc.BASE64Encoder encode = new sun.misc.BASE64Encoder();
String base64 = encode.encode(body);
System.out.println(base64);
%>
<%="data:image/png;base64,"+base64%>
这样就可以实现图片走服务端解析后返回浏览器内部显示。
原作者:http://bbs.exmobi.cn/forum.php?mod=viewthread&tid=3270&extra=page%253D1&page=1