mui.init.5+.js 20 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702
  1. /**
  2. * mui.init 5+
  3. * @param {type} $
  4. * @returns {undefined}
  5. */
  6. (function($) {
  7. var defaultOptions = {
  8. swipeBack: false,
  9. preloadPages: [], //5+ lazyLoad webview
  10. preloadLimit: 10, //预加载窗口的数量限制(一旦超出,先进先出)
  11. keyEventBind: {
  12. backbutton: true,
  13. menubutton: true
  14. },
  15. titleConfig: {
  16. height: "44px",
  17. backgroundColor: "#f7f7f7", //导航栏背景色
  18. bottomBorderColor: "#cccccc", //底部边线颜色
  19. title: { //标题配置
  20. text: "", //标题文字
  21. position: {
  22. top: 0,
  23. left: 0,
  24. width: "100%",
  25. height: "100%"
  26. },
  27. styles: {
  28. color: "#000000",
  29. align: "center",
  30. family: "'Helvetica Neue',Helvetica,sans-serif",
  31. size: "17px",
  32. style: "normal",
  33. weight: "normal",
  34. fontSrc: ""
  35. }
  36. },
  37. back: {
  38. image: {
  39. base64Data: '',
  40. imgSrc: '',
  41. sprite: {
  42. top: '0px',
  43. left: '0px',
  44. width: '100%',
  45. height: '100%'
  46. },
  47. position: {
  48. top: "10px",
  49. left: "10px",
  50. width: "24px",
  51. height: "24px"
  52. }
  53. }
  54. }
  55. }
  56. };
  57. //默认页面动画
  58. var defaultShow = {
  59. event:"titleUpdate",
  60. autoShow: true,
  61. duration: 300,
  62. aniShow: 'slide-in-right',
  63. extras:{}
  64. };
  65. //若执行了显示动画初始化操作,则要覆盖默认配置
  66. if($.options.show) {
  67. defaultShow = $.extend(true, defaultShow, $.options.show);
  68. }
  69. $.currentWebview = null;
  70. $.extend(true, $.global, defaultOptions);
  71. $.extend(true, $.options, defaultOptions);
  72. /**
  73. * 等待动画配置
  74. * @param {type} options
  75. * @returns {Object}
  76. */
  77. $.waitingOptions = function(options) {
  78. return $.extend(true, {}, {
  79. autoShow: true,
  80. title: '',
  81. modal: false
  82. }, options);
  83. };
  84. /**
  85. * 窗口显示配置
  86. * @param {type} options
  87. * @returns {Object}
  88. */
  89. $.showOptions = function(options) {
  90. return $.extend(true, {}, defaultShow, options);
  91. };
  92. /**
  93. * 窗口默认配置
  94. * @param {type} options
  95. * @returns {Object}
  96. */
  97. $.windowOptions = function(options) {
  98. return $.extend({
  99. scalable: false,
  100. bounce: "" //vertical
  101. }, options);
  102. };
  103. /**
  104. * plusReady
  105. * @param {type} callback
  106. * @returns {_L6.$}
  107. */
  108. $.plusReady = function(callback) {
  109. if(window.plus) {
  110. setTimeout(function() { //解决callback与plusready事件的执行时机问题(典型案例:showWaiting,closeWaiting)
  111. callback();
  112. }, 0);
  113. } else {
  114. document.addEventListener("plusready", function() {
  115. callback();
  116. }, false);
  117. }
  118. return this;
  119. };
  120. /**
  121. * 5+ event(5+没提供之前我自己实现)
  122. * @param {type} webview
  123. * @param {type} eventType
  124. * @param {type} data
  125. * @returns {undefined}
  126. */
  127. $.fire = function(webview, eventType, data) {
  128. if(webview) {
  129. if(typeof data === 'undefined') {
  130. data = '';
  131. } else if(typeof data === 'boolean' || typeof data === 'number') {
  132. webview.evalJS("typeof mui!=='undefined'&&mui.receive('" + eventType + "'," + data + ")");
  133. return;
  134. } else if($.isPlainObject(data) || $.isArray(data)) {
  135. data = JSON.stringify(data || {}).replace(/\'/g, "\\u0027").replace(/\\/g, "\\u005c");
  136. }
  137. webview.evalJS("typeof mui!=='undefined'&&mui.receive('" + eventType + "','" + data + "')");
  138. }
  139. };
  140. /**
  141. * 5+ event(5+没提供之前我自己实现)
  142. * @param {type} eventType
  143. * @param {type} data
  144. * @returns {undefined}
  145. */
  146. $.receive = function(eventType, data) {
  147. if(eventType) {
  148. try {
  149. if(data && typeof data === 'string') {
  150. data = JSON.parse(data);
  151. }
  152. } catch(e) {}
  153. $.trigger(document, eventType, data);
  154. }
  155. };
  156. var triggerPreload = function(webview) {
  157. if(!webview.preloaded) { //保证仅触发一次
  158. $.fire(webview, 'preload');
  159. var list = webview.children();
  160. for(var i = 0; i < list.length; i++) {
  161. $.fire(list[i], 'preload');
  162. }
  163. webview.preloaded = true;
  164. }
  165. };
  166. var trigger = function(webview, eventType, timeChecked) {
  167. if(timeChecked) {
  168. if(!webview[eventType + 'ed']) {
  169. $.fire(webview, eventType);
  170. var list = webview.children();
  171. for(var i = 0; i < list.length; i++) {
  172. $.fire(list[i], eventType);
  173. }
  174. webview[eventType + 'ed'] = true;
  175. }
  176. } else {
  177. $.fire(webview, eventType);
  178. var list = webview.children();
  179. for(var i = 0; i < list.length; i++) {
  180. $.fire(list[i], eventType);
  181. }
  182. }
  183. };
  184. /**
  185. * 打开新窗口
  186. * @param {string} url 要打开的页面地址
  187. * @param {string} id 指定页面ID
  188. * @param {object} options 可选:参数,等待,窗口,显示配置{params:{},waiting:{},styles:{},show:{}}
  189. */
  190. $.openWindow = function(url, id, options) {
  191. if(typeof url === 'object') {
  192. options = url;
  193. url = options.url;
  194. id = options.id || url;
  195. } else {
  196. if(typeof id === 'object') {
  197. options = id;
  198. id = options.id || url;
  199. } else {
  200. id = id || url;
  201. }
  202. }
  203. if(!$.os.plus) {
  204. //TODO 先临时这么处理:手机上顶层跳,PC上parent跳
  205. if($.os.ios || $.os.android) {
  206. window.top.location.href = url;
  207. } else {
  208. window.parent.location.href = url;
  209. }
  210. return;
  211. }
  212. if(!window.plus) {
  213. return;
  214. }
  215. options = options || {};
  216. var params = options.params || {};
  217. var webview = null,
  218. webviewCache = null,
  219. nShow, nWaiting;
  220. if($.webviews[id]) {
  221. webviewCache = $.webviews[id];
  222. //webview真实存在,才能获取
  223. if(plus.webview.getWebviewById(id)) {
  224. webview = webviewCache.webview;
  225. }
  226. } else if(options.createNew !== true) {
  227. webview = plus.webview.getWebviewById(id);
  228. }
  229. if(webview) { //已缓存
  230. //每次show都需要传递动画参数;
  231. //预加载的动画参数优先级:openWindow配置>preloadPages配置>mui默认配置;
  232. nShow = webviewCache ? webviewCache.show : defaultShow;
  233. nShow = options.show ? $.extend(nShow, options.show) : nShow;
  234. nShow.autoShow && webview.show(nShow.aniShow, nShow.duration, function() {
  235. triggerPreload(webview);
  236. trigger(webview, 'pagebeforeshow', false);
  237. });
  238. if(webviewCache) {
  239. webviewCache.afterShowMethodName && webview.evalJS(webviewCache.afterShowMethodName + '(\'' + JSON.stringify(params) + '\')');
  240. }
  241. return webview;
  242. } else { //新窗口
  243. if(!url) {
  244. throw new Error('webview[' + id + '] does not exist');
  245. }
  246. //显示waiting
  247. var waitingConfig = $.waitingOptions(options.waiting);
  248. if(waitingConfig.autoShow) {
  249. nWaiting = plus.nativeUI.showWaiting(waitingConfig.title, waitingConfig.options);
  250. }
  251. //创建页面
  252. options = $.extend(options, {
  253. id: id,
  254. url: url
  255. });
  256. webview = $.createWindow(options);
  257. //显示
  258. nShow = $.showOptions(options.show);
  259. if(nShow.autoShow) {
  260. var showWebview = function() {
  261. //关闭等待框
  262. if(nWaiting) {
  263. nWaiting.close();
  264. }
  265. //显示页面
  266. webview.show(nShow.aniShow, nShow.duration, function() {},nShow.extras);
  267. options.afterShowMethodName && webview.evalJS(options.afterShowMethodName + '(\'' + JSON.stringify(params) + '\')');
  268. };
  269. //titleUpdate触发时机早于loaded,更换为titleUpdate后,可以更早的显示webview
  270. webview.addEventListener(nShow.event, showWebview, false);
  271. //loaded事件发生后,触发预加载和pagebeforeshow事件
  272. webview.addEventListener("loaded", function() {
  273. triggerPreload(webview);
  274. trigger(webview, 'pagebeforeshow', false);
  275. }, false);
  276. }
  277. }
  278. return webview;
  279. };
  280. $.openWindowWithTitle = function(options, titleConfig) {
  281. options = options || {};
  282. var url = options.url;
  283. var id = options.id || url;
  284. if(!$.os.plus) {
  285. //TODO 先临时这么处理:手机上顶层跳,PC上parent跳
  286. if($.os.ios || $.os.android) {
  287. window.top.location.href = url;
  288. } else {
  289. window.parent.location.href = url;
  290. }
  291. return;
  292. }
  293. if(!window.plus) {
  294. return;
  295. }
  296. var params = options.params || {};
  297. var webview = null,
  298. webviewCache = null,
  299. nShow, nWaiting;
  300. if($.webviews[id]) {
  301. webviewCache = $.webviews[id];
  302. //webview真实存在,才能获取
  303. if(plus.webview.getWebviewById(id)) {
  304. webview = webviewCache.webview;
  305. }
  306. } else if(options.createNew !== true) {
  307. webview = plus.webview.getWebviewById(id);
  308. }
  309. if(webview) { //已缓存
  310. //每次show都需要传递动画参数;
  311. //预加载的动画参数优先级:openWindow配置>preloadPages配置>mui默认配置;
  312. nShow = webviewCache ? webviewCache.show : defaultShow;
  313. nShow = options.show ? $.extend(nShow, options.show) : nShow;
  314. nShow.autoShow && webview.show(nShow.aniShow, nShow.duration, function() {
  315. triggerPreload(webview);
  316. trigger(webview, 'pagebeforeshow', false);
  317. });
  318. if(webviewCache) {
  319. webviewCache.afterShowMethodName && webview.evalJS(webviewCache.afterShowMethodName + '(\'' + JSON.stringify(params) + '\')');
  320. }
  321. return webview;
  322. } else { //新窗口
  323. if(!url) {
  324. throw new Error('webview[' + id + '] does not exist');
  325. }
  326. //显示waiting
  327. var waitingConfig = $.waitingOptions(options.waiting);
  328. if(waitingConfig.autoShow) {
  329. nWaiting = plus.nativeUI.showWaiting(waitingConfig.title, waitingConfig.options);
  330. }
  331. //创建页面
  332. options = $.extend(options, {
  333. id: id,
  334. url: url
  335. });
  336. webview = $.createWindow(options);
  337. if(titleConfig) { //处理原生头
  338. $.extend(true, $.options.titleConfig, titleConfig);
  339. var tid = $.options.titleConfig.id ? $.options.titleConfig.id : id + "_title";
  340. var view = new plus.nativeObj.View(tid, {
  341. top: 0,
  342. height: $.options.titleConfig.height,
  343. width: "100%",
  344. dock: "top",
  345. position: "dock"
  346. });
  347. view.drawRect($.options.titleConfig.backgroundColor); //绘制背景色
  348. var _b = parseInt($.options.titleConfig.height) - 1;
  349. view.drawRect($.options.titleConfig.bottomBorderColor, {
  350. top: _b + "px",
  351. left: "0px"
  352. }); //绘制底部边线
  353. //绘制文字
  354. if($.options.titleConfig.title.text){
  355. var _title = $.options.titleConfig.title;
  356. view.drawText(_title.text,_title.position , _title.styles);
  357. }
  358. //返回图标绘制
  359. var _back = $.options.titleConfig.back;
  360. var backClick = null;
  361. //优先字体
  362. //其次是图片
  363. var _backImage = _back.image;
  364. if(_backImage.base64Data || _backImage.imgSrc) {
  365. //TODO 此处需要处理百分比的情况
  366. backClick = {
  367. left:parseInt(_backImage.position.left),
  368. right:parseInt(_backImage.position.left) + parseInt(_backImage.position.width)
  369. };
  370. var bitmap = new plus.nativeObj.Bitmap(id + "_back");
  371. if(_backImage.base64Data) { //优先base64编码字符串
  372. bitmap.loadBase64Data(_backImage.base64Data);
  373. } else { //其次加载图片文件
  374. bitmap.load(_backImage.imgSrc);
  375. }
  376. view.drawBitmap(bitmap,_backImage.sprite , _backImage.position);
  377. }
  378. //处理点击事件
  379. view.setTouchEventRect({
  380. top: "0px",
  381. left: "0px",
  382. width: "100%",
  383. height: "100%"
  384. });
  385. view.interceptTouchEvent(true);
  386. view.addEventListener("click", function(e) {
  387. var x = e.clientX;
  388. //返回按钮点击
  389. if(backClick&& x > backClick.left && x < backClick.right){
  390. if( _back.click && $.isFunction(_back.click)){
  391. _back.click();
  392. }else{
  393. webview.evalJS("window.mui&&mui.back();");
  394. }
  395. }
  396. }, false);
  397. webview.append(view);
  398. }
  399. //显示
  400. nShow = $.showOptions(options.show);
  401. if(nShow.autoShow) {
  402. //titleUpdate触发时机早于loaded,更换为titleUpdate后,可以更早的显示webview
  403. webview.addEventListener(nShow.event, function () {
  404. //关闭等待框
  405. if(nWaiting) {
  406. nWaiting.close();
  407. }
  408. //显示页面
  409. webview.show(nShow.aniShow, nShow.duration, function() {},nShow.extras);
  410. }, false);
  411. }
  412. }
  413. return webview;
  414. };
  415. /**
  416. * 根据配置信息创建一个webview
  417. * @param {type} options
  418. * @param {type} isCreate
  419. * @returns {webview}
  420. */
  421. $.createWindow = function(options, isCreate) {
  422. if(!window.plus) {
  423. return;
  424. }
  425. var id = options.id || options.url;
  426. var webview;
  427. if(options.preload) {
  428. if($.webviews[id] && $.webviews[id].webview.getURL()) { //已经cache
  429. webview = $.webviews[id].webview;
  430. } else { //新增预加载窗口
  431. //判断是否携带createNew参数,默认为false
  432. if(options.createNew !== true) {
  433. webview = plus.webview.getWebviewById(id);
  434. }
  435. //之前没有,那就新创建
  436. if(!webview) {
  437. webview = plus.webview.create(options.url, id, $.windowOptions(options.styles), $.extend({
  438. preload: true
  439. }, options.extras));
  440. if(options.subpages) {
  441. $.each(options.subpages, function(index, subpage) {
  442. var subpageId = subpage.id || subpage.url;
  443. if(subpageId) { //过滤空对象
  444. var subWebview = plus.webview.getWebviewById(subpageId);
  445. if(!subWebview) { //如果该webview不存在,则创建
  446. subWebview = plus.webview.create(subpage.url, subpageId, $.windowOptions(subpage.styles), $.extend({
  447. preload: true
  448. }, subpage.extras));
  449. }
  450. webview.append(subWebview);
  451. }
  452. });
  453. }
  454. }
  455. }
  456. //TODO 理论上,子webview也应该计算到预加载队列中,但这样就麻烦了,要退必须退整体,否则可能出现问题;
  457. $.webviews[id] = {
  458. webview: webview, //目前仅preload的缓存webview
  459. preload: true,
  460. show: $.showOptions(options.show),
  461. afterShowMethodName: options.afterShowMethodName //就不应该用evalJS。应该是通过事件消息通讯
  462. };
  463. //索引该预加载窗口
  464. var preloads = $.data.preloads;
  465. var index = preloads.indexOf(id);
  466. if(~index) { //删除已存在的(变相调整插入位置)
  467. preloads.splice(index, 1);
  468. }
  469. preloads.push(id);
  470. if(preloads.length > $.options.preloadLimit) {
  471. //先进先出
  472. var first = $.data.preloads.shift();
  473. var webviewCache = $.webviews[first];
  474. if(webviewCache && webviewCache.webview) {
  475. //需要将自己打开的所有页面,全部close;
  476. //关闭该预加载webview
  477. $.closeAll(webviewCache.webview);
  478. }
  479. //删除缓存
  480. delete $.webviews[first];
  481. }
  482. } else {
  483. if(isCreate !== false) { //直接创建非预加载窗口
  484. webview = plus.webview.create(options.url, id, $.windowOptions(options.styles), options.extras);
  485. if(options.subpages) {
  486. $.each(options.subpages, function(index, subpage) {
  487. var subpageId = subpage.id || subpage.url;
  488. var subWebview = plus.webview.getWebviewById(subpageId);
  489. if(!subWebview) {
  490. subWebview = plus.webview.create(subpage.url, subpageId, $.windowOptions(subpage.styles), subpage.extras);
  491. }
  492. webview.append(subWebview);
  493. });
  494. }
  495. }
  496. }
  497. return webview;
  498. };
  499. /**
  500. * 预加载
  501. */
  502. $.preload = function(options) {
  503. //调用预加载函数,不管是否传递preload参数,强制变为true
  504. if(!options.preload) {
  505. options.preload = true;
  506. }
  507. return $.createWindow(options);
  508. };
  509. /**
  510. *关闭当前webview打开的所有webview;
  511. */
  512. $.closeOpened = function(webview) {
  513. var opened = webview.opened();
  514. if(opened) {
  515. for(var i = 0, len = opened.length; i < len; i++) {
  516. var openedWebview = opened[i];
  517. var open_open = openedWebview.opened();
  518. if(open_open && open_open.length > 0) {
  519. //关闭打开的webview
  520. $.closeOpened(openedWebview);
  521. //关闭自己
  522. openedWebview.close("none");
  523. } else {
  524. //如果直接孩子节点,就不用关闭了,因为父关闭的时候,会自动关闭子;
  525. if(openedWebview.parent() !== webview) {
  526. openedWebview.close('none');
  527. }
  528. }
  529. }
  530. }
  531. };
  532. $.closeAll = function(webview, aniShow) {
  533. $.closeOpened(webview);
  534. if(aniShow) {
  535. webview.close(aniShow);
  536. } else {
  537. webview.close();
  538. }
  539. };
  540. /**
  541. * 批量创建webview
  542. * @param {type} options
  543. * @returns {undefined}
  544. */
  545. $.createWindows = function(options) {
  546. $.each(options, function(index, option) {
  547. //初始化预加载窗口(创建)和非预加载窗口(仅配置,不创建)
  548. $.createWindow(option, false);
  549. });
  550. };
  551. /**
  552. * 创建当前页面的子webview
  553. * @param {type} options
  554. * @returns {webview}
  555. */
  556. $.appendWebview = function(options) {
  557. if(!window.plus) {
  558. return;
  559. }
  560. var id = options.id || options.url;
  561. var webview;
  562. if(!$.webviews[id]) { //保证执行一遍
  563. //TODO 这里也有隐患,比如某个webview不是作为subpage创建的,而是作为target webview的话;
  564. if(!plus.webview.getWebviewById(id)) {
  565. webview = plus.webview.create(options.url, id, options.styles, options.extras);
  566. }
  567. //之前的实现方案:子窗口loaded之后再append到父窗口中;
  568. //问题:部分子窗口loaded事件发生较晚,此时执行父窗口的children方法会返回空,导致父子通讯失败;
  569. // 比如父页面执行完preload事件后,需触发子页面的preload事件,此时未append的话,就无法触发;
  570. //修改方式:不再监控loaded事件,直接append
  571. //by chb@20150521
  572. // webview.addEventListener('loaded', function() {
  573. plus.webview.currentWebview().append(webview);
  574. // });
  575. $.webviews[id] = options;
  576. }
  577. return webview;
  578. };
  579. //全局webviews
  580. $.webviews = {};
  581. //预加载窗口索引
  582. $.data.preloads = [];
  583. //$.currentWebview
  584. $.plusReady(function() {
  585. $.currentWebview = plus.webview.currentWebview();
  586. });
  587. $.addInit({
  588. name: '5+',
  589. index: 100,
  590. handle: function() {
  591. var options = $.options;
  592. var subpages = options.subpages || [];
  593. if($.os.plus) {
  594. $.plusReady(function() {
  595. //TODO 这里需要判断一下,最好等子窗口加载完毕后,再调用主窗口的show方法;
  596. //或者:在openwindow方法中,监听实现;
  597. $.each(subpages, function(index, subpage) {
  598. $.appendWebview(subpage);
  599. });
  600. //判断是否首页
  601. if(plus.webview.currentWebview() === plus.webview.getWebviewById(plus.runtime.appid)) {
  602. //首页需要自己激活预加载;
  603. //timeout因为子页面loaded之后才append的,防止子页面尚未append、从而导致其preload未触发的问题;
  604. setTimeout(function() {
  605. triggerPreload(plus.webview.currentWebview());
  606. }, 300);
  607. }
  608. //设置ios顶部状态栏颜色;
  609. if($.os.ios && $.options.statusBarBackground) {
  610. plus.navigator.setStatusBarBackground($.options.statusBarBackground);
  611. }
  612. if($.os.android && parseFloat($.os.version) < 4.4) {
  613. //解决Android平台4.4版本以下,resume后,父窗体标题延迟渲染的问题;
  614. if(plus.webview.currentWebview().parent() == null) {
  615. document.addEventListener("resume", function() {
  616. var body = document.body;
  617. body.style.display = 'none';
  618. setTimeout(function() {
  619. body.style.display = '';
  620. }, 10);
  621. });
  622. }
  623. }
  624. });
  625. } else {
  626. //已支持iframe嵌入
  627. // if (subpages.length > 0) {
  628. // var err = document.createElement('div');
  629. // err.className = 'mui-error';
  630. // //文字描述
  631. // var span = document.createElement('span');
  632. // span.innerHTML = '在该浏览器下,不支持创建子页面,具体参考';
  633. // err.appendChild(span);
  634. // var a = document.createElement('a');
  635. // a.innerHTML = '"mui框架适用场景"';
  636. // a.href = 'http://ask.dcloud.net.cn/article/113';
  637. // err.appendChild(a);
  638. // document.body.appendChild(err);
  639. // console.log('在该浏览器下,不支持创建子页面');
  640. // }
  641. }
  642. }
  643. });
  644. window.addEventListener('preload', function() {
  645. //处理预加载部分
  646. var webviews = $.options.preloadPages || [];
  647. $.plusReady(function() {
  648. $.each(webviews, function(index, webview) {
  649. $.createWindow($.extend(webview, {
  650. preload: true
  651. }));
  652. });
  653. });
  654. });
  655. $.supportStatusbarOffset = function() {
  656. return $.os.plus && $.os.ios && parseFloat($.os.version) >= 7;
  657. };
  658. $.ready(function() {
  659. //标识当前环境支持statusbar
  660. if($.supportStatusbarOffset()) {
  661. document.body.classList.add($.className('statusbar'));
  662. }
  663. });
  664. })(mui);