1. /**
    2. * @description 图片base64加载
    3. * @author lizhouquan
    4. */
    5. bds.base64 = (function () {
    6. //获取base64前置参数
    7. var _opt = bds._base64;
    8. //内部数据;
    9. var _containerAllId = "container",
    10. _containerLeftId = "content_left",
    11. _containerRightId = "content_right",
    12. _BOTTAGLSNAME = "BASE64_BOTTAG",
    13. _domain = bds._base64.domain, //base64图片服务域名
    14. _imgWatch = [], //图片加载观察list,如果没有onload,进行容错
    15. _domLoaded = [], //标识对应dom是否已下载
    16. _data = [], //暂存请求回调数据
    17. _dataLoaded = [], //数据是否返回
    18. _finish = [], //是否已完成渲染
    19. _hasSpImg = false, //是否有左侧模板sp_img走base64加载
    20. _expGroup = 0, //左侧实验组
    21. _reqTime = 0, //请求开始时间
    22. _reqEnd = 0, //请求返回时间 - 右侧
    23. _reqEndL = 0, //请求返回时间 - 左侧
    24. _rsst = 0, //请求开始时间 - 测速
    25. _rest = 0, //请求返回时间 - 测速
    26. _dt = 1, //domain类型
    27. _loadState = {}, //记录imglist的状态
    28. _hasPreload = 0, //记录页面是否开启preload
    29. _ispdc = false; //是否开启了性能统计
    30. //异步下发起下次搜索时重置变量
    31. var preXhrs = [],$ = window.$;
    32. if($) {
    33. $(window).on("swap_begin",function(){
    34. _imgWatch = []; //图片加载观察list,如果没有onload,进行容错
    35. _domLoaded = []; //标识对应dom是否已下载
    36. _data = []; //暂存请求回调数据
    37. _dataLoaded = []; //数据是否返回
    38. _finish = []; //是否已完成渲染
    39. _hasSpImg = false; //是否有左侧模板sp_img走base64加载
    40. _expGroup = 0; //左侧实验组
    41. _reqTime = 0; //请求开始时间
    42. _reqEnd = 0; //请求返回时间 - 右侧
    43. _reqEndL = 0; //请求返回时间 - 左侧
    44. _rsst = 0; //请求开始时间 - 测速
    45. _rest = 0; //请求返回时间 - 测速
    46. _dt = 1; //domain类型
    47. _ispdc = false; //是否开启了性能统计
    48. //停止正在执行的base64回调操作
    49. for(var i = 0 ; i < preXhrs.length; i++) {
    50. preXhrs[i].abort();
    51. }
    52. });
    53. }
    54. //初始化方法
    55. var init = function(imgRight,imgLeft,isPreload){
    56. var imgArr = imgRight || [], imgArr2 = imgLeft || [];
    57. if(window.__IS_IMG_PREFETCH){
    58. //异步base64去重
    59. function filter(img){
    60. return !window.__IS_IMG_PREFETCH.hasOwnProperty(img);
    61. }
    62. imgArr=$.grep(imgArr,filter);
    63. imgArr2=$.grep(imgArr2,filter);
    64. }
    65. if(window.__IMG_PRELOAD && isPreload) {
    66. //定义loadState,防止callback乱序
    67. _loadState["cbr"] = 0;
    68. _loadState["cbpr"] = 0;
    69. _hasPreload = 1; //标记页面中有预取
    70. var imgPreloadList = window.__IMG_PRELOAD = {};
    71. for(var i = 0; i < imgArr.length; i++) {
    72. if(!imgPreloadList.hasOwnProperty(imgArr[i])) {
    73. window.__IMG_PRELOAD[imgArr[i]] = true;
    74. }
    75. }
    76. } else if(window.__IMG_PRELOAD && !isPreload) {
    77. //同步base64右侧去重
    78. var tmpArr = [];
    79. for(var i = 0; i < imgArr.length; i++){
    80. if(!window.__IMG_PRELOAD.hasOwnProperty(imgArr[i])) {
    81. tmpArr.push(imgArr[i]);
    82. }
    83. }
    84. imgArr = tmpArr;
    85. }
    86. if(_opt.b64Exp) {
    87. _expGroup = _opt.b64Exp;
    88. if(_expGroup == 1){
    89. _domain = "http://b2.bdstatic.com/"; /*base64 new domain sample deploy*/
    90. _dt = 2;
    91. }
    92. }
    93. _ispdc= _opt.pdc>0 ? true : false;
    94. _reqTime = new Date()*1;
    95. if(_expGroup==2){
    96. //左右分别发请求
    97. if(imgArr2.length>0){
    98. _hasSpImg = true;
    99. }
    100. if(!isPreload) {
    101. cbl({});
    102. }
    103. }
    104. if(imgArr.length>0){
    105. //发送请求
    106. if(_ispdc){
    107. if(bds.ready){
    108. bds.ready(function(){
    109. setTimeout(function(){
    110. var _bottag = botTag.get();
    111. var logstr = "dt=" + _dt + "&time=" + ((_reqEnd>0)?(_reqEnd-_reqTime):0) + "&bot=" + _bottag + "&rcount=" + imgArr.length;
    112. window._B64_REQ_LOG = ((_reqEnd>0)?(_reqEnd-_reqTime):0) + "_" + imgArr.length;
    113. if(_expGroup==2 && _reqEndL>0){
    114. var _apics = document.getElementById("ala_img_pics");
    115. var _lcount = (_apics&&_apics.children)?_apics.children.length:0;
    116. logstr += "&time2=" + (_reqEndL-_reqTime) + "&lcount=" + _lcount;
    117. }
    118. if(Math.random()*100<10){
    119. sendLog(logstr);
    120. }
    121. }, 2000);
    122. });
    123. }
    124. }
    125. } else {
    126. if(!isPreload) {
    127. cbr({});
    128. }
    129. }
    130. if(imgArr.length>0 || imgArr2.length>0){
    131. if(!isPreload) {
    132. watchReq(imgArr.length);
    133. }
    134. }
    135. };
    136. //异步加载js
    137. function crc32 (str) {
    138. if(typeof str=="string"){
    139. var i,crc=0,j=0;
    140. for(i=0;i<str.length;i++){
    141. j=i%20+1;
    142. crc+=str.charCodeAt(i)<<j;
    143. }
    144. return Math.abs(crc);
    145. }
    146. return 0;
    147. }
    148. var loadJs = function (url) {
    149. var matchs = url.match(/.*(bds\.base64\.cb[rl])/);
    150. if(!matchs){
    151. return;
    152. }
    153. var imglist=url.match(/imglist=([^&]*)/);
    154. if(!imglist||!imglist[1]){
    155. return;
    156. }
    157. //see b64_base_popstate.js, this just sync result page
    158. callback_name=crc32(imglist[1].replace(/,/g,""));
    159. callback_name="cb_"+(callback_name+"").substr(Math.max(0,callback_name.length-8),8)+"_0";
    160. window[callback_name]=function(data){
    161. if(matchs[1] == "bds.base64.cbr") {
    162. cbr(data);
    163. }else if(matchs[1] == "bds.base64.cbl") {
    164. cbl(data);
    165. }
    166. window[callback_name]=null;
    167. };
    168. var url = matchs[0].replace(/bds\.base64\.cb[rl]/,callback_name);
    169. var a = document.createElement("script");
    170. a.setAttribute("type", "text/javascript");
    171. a.setAttribute("src", url);
    172. a.setAttribute("defer", "defer");
    173. a.setAttribute("async", "true");
    174. document.getElementsByTagName("head")[0].appendChild(a);
    175. };
    176. //图片回填
    177. var imgLoad = function(data,side){
    178. if(_finish[side]){
    179. return;
    180. }
    181. _finish[side] = true;
    182. if(side=="right"){
    183. botTag.ot(false); //设置超时标记减1.
    184. }
    185. //获取所有图片,通过data-base64-id属性获取需要回填的图片
    186. var imgs = document.getElementById(_expGroup!=1?((side=="left")?_containerLeftId:_containerRightId):_containerAllId).getElementsByTagName("IMG");
    187. for(var i=0;i<imgs.length;i++){
    188. var b64Id = imgs[i].getAttribute("data-b64-id");
    189. if(b64Id){
    190. var find = false;
    191. if(data.hasOwnProperty(b64Id)) {
    192. setSrc(imgs[i],data[b64Id]);
    193. find = true;
    194. }
    195. if(!find){
    196. //小容错
    197. failover(imgs[i]);
    198. }
    199. }
    200. }
    201. fail_ie7();
    202. };
    203. function fail_ie7(){
    204. //外层容错 IE7
    205. setTimeout(function(){
    206. for( var i=0; i<_imgWatch.length; i++ ){
    207. var n = _imgWatch[i];
    208. if(!n.loaded){
    209. failover(n.obj);
    210. }
    211. }
    212. _imgWatch=[];
    213. },200);
    214. }
    215. function setSrc(img,data){
    216. try{
    217. img.onerror = function(){
    218. failover(this);
    219. };
    220. //标记监视,供容错检查
    221. _imgWatch.push({
    222. obj:img,
    223. loaded:false
    224. });
    225. img.onload = function(){
    226. //标记已加载
    227. for( var i=0; i<_imgWatch.length; i++ ){
    228. var m = _imgWatch[i];
    229. if(m.obj == this){
    230. m.loaded = true;
    231. }
    232. }
    233. };
    234. img.src = "data:image\/jpeg;base64," + data;
    235. }catch(e){
    236. //触发exception
    237. failover(img);
    238. }
    239. }
    240. //容错,回填原始src
    241. var failover = function(img){
    242. if(img.getAttribute("data-b64-id")!=null && img.getAttribute("data-b64-id")!="" && img.getAttribute("data-src")!=null){
    243. img.src = img.getAttribute("data-src");
    244. }
    245. };
    246. var watchReq = function(len){
    247. var wt = 1250;
    248. if(len<6){
    249. wt = 1000;
    250. }else if(len>10){
    251. wt = 1500;
    252. }
    253. setTimeout(function(){
    254. if( !_dataLoaded["right"] ){
    255. var imgs = document.getElementById(_containerRightId).getElementsByTagName("IMG");
    256. for(var i=0;i<imgs.length;i++){
    257. failover(imgs[i]);
    258. }
    259. _finish["right"] = true;
    260. //设置超时标记
    261. botTag.ot(true);
    262. }
    263. setTimeout(function(){
    264. if(_hasSpImg && !_dataLoaded["left"]){
    265. var imgs = document.getElementById(_containerLeftId).getElementsByTagName("IMG");
    266. for(var i=0;i<imgs.length;i++){
    267. failover(imgs[i]);
    268. }
    269. _finish["left"] = true;
    270. }
    271. },500);
    272. },wt);
    273. };
    274. /**
    275. * base64网速检测标记
    276. * 超时次数变量 BOT
    277. * 初始:0
    278. * 范围:0-6
    279. * 变换规则:
    280. * 每次超时,BOT +1;
    281. * 每次正常:BOT -1;
    282. * 到达边界值时,不再继续增加/减少
    283. * 如何使用:(未上线)
    284. * BOT大于3时,设置cookie: B64_BOT=1,VUI针对本次请求,读cookie,如果B64_BOT=1,关闭base64服务
    285. * 当BOT小于3时,设置cookie: B64_BOT=0,VUI正常开启base64服务。
    286. */
    287. var botTag = {
    288. ot : function(isInc){
    289. var _bottag = botTag.get();
    290. if(isInc){
    291. if(_bottag<6){
    292. _bottag++;
    293. }
    294. }else{
    295. if(_bottag>0){
    296. _bottag--;
    297. }
    298. }
    299. if( _bottag>=2 ){
    300. var date = new Date();
    301. date.setTime(date.getTime() + 24*3600*1000*5);
    302. //此处设置cookie
    303. document.cookie = "B64_BOT=1; expires=" + date.toGMTString();
    304. //_bottag = 0;
    305. }else if( _bottag<1 ){
    306. if(document.cookie.match('B64_BOT=1')){
    307. document.cookie = "B64_BOT=0;";
    308. }
    309. }
    310. try{
    311. if(window.localStorage){
    312. window.localStorage[_BOTTAGLSNAME] = _bottag;
    313. }
    314. }catch(e){}
    315. },
    316. get : function(){
    317. try{
    318. if(window.localStorage){
    319. var _bottag = window.localStorage[_BOTTAGLSNAME];
    320. _bottag = _bottag?parseInt(_bottag):0;