example.js 10 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301
  1. /**
  2. * Created by jf on 2015/9/11.
  3. * Modified by bear on 2016/9/7.
  4. */
  5. const footerTmpl = $('#footerTmpl').html();
  6. $(function () {
  7. var pageManager = {
  8. $container: $('#container'),
  9. _pageStack: [],
  10. _configs: [],
  11. _pageAppend: function(){},
  12. _defaultPage: null,
  13. _pageIndex: 1,
  14. setDefault: function (defaultPage) {
  15. this._defaultPage = this._find('name', defaultPage);
  16. return this;
  17. },
  18. setPageAppend: function (pageAppend) {
  19. this._pageAppend = pageAppend;
  20. return this;
  21. },
  22. init: function () {
  23. var self = this;
  24. $(window).on('hashchange', function () {
  25. var state = history.state || {};
  26. var url = location.hash.indexOf('#') === 0 ? location.hash : '#';
  27. var page = self._find('url', url) || self._defaultPage;
  28. if (state._pageIndex <= self._pageIndex || self._findInStack(url)) {
  29. self._back(page);
  30. } else {
  31. self._go(page);
  32. }
  33. });
  34. if (history.state && history.state._pageIndex) {
  35. this._pageIndex = history.state._pageIndex;
  36. }
  37. this._pageIndex--;
  38. var url = location.hash.indexOf('#') === 0 ? location.hash : '#';
  39. var page = self._find('url', url) || self._defaultPage;
  40. this._go(page);
  41. return this;
  42. },
  43. push: function (config) {
  44. this._configs.push(config);
  45. return this;
  46. },
  47. go: function (to) {
  48. var config = this._find('name', to);
  49. if (!config) {
  50. return;
  51. }
  52. location.hash = config.url;
  53. },
  54. _go: function (config) {
  55. this._pageIndex ++;
  56. history.replaceState && history.replaceState({_pageIndex: this._pageIndex}, '', location.href);
  57. var html = $(config.template).html();
  58. var $html = $(html).addClass('slideIn').addClass(config.name);
  59. $html.on('animationend webkitAnimationEnd', function(){
  60. $html.removeClass('slideIn').addClass('js_show');
  61. });
  62. this.$container.append($html);
  63. this._pageAppend.call(this, $html);
  64. this._pageStack.push({
  65. config: config,
  66. dom: $html
  67. });
  68. if (!config.isBind) {
  69. this._bind(config);
  70. }
  71. return this;
  72. },
  73. back: function () {
  74. history.back();
  75. },
  76. _back: function (config) {
  77. this._pageIndex --;
  78. var stack = this._pageStack.pop();
  79. if (!stack) {
  80. return;
  81. }
  82. var url = location.hash.indexOf('#') === 0 ? location.hash : '#';
  83. var found = this._findInStack(url);
  84. if (!found) {
  85. var html = $(config.template).html();
  86. var $html = $(html).addClass('js_show').addClass(config.name);
  87. $html.insertBefore(stack.dom);
  88. if (!config.isBind) {
  89. this._bind(config);
  90. }
  91. this._pageStack.push({
  92. config: config,
  93. dom: $html
  94. });
  95. }
  96. stack.dom.addClass('slideOut').on('animationend webkitAnimationEnd', function () {
  97. stack.dom.remove();
  98. });
  99. return this;
  100. },
  101. _findInStack: function (url) {
  102. var found = null;
  103. for(var i = 0, len = this._pageStack.length; i < len; i++){
  104. var stack = this._pageStack[i];
  105. if (stack.config.url === url) {
  106. found = stack;
  107. break;
  108. }
  109. }
  110. return found;
  111. },
  112. _find: function (key, value) {
  113. var page = null;
  114. for (var i = 0, len = this._configs.length; i < len; i++) {
  115. if (this._configs[i][key] === value) {
  116. page = this._configs[i];
  117. break;
  118. }
  119. }
  120. return page;
  121. },
  122. _bind: function (page) {
  123. var events = page.events || {};
  124. for (var t in events) {
  125. for (var type in events[t]) {
  126. this.$container.on(type, t, events[t][type]);
  127. }
  128. }
  129. page.isBind = true;
  130. }
  131. };
  132. function fastClick(){
  133. var supportTouch = function(){
  134. try {
  135. document.createEvent("TouchEvent");
  136. return true;
  137. } catch (e) {
  138. return false;
  139. }
  140. }();
  141. var _old$On = $.fn.on;
  142. $.fn.on = function(){
  143. if(/click/.test(arguments[0]) && typeof arguments[1] == 'function' && supportTouch){ // 只扩展支持touch的当前元素的click事件
  144. var touchStartY, callback = arguments[1];
  145. _old$On.apply(this, ['touchstart', function(e){
  146. touchStartY = e.changedTouches[0].clientY;
  147. }]);
  148. _old$On.apply(this, ['touchend', function(e){
  149. if (Math.abs(e.changedTouches[0].clientY - touchStartY) > 10) return;
  150. e.preventDefault();
  151. callback.apply(this, [e]);
  152. }]);
  153. }else{
  154. _old$On.apply(this, arguments);
  155. }
  156. return this;
  157. };
  158. }
  159. function preload(){
  160. $(window).on("load", function(){
  161. var imgList = [
  162. "./images/layers/content.png",
  163. "./images/layers/navigation.png",
  164. "./images/layers/popout.png",
  165. "./images/layers/transparent.gif"
  166. ];
  167. for (var i = 0, len = imgList.length; i < len; ++i) {
  168. new Image().src = imgList[i];
  169. }
  170. });
  171. }
  172. function androidInputBugFix(){
  173. // .container 设置了 overflow 属性, 导致 Android 手机下输入框获取焦点时, 输入法挡住输入框的 bug
  174. // 相关 issue: https://github.com/weui/weui/issues/15
  175. // 解决方法:
  176. // 0. .container 去掉 overflow 属性, 但此 demo 下会引发别的问题
  177. // 1. 参考 http://stackoverflow.com/questions/23757345/android-does-not-correctly-scroll-on-input-focus-if-not-body-element
  178. // Android 手机下, input 或 textarea 元素聚焦时, 主动滚一把
  179. if (/Android/gi.test(navigator.userAgent)) {
  180. window.addEventListener('resize', function () {
  181. if (document.activeElement.tagName == 'INPUT' || document.activeElement.tagName == 'TEXTAREA') {
  182. window.setTimeout(function () {
  183. document.activeElement.scrollIntoViewIfNeeded();
  184. }, 0);
  185. }
  186. })
  187. }
  188. }
  189. function setJSAPI(){
  190. var option = {
  191. title: 'WeUI, 为微信 Web 服务量身设计',
  192. desc: 'WeUI, 为微信 Web 服务量身设计',
  193. link: "https://weui.io",
  194. imgUrl: 'https://mmbiz.qpic.cn/mmemoticon/ajNVdqHZLLA16apETUPXh9Q5GLpSic7lGuiaic0jqMt4UY8P4KHSBpEWgM7uMlbxxnVR7596b3NPjUfwg7cFbfCtA/0'
  195. };
  196. $.getJSON('https://weui.io/api/sign?url=' + encodeURIComponent(location.href.split('#')[0]), function (res) {
  197. wx.config({
  198. beta: true,
  199. debug: false,
  200. appId: res.appid,
  201. timestamp: res.timestamp,
  202. nonceStr: res.nonceStr,
  203. signature: res.signature,
  204. jsApiList: [
  205. 'onMenuShareTimeline',
  206. 'onMenuShareAppMessage',
  207. 'onMenuShareQQ',
  208. 'onMenuShareWeibo',
  209. 'onMenuShareQZone',
  210. // 'setNavigationBarColor',
  211. 'setBounceBackground'
  212. ]
  213. });
  214. wx.ready(function () {
  215. /*
  216. wx.invoke('setNavigationBarColor', {
  217. color: '#F8F8F8'
  218. });
  219. */
  220. wx.invoke('setBounceBackground', {
  221. 'backgroundColor': '#F8F8F8',
  222. 'footerBounceColor' : '#F8F8F8'
  223. });
  224. wx.onMenuShareTimeline(option);
  225. wx.onMenuShareQQ(option);
  226. wx.onMenuShareAppMessage({
  227. title: 'WeUI',
  228. desc: '为微信 Web 服务量身设计',
  229. link: location.href,
  230. imgUrl: 'https://mmbiz.qpic.cn/mmemoticon/ajNVdqHZLLA16apETUPXh9Q5GLpSic7lGuiaic0jqMt4UY8P4KHSBpEWgM7uMlbxxnVR7596b3NPjUfwg7cFbfCtA/0'
  231. });
  232. });
  233. });
  234. }
  235. function setPageManager(){
  236. var pages = {}, tpls = $('script[type="text/html"]');
  237. for (var i = 0, len = tpls.length; i < len; ++i) {
  238. var tpl = tpls[i], name = tpl.id.replace(/tpl_/, '');
  239. pages[name] = {
  240. name: name,
  241. url: '#' + name,
  242. template: '#' + tpl.id
  243. };
  244. }
  245. pages.home.url = '#';
  246. for (var page in pages) {
  247. pageManager.push(pages[page]);
  248. }
  249. pageManager
  250. .setPageAppend(function($html){
  251. $html.eq(0).append(footerTmpl);
  252. setTimeout(() => {
  253. var $foot = $html.find('.page__ft');
  254. if($foot.length < 1) return;
  255. var winH = $(window).height();
  256. if($foot.position().top + $foot.height() < winH){
  257. $foot.addClass('j_bottom');
  258. }else{
  259. $foot.removeClass('j_bottom');
  260. }
  261. });
  262. })
  263. .setDefault('home')
  264. .init();
  265. }
  266. function init(){
  267. preload();
  268. fastClick();
  269. androidInputBugFix();
  270. setJSAPI();
  271. setPageManager();
  272. window.pageManager = pageManager;
  273. window.home = function(){
  274. location.hash = '';
  275. };
  276. }
  277. init();
  278. });