webviewGroup.js 7.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286
  1. var webviewGroup = function(id, options) {
  2. this.id = id;
  3. this.options = options;
  4. this.styles = options.styles;
  5. this.items = options.items;
  6. this.onChange = options.onChange
  7. this.options.index = options.index || 0;
  8. this.webviews = {};
  9. this.webviewContexts = {};
  10. this.currentWebview = false;
  11. this._init();
  12. };
  13. var proto = webviewGroup.prototype;
  14. proto._init = function() {
  15. this._initParent();
  16. this._initNativeView();
  17. this._initWebviewContexts(this.options.index);
  18. };
  19. proto._initParent = function() {
  20. this.parent = plus.webview.getWebviewById(this.id);
  21. if(!this.parent) {
  22. this.parent = plus.webview.create(this.id, this.id);
  23. this.parent.show('none');
  24. }
  25. };
  26. proto._initNativeView = function() {
  27. // fixed by wmy 因为沉浸式应用,需要额外加上状态栏高度
  28. var statusbar_H = plus.navigator.getStatusbarHeight();
  29. this.nativeView = new plus.nativeObj.View('__MUI_TAB_NATIVE', {
  30. 'top': (83 + statusbar_H) +'px', //这个需要根据顶部导航及顶部选项卡高度自动调整
  31. 'height': (window.screen.height - 83)+"px",
  32. 'left': '100%',
  33. 'width': '100%',
  34. "backgroundColor":"#ffffff"
  35. });
  36. this.nativeView.show();
  37. };
  38. proto._initWebviewContexts = function() {
  39. for(var len = this.items.length, i = len - 1; i >= 0; i--) {
  40. var webviewOptions = this.items[i];
  41. var id = webviewOptions.id;
  42. var isFirst = i === 0;
  43. var isLast = i === (len - 1);
  44. var isCurrent = this.options.index === i;
  45. var extras = webviewOptions.extras;
  46. extras.__mui_url = webviewOptions.url;
  47. extras.__mui_index = i;
  48. extras.__mui_left = isFirst ? '' : this.items[i - 1].id;
  49. extras.__mui_right = isLast ? '' : this.items[i + 1].id;
  50. var styles = webviewOptions.styles || {};
  51. if(i > this.options.index) {
  52. styles.left = '100%';
  53. } else if(i < this.options.index) {
  54. styles.left = '-100%';
  55. } else {
  56. styles.left = '0';
  57. }
  58. var webviewContext = new webviewGroupContext(id, webviewOptions, this);
  59. this.webviewContexts[id] = webviewContext;
  60. if(isCurrent) {
  61. webviewContext.webview = plus.webview.getWebviewById(id);
  62. webviewContext.createWebview();
  63. webviewContext.webview.show("none");
  64. this._initDrags(webviewContext.webview);
  65. this.currentWebview = webviewContext.webview;
  66. }
  67. }
  68. };
  69. proto._onChange = function(webview) {
  70. this.currentWebview = webview;
  71. this.onChange({
  72. index: webview.__mui_index
  73. });
  74. };
  75. proto._dragCallback = function(dir, fromWebview, view, viewId) {
  76. if(view === this.nativeView) { //需要创建webview
  77. //第一步:初始化目标webview
  78. this.webviewContexts[viewId].createWebview('drag');
  79. var targetWebview = this.webviewContexts[viewId].webview;
  80. targetWebview.show();
  81. this.nativeView.setStyle({
  82. left: '100%'
  83. });
  84. //第二步:初始化目标webview的drag
  85. this._initDrags(targetWebview);
  86. this._onChange(targetWebview);
  87. //第三步:校验目标webview的左右webview的drag初始化
  88. this._checkDrags(targetWebview);
  89. } else {
  90. this._onChange(view);
  91. }
  92. };
  93. proto._initDrag = function(webview, dir) {
  94. var flag = ('__mui_drag_' + dir + '_flag');
  95. if(webview[flag]) {
  96. return;
  97. }
  98. var viewId = webview['__mui_' + (dir === 'left' ? 'right' : 'left')];
  99. if(viewId) {
  100. var view = plus.webview.getWebviewById(viewId);
  101. if(!view) { //如果目标webview不存在,使用nativeView替换
  102. view = this.nativeView;
  103. } else {
  104. webview[flag] = true;
  105. }
  106. webview.drag({
  107. 'direction': dir,
  108. 'moveMode': 'followFinger'
  109. }, {
  110. 'view': view,
  111. 'moveMode': 'follow'
  112. },
  113. function(res) {
  114. if(res.type === 'end' && res.result) { //拖拽完成
  115. this._dragCallback(dir, webview, view, viewId);
  116. }
  117. }.bind(this)
  118. )
  119. } else {
  120. webview[flag] = true;
  121. }
  122. };
  123. proto._initDrags = function(webview) {
  124. this._initDrag(webview, 'left');
  125. this._initDrag(webview, 'right');
  126. };
  127. proto._checkDrags = function(webview) {
  128. var left = webview.__mui_left;
  129. var right = webview.__mui_right;
  130. if(left) {
  131. var leftWebview = plus.webview.getWebviewById(left);
  132. if(leftWebview && !leftWebview.__mui_drag_left_flag) {
  133. this._initDrag(leftWebview, 'left');
  134. }
  135. }
  136. if(right) {
  137. var rightWebview = plus.webview.getWebviewById(right);
  138. if(rightWebview && !rightWebview.__mui_drag_right_flag) {
  139. this._initDrag(rightWebview, 'right');
  140. }
  141. }
  142. };
  143. proto.getCurrentWebview = function() {
  144. return this.currentWebview;
  145. };
  146. proto.getCurrentWebviewContext = function() {
  147. if(this.currentWebview) {
  148. return this.webviewContexts[this.currentWebview.id];
  149. }
  150. return false;
  151. };
  152. proto.switchTab = function(id) {
  153. id = id.replace('_0', ''); //首页需要替换为appid
  154. var fromWebview = this.currentWebview;
  155. if(id === fromWebview.id) {
  156. return;
  157. }
  158. var toWebviewContext = this.webviewContexts[id];
  159. var toWebview = toWebviewContext.webview;
  160. var fromToLeft = '100%';
  161. var toFromLeft = '-100%';
  162. if(toWebviewContext.options.extras.__mui_index > fromWebview.__mui_index) {
  163. fromToLeft = '-100%';
  164. toFromLeft = '100%';
  165. }
  166. var isNew = false;
  167. if(!toWebview) {
  168. isNew = true;
  169. toWebviewContext.createWebview('startAnimation');
  170. toWebview = toWebviewContext.webview;
  171. // toWebview.showBehind(plus.webview.getSecondWebview());
  172. toWebview.show();
  173. this._initDrags(toWebview);
  174. this._checkDrags(toWebview); //新建的时候均需校验
  175. }
  176. var self = this;
  177. // console.log("current:" + fromWebview.id + ",to:" + fromToLeft);
  178. // console.log("next:" + toWebview.id + ",from:" + toFromLeft);
  179. plus.webview.startAnimation({
  180. 'view': fromWebview,
  181. 'styles': {
  182. 'fromLeft': '0',
  183. 'toLeft': fromToLeft
  184. },
  185. 'action': 'show'
  186. }, {
  187. 'view': toWebview,
  188. 'styles': {
  189. 'fromLeft': toFromLeft,
  190. 'toLeft': '0'
  191. },
  192. 'action': 'show'
  193. },
  194. function(e) {
  195. //console.log("startAnimation callback...");
  196. if(e.id === toWebview.id) {
  197. isNew && plus.nativeUI.showWaiting();
  198. this.currentWebview = toWebview;
  199. this.onChange({
  200. index: toWebview.__mui_index
  201. });
  202. }
  203. }.bind(this)
  204. )
  205. };
  206. /**
  207. * @param {Object} id
  208. * @param {Object} webviewOptions
  209. */
  210. var webviewGroupContext = function(id, webviewOptions, groupContext) {
  211. this.id = id;
  212. this.url = webviewOptions.url;
  213. this.options = webviewOptions;
  214. this.groupContext = groupContext;
  215. this.webview = false;
  216. this.inited = false;
  217. };
  218. var _proto = webviewGroupContext.prototype;
  219. _proto.createWebview = function(from) {
  220. var options = this.options;
  221. options.styles = options.styles || {
  222. top: "83px",
  223. bottom: "0px",
  224. render: "always"
  225. };
  226. options.styles.popGesture = 'none';
  227. if(this.webview) {
  228. this.webview.setStyle(options.styles);
  229. for(var key in options.extras) {
  230. this.webview[key] = options.extras[key];
  231. }
  232. } else {
  233. options.styles.left = '100%';
  234. if(from !== 'startAnimation') {
  235. options.styles.left = '0';
  236. plus.nativeUI.showWaiting();
  237. }
  238. this.webview = plus.webview.create(this.url, this.id, options.styles, options.extras);
  239. //append进去,避免返回时闪屏
  240. plus.webview.currentWebview().append(this.webview);
  241. }
  242. this._initWebview();
  243. this.inited = true;
  244. };
  245. _proto._initWebview = function() {
  246. var options = this.options;
  247. if(!this.webview) {
  248. return;
  249. }
  250. this.webview.addEventListener('rendering', function() {
  251. setTimeout(function() {
  252. plus.nativeUI.closeWaiting();
  253. }, 500);
  254. });
  255. if(options.pullToRefresh && options.pullToRefresh.support && support.pullToRefresh()) {
  256. var callback = options.pullToRefresh.callback;
  257. this.webview.setPullToRefresh(options.pullToRefresh, function() {
  258. if(callback) { //如果指定了下拉回调
  259. callback(this.webview);
  260. } else { //下拉刷新回调,默认reload当前页面
  261. var self = this;
  262. var titleUpdate = function() {
  263. setTimeout(function() {
  264. self.webview.endPullToRefresh();
  265. }.bind(this), 1000);
  266. self.webview.removeEventListener('titleUpdate', titleUpdate);
  267. };
  268. this.webview.addEventListener('titleUpdate', titleUpdate);
  269. this.webview.reload();
  270. }
  271. }.bind(this));
  272. }
  273. };