navigator.iscroll.js 10 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203
  1. /**
  2. * @file 导航栏组件 - iScroll插件
  3. * @name Navigator.iscroll
  4. * @desc <qrcode align="right" title="Live Demo">../gmu/_examples/webapp/naivgator/navigator.html</qrcode>
  5. * navigator iscroll插件,可滚动导航栏
  6. * @import core/zepto.iscroll.js, widget/navigator.js
  7. */
  8. (function ($, undefined) {
  9. /**
  10. * @name navigator
  11. * @grammar navigator(options) ⇒ self
  12. * @grammar $.ui.navigator([el [,options]]) ⇒ instance
  13. * @desc
  14. * **Options**
  15. * navigator iscroll插件在原来options基础上增加以下参数
  16. * - ''disablePlugin'' {Boolean|String}: (可选, 默认false)是否禁用插件,加载了该插件,若需要禁用,可直接设为true
  17. * - ''isScrollToNext'' {Boolean}: (必选, 默认true)是否启用点击可视范围内第一个或最后一个跳动
  18. * - ''isShowShadow'' {Boolean}: (可选, 默认true)是否启用阴影
  19. * - ''iScrollOpts'' {Object}: (可选)配置iScroll中的参数,其中scrollstart,scrollmove,scrollend做为单独事件在组件中派生,可直接绑相应事件
  20. * - ''scrollstart'' {Function}: (可选)滑动前触发的事件,对应iScroll中的onScrollStart
  21. * - ''scrollmove'' {Function}: (可选)滑动中触发的事件,对应iScroll中的onScrollMove
  22. * - ''scrollend'' {Function}: (可选)滑动后触发的事件,对应iScroll中的onScrollEnd
  23. *
  24. * **setup方式html规则**
  25. * <code type="html">
  26. * <div id="nav-smartSetup">
  27. * <a class="ui-navigator-fixleft" href="#test1">fixleft</a> <!--固定元素,若没有,则不写,可写多个,左边加class="ui-navigator-fixleft"-->
  28. * <ul> <!--中间非固定tab-->
  29. * <li><a href="#test1">首页</a></li>
  30. * <li><a href="javascript:;">电影</a></li>
  31. * <li><a class="cur" href="javascript:;">电视剧</a></li>
  32. * </ul>
  33. * <a class="ui-navigator-fixleft" href="#test1">fixleft</a> <!--固定元素,若没有,则不写,可写多个,右边加class="ui-navigator-fixright"-->
  34. * </div>
  35. * </code>
  36. * **full setup方式html规则**
  37. * <code type="html"> <!--需将所有的class都写全-->
  38. * <div id="nav-smartSetup">
  39. * <a class="ui-navigator-fixleft ui-navigator-fix" href="#test1">fixleft</a> <!--固定元素,若没有,则不写,可写多个,左边加class="ui-navigator-fixleft"-->
  40. * <div class="ui-navigator-wrapper" style="overflow:hidden;">
  41. * <ul class="ui-navigator-list"> <!--中间非固定tab-->
  42. * <li><a href="#test1">首页</a></li>
  43. * <li><a href="javascript:;">电影</a></li>
  44. * <li><a class="cur" href="javascript:;">电视剧</a></li>
  45. * </ul>
  46. * </div>
  47. * <a class="ui-navigator-fixleft ui-navigator-fix" href="#test1">fixleft</a> <!--固定元素,若没有,则不写,可写多个,右边加class="ui-navigator-fixright"-->
  48. * </div>
  49. * </code>
  50. * **Demo**
  51. * <codepreview href="../gmu/_examples/widget/navigator/navigator.html">
  52. * ../gmu/_examples/widget/navigator/navigator.html
  53. * ../gmu/_examples/widget/navigator/navigator_fix.html
  54. * </codepreview>
  55. */
  56. $.ui.navigator.register(function () {
  57. return {
  58. pluginName: 'iscroll',
  59. _init: function () {
  60. return this._adjustHtml()._reBindEvent()._initOrg();
  61. },
  62. _reBindEvent: function () {
  63. var me = this,
  64. data = me._data;
  65. data.isScrollToNext = data.isScrollToNext === undefined ? true : data.isScrollToNext ;
  66. data.isShowShadow = data.isShowShadow === undefined ? true : data.isShowShadow;
  67. me._loadIscroll();
  68. $(window).on('ortchange', $.proxy(me._ortChangeHandler, me));
  69. me.on('destroy', function () {
  70. $(window).off('ortchange', me._ortChangeHandler);
  71. data.iScroll.destroy();
  72. });
  73. return me;
  74. },
  75. _adjustHtml: function () {
  76. var me = this,
  77. data = me._data,
  78. $el = me.root().addClass('ui-navigator'),
  79. $navScroller = $el.find('ul'),
  80. $navWrapper = $el.find('.ui-navigator-wrapper'),
  81. $navList = $navScroller.find('li'),
  82. scrollerSumWidth = [0];
  83. !$navWrapper.length && $navScroller.wrap('<div class="ui-navigator-wrapper"></div>'); //smart模式
  84. $navScroller.find('li').each(function (index) { //记录每个tab长度的累加和,为半个tab滑动用
  85. scrollerSumWidth[index] = index ? (scrollerSumWidth[index -1] + this.offsetWidth) :
  86. (scrollerSumWidth[index] + this.offsetLeft - $navScroller[0].offsetLeft + this.offsetWidth);
  87. });
  88. $.extend(data, {
  89. _$navWrapper: $el.find('.ui-navigator-wrapper'),
  90. _$navScroller: $navScroller.width(scrollerSumWidth[$navList.length - 1]),
  91. _$navList: $navList,
  92. _scrollerNum: $navList.length,
  93. _scrollerSumWidth: scrollerSumWidth,
  94. _$fixElemLeft: $el.find('.ui-navigator-fixleft'),
  95. _$fixElemRight: $el.find('.ui-navigator-fixright')
  96. });
  97. return me;
  98. },
  99. _loadIscroll:function () {
  100. var me = this,
  101. data = me._data;
  102. data.iScroll = iScroll(data._$navWrapper.get(0), data.iScrollOpts = $.extend({
  103. hScroll:true,
  104. vScroll:false,
  105. hScrollbar:false,
  106. vScrollbar:false
  107. }, data.iScrollOpts, {
  108. onScrollStart:function (e) {
  109. me.trigger('scrollstart', e);
  110. },
  111. onScrollMove:function (e) {
  112. me.trigger('scrollmove', e);
  113. },
  114. onScrollEnd:function (e) {
  115. data.isShowShadow && me._setShadow();
  116. me.trigger('scrollend', e);
  117. }
  118. }));
  119. return me;
  120. },
  121. _setShadow:function () {
  122. var me = this,
  123. data = me._data,
  124. $navWrapper = data._$navWrapper,
  125. shadowClass = {
  126. left: 'ui-navigator-shadowl',
  127. right: 'ui-navigator-shadowr',
  128. all: 'ui-navigator-shadowall'
  129. },
  130. iScroll = data.iScroll,
  131. movedX = iScroll.x;
  132. if (movedX < 0) {
  133. $navWrapper.removeClass(shadowClass['left'] + ' ' + shadowClass['right']).addClass(shadowClass['all']); //开始滑动时
  134. if (movedX <= iScroll.maxScrollX) { //向右滑动到最大
  135. $navWrapper.removeClass(shadowClass['all'] + ' ' + shadowClass['right']).addClass(shadowClass['left']);
  136. }
  137. } else { //向左滑动到最大
  138. $navWrapper.removeClass(shadowClass['all'] + ' ' + shadowClass['left']);
  139. //转屏后是否可滑动
  140. iScroll.hScroll ? $navWrapper.addClass(shadowClass['right']) : $navWrapper.removeClass(shadowClass['all'] + ' ' + shadowClass['left'] + ' ' +shadowClass['right']);
  141. }
  142. return me;
  143. },
  144. _scrollToNext: function (index, pos) {
  145. var me = this,
  146. data = me._data,
  147. scrollerSumWidth = data._scrollerSumWidth,
  148. iScroll = data.iScroll; //iscroll滚动的时间
  149. iScroll.scrollTo(pos == 'last' ? iScroll.wrapperW - (scrollerSumWidth[index + 1] || scrollerSumWidth[scrollerSumWidth.length - 1]) : pos == 'first' ? (-scrollerSumWidth[index - 2] || 0) : iScroll.x, 0, 400);
  150. return me;
  151. },
  152. _getPos:function (index) {
  153. var me = this,
  154. data = me._data,
  155. iScroll = data.iScroll,
  156. movedXDis = Math.abs(iScroll.x) || 0,
  157. scrollerSumWidth = data._scrollerSumWidth,
  158. $navList = data._$navList,
  159. thisOffsetDis = scrollerSumWidth[index] - movedXDis,
  160. preOffsetDis = scrollerSumWidth[(index - 1) || 0] - movedXDis,
  161. nextOffsetDis = (scrollerSumWidth[index + 1] || scrollerSumWidth[scrollerSumWidth.length - 1]) - movedXDis,
  162. wrapperWidth = iScroll.wrapperW;
  163. return (thisOffsetDis >= wrapperWidth || nextOffsetDis > wrapperWidth) ? //当前tab为半个tab或者其下一个tab为半个,则视为可显示区的最后一个
  164. 'last' : (thisOffsetDis <= $navList[index].offsetWidth || preOffsetDis < $navList[index - 1].offsetWidth) ? //当前tab为半个或者其前面的tab是半个,则视为可显示区的第一个
  165. 'first' : 'middle';
  166. },
  167. _ortChangeHandler:function () {
  168. var me = this,
  169. data = me._data,
  170. iScroll = data.iScroll;
  171. iScroll.refresh();
  172. me._setShadow(); //增加阴影的转屏处理 traceid:FEBASE-663
  173. data._$navWrapper.width(iScroll.wrapperW - iScroll.wrapperOffsetLeft);
  174. },
  175. switchTo: function (index, isDef, e) {
  176. var me = this,
  177. data = me._data;
  178. me.switchToOrg(index, isDef, e);
  179. if (!data._$tabList.eq(index).hasClass('ui-navigator-fix')) {
  180. var $fixElemLeft = data._$fixElemLeft,
  181. index = index - ($fixElemLeft.length ? $fixElemLeft.length : 0), //若存在左fix的元素,则滑动的tab的index需相应减去fix tab数量
  182. pos = me._getPos(index);
  183. isDef && data.isShowShadow && me._setShadow(); //默认defTab设置阴影
  184. data.isScrollToNext && me._scrollToNext(index, pos);
  185. }
  186. return me;
  187. }
  188. }
  189. });
  190. })(Zepto);