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