Skip to content
Toggle navigation
P
Projects
G
Groups
S
Snippets
Help
php
/
maf
This project
Loading...
Sign in
Toggle navigation
Go to a project
Project
Repository
Issues
0
Merge Requests
0
Pipelines
Wiki
Members
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Commit
2137b070
authored
Jan 15, 2020
by
doszhang
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
dos
parent
060e76ec
Hide whitespace changes
Inline
Side-by-side
Showing
4 changed files
with
2100 additions
and
1 deletions
+2100
-1
Application/Home/View/default/Index_index.tpl
+2
-0
Public/static/js/._iscroll.js
+0
-0
Public/static/js/common.js
+7
-1
Public/static/js/iscroll.js
+2091
-0
No files found.
Application/Home/View/default/Index_index.tpl
View file @
2137b070
...
@@ -17,5 +17,6 @@
...
@@ -17,5 +17,6 @@
{:/block}
{:/block}
//js 文件导入
//js 文件导入
{:block name="js"}
{:block name="js"}
<script
src=
"__CDN__/js/iscroll.js"
></script>
<script
src=
"__CDN__/js/common.js"
></script>
<script
src=
"__CDN__/js/common.js"
></script>
{:/block}
{:/block}
\ No newline at end of file
Public/static/js/._iscroll.js
0 → 100644
View file @
2137b070
File added
Public/static/js/common.js
View file @
2137b070
...
@@ -70,6 +70,8 @@ let checkedRule = false;
...
@@ -70,6 +70,8 @@ let checkedRule = false;
//滚动防抖定时器
//滚动防抖定时器
let
timer
;
let
timer
;
let
myScroll
;
//记录初始状态下fontsize
//记录初始状态下fontsize
const
fontSize
=
parseFloat
(
$
(
'html'
).
css
(
'fontSize'
));
const
fontSize
=
parseFloat
(
$
(
'html'
).
css
(
'fontSize'
));
...
@@ -92,7 +94,7 @@ let posterCtx;
...
@@ -92,7 +94,7 @@ let posterCtx;
$
(
'input[name=tel]'
).
attr
(
'type'
,
'tel'
);
$
(
'input[name=tel]'
).
attr
(
'type'
,
'tel'
);
$
(
document
).
ready
(
function
()
{
$
(
document
).
ready
(
function
()
{
$
(
'.page
:not(.rule-page .rule-block)
'
).
on
(
'touchmove'
,
function
()
{
$
(
'.page'
).
on
(
'touchmove'
,
function
()
{
return
false
;
return
false
;
});
});
$
(
"input"
).
on
(
"blur"
,
function
()
{
$
(
"input"
).
on
(
"blur"
,
function
()
{
...
@@ -198,6 +200,10 @@ function ruleScroll() {
...
@@ -198,6 +200,10 @@ function ruleScroll() {
}
}
function
loaded
()
{
myScroll
=
new
IScroll
(
'#wrapper'
);
}
function
hideRule
()
{
function
hideRule
()
{
$
(
'.rule-page'
).
hide
();
$
(
'.rule-page'
).
hide
();
}
}
...
...
Public/static/js/iscroll.js
0 → 100644
View file @
2137b070
/*! iScroll v5.2.0 ~ (c) 2008-2016 Matteo Spinelli ~ http://cubiq.org/license */
(
function
(
window
,
document
,
Math
)
{
var
rAF
=
window
.
requestAnimationFrame
||
window
.
webkitRequestAnimationFrame
||
window
.
mozRequestAnimationFrame
||
window
.
oRequestAnimationFrame
||
window
.
msRequestAnimationFrame
||
function
(
callback
)
{
window
.
setTimeout
(
callback
,
1000
/
60
);
};
var
utils
=
(
function
()
{
var
me
=
{};
var
_elementStyle
=
document
.
createElement
(
'div'
).
style
;
var
_vendor
=
(
function
()
{
var
vendors
=
[
't'
,
'webkitT'
,
'MozT'
,
'msT'
,
'OT'
],
transform
,
i
=
0
,
l
=
vendors
.
length
;
for
(
;
i
<
l
;
i
++
)
{
transform
=
vendors
[
i
]
+
'ransform'
;
if
(
transform
in
_elementStyle
)
return
vendors
[
i
].
substr
(
0
,
vendors
[
i
].
length
-
1
);
}
return
false
;
})();
function
_prefixStyle
(
style
)
{
if
(
_vendor
===
false
)
return
false
;
if
(
_vendor
===
''
)
return
style
;
return
_vendor
+
style
.
charAt
(
0
).
toUpperCase
()
+
style
.
substr
(
1
);
}
me
.
getTime
=
Date
.
now
||
function
getTime
()
{
return
new
Date
().
getTime
();
};
me
.
extend
=
function
(
target
,
obj
)
{
for
(
var
i
in
obj
)
{
target
[
i
]
=
obj
[
i
];
}
};
me
.
addEvent
=
function
(
el
,
type
,
fn
,
capture
)
{
el
.
addEventListener
(
type
,
fn
,
!!
capture
);
};
me
.
removeEvent
=
function
(
el
,
type
,
fn
,
capture
)
{
el
.
removeEventListener
(
type
,
fn
,
!!
capture
);
};
me
.
prefixPointerEvent
=
function
(
pointerEvent
)
{
return
window
.
MSPointerEvent
?
'MSPointer'
+
pointerEvent
.
charAt
(
7
).
toUpperCase
()
+
pointerEvent
.
substr
(
8
):
pointerEvent
;
};
me
.
momentum
=
function
(
current
,
start
,
time
,
lowerMargin
,
wrapperSize
,
deceleration
)
{
var
distance
=
current
-
start
,
speed
=
Math
.
abs
(
distance
)
/
time
,
destination
,
duration
;
deceleration
=
deceleration
===
undefined
?
0.0006
:
deceleration
;
destination
=
current
+
(
speed
*
speed
)
/
(
2
*
deceleration
)
*
(
distance
<
0
?
-
1
:
1
);
duration
=
speed
/
deceleration
;
if
(
destination
<
lowerMargin
)
{
destination
=
wrapperSize
?
lowerMargin
-
(
wrapperSize
/
2.5
*
(
speed
/
8
)
)
:
lowerMargin
;
distance
=
Math
.
abs
(
destination
-
current
);
duration
=
distance
/
speed
;
}
else
if
(
destination
>
0
)
{
destination
=
wrapperSize
?
wrapperSize
/
2.5
*
(
speed
/
8
)
:
0
;
distance
=
Math
.
abs
(
current
)
+
destination
;
duration
=
distance
/
speed
;
}
return
{
destination
:
Math
.
round
(
destination
),
duration
:
duration
};
};
var
_transform
=
_prefixStyle
(
'transform'
);
me
.
extend
(
me
,
{
hasTransform
:
_transform
!==
false
,
hasPerspective
:
_prefixStyle
(
'perspective'
)
in
_elementStyle
,
hasTouch
:
'ontouchstart'
in
window
,
hasPointer
:
!!
(
window
.
PointerEvent
||
window
.
MSPointerEvent
),
// IE10 is prefixed
hasTransition
:
_prefixStyle
(
'transition'
)
in
_elementStyle
});
/*
This should find all Android browsers lower than build 535.19 (both stock browser and webview)
- galaxy S2 is ok
- 2.3.6 : `AppleWebKit/533.1 (KHTML, like Gecko) Version/4.0 Mobile Safari/533.1`
- 4.0.4 : `AppleWebKit/534.30 (KHTML, like Gecko) Version/4.0 Mobile Safari/534.30`
- galaxy S3 is badAndroid (stock brower, webview)
`AppleWebKit/534.30 (KHTML, like Gecko) Version/4.0 Mobile Safari/534.30`
- galaxy S4 is badAndroid (stock brower, webview)
`AppleWebKit/534.30 (KHTML, like Gecko) Version/4.0 Mobile Safari/534.30`
- galaxy S5 is OK
`AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Mobile Safari/537.36 (Chrome/)`
- galaxy S6 is OK
`AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Mobile Safari/537.36 (Chrome/)`
*/
me
.
isBadAndroid
=
(
function
()
{
var
appVersion
=
window
.
navigator
.
appVersion
;
// Android browser is not a chrome browser.
if
(
/Android/
.
test
(
appVersion
)
&&
!
(
/Chrome
\/\d
/
.
test
(
appVersion
)))
{
var
safariVersion
=
appVersion
.
match
(
/Safari
\/(\d
+.
\d)
/
);
if
(
safariVersion
&&
typeof
safariVersion
===
"object"
&&
safariVersion
.
length
>=
2
)
{
return
parseFloat
(
safariVersion
[
1
])
<
535.19
;
}
else
{
return
true
;
}
}
else
{
return
false
;
}
})();
me
.
extend
(
me
.
style
=
{},
{
transform
:
_transform
,
transitionTimingFunction
:
_prefixStyle
(
'transitionTimingFunction'
),
transitionDuration
:
_prefixStyle
(
'transitionDuration'
),
transitionDelay
:
_prefixStyle
(
'transitionDelay'
),
transformOrigin
:
_prefixStyle
(
'transformOrigin'
)
});
me
.
hasClass
=
function
(
e
,
c
)
{
var
re
=
new
RegExp
(
"(^|\\s)"
+
c
+
"(\\s|$)"
);
return
re
.
test
(
e
.
className
);
};
me
.
addClass
=
function
(
e
,
c
)
{
if
(
me
.
hasClass
(
e
,
c
)
)
{
return
;
}
var
newclass
=
e
.
className
.
split
(
' '
);
newclass
.
push
(
c
);
e
.
className
=
newclass
.
join
(
' '
);
};
me
.
removeClass
=
function
(
e
,
c
)
{
if
(
!
me
.
hasClass
(
e
,
c
)
)
{
return
;
}
var
re
=
new
RegExp
(
"(^|\\s)"
+
c
+
"(\\s|$)"
,
'g'
);
e
.
className
=
e
.
className
.
replace
(
re
,
' '
);
};
me
.
offset
=
function
(
el
)
{
var
left
=
-
el
.
offsetLeft
,
top
=
-
el
.
offsetTop
;
// jshint -W084
while
(
el
=
el
.
offsetParent
)
{
left
-=
el
.
offsetLeft
;
top
-=
el
.
offsetTop
;
}
// jshint +W084
return
{
left
:
left
,
top
:
top
};
};
me
.
preventDefaultException
=
function
(
el
,
exceptions
)
{
for
(
var
i
in
exceptions
)
{
if
(
exceptions
[
i
].
test
(
el
[
i
])
)
{
return
true
;
}
}
return
false
;
};
me
.
extend
(
me
.
eventType
=
{},
{
touchstart
:
1
,
touchmove
:
1
,
touchend
:
1
,
mousedown
:
2
,
mousemove
:
2
,
mouseup
:
2
,
pointerdown
:
3
,
pointermove
:
3
,
pointerup
:
3
,
MSPointerDown
:
3
,
MSPointerMove
:
3
,
MSPointerUp
:
3
});
me
.
extend
(
me
.
ease
=
{},
{
quadratic
:
{
style
:
'cubic-bezier(0.25, 0.46, 0.45, 0.94)'
,
fn
:
function
(
k
)
{
return
k
*
(
2
-
k
);
}
},
circular
:
{
style
:
'cubic-bezier(0.1, 0.57, 0.1, 1)'
,
// Not properly "circular" but this looks better, it should be (0.075, 0.82, 0.165, 1)
fn
:
function
(
k
)
{
return
Math
.
sqrt
(
1
-
(
--
k
*
k
)
);
}
},
back
:
{
style
:
'cubic-bezier(0.175, 0.885, 0.32, 1.275)'
,
fn
:
function
(
k
)
{
var
b
=
4
;
return
(
k
=
k
-
1
)
*
k
*
(
(
b
+
1
)
*
k
+
b
)
+
1
;
}
},
bounce
:
{
style
:
''
,
fn
:
function
(
k
)
{
if
(
(
k
/=
1
)
<
(
1
/
2.75
)
)
{
return
7.5625
*
k
*
k
;
}
else
if
(
k
<
(
2
/
2.75
)
)
{
return
7.5625
*
(
k
-=
(
1.5
/
2.75
)
)
*
k
+
0.75
;
}
else
if
(
k
<
(
2.5
/
2.75
)
)
{
return
7.5625
*
(
k
-=
(
2.25
/
2.75
)
)
*
k
+
0.9375
;
}
else
{
return
7.5625
*
(
k
-=
(
2.625
/
2.75
)
)
*
k
+
0.984375
;
}
}
},
elastic
:
{
style
:
''
,
fn
:
function
(
k
)
{
var
f
=
0.22
,
e
=
0.4
;
if
(
k
===
0
)
{
return
0
;
}
if
(
k
==
1
)
{
return
1
;
}
return
(
e
*
Math
.
pow
(
2
,
-
10
*
k
)
*
Math
.
sin
(
(
k
-
f
/
4
)
*
(
2
*
Math
.
PI
)
/
f
)
+
1
);
}
}
});
me
.
tap
=
function
(
e
,
eventName
)
{
var
ev
=
document
.
createEvent
(
'Event'
);
ev
.
initEvent
(
eventName
,
true
,
true
);
ev
.
pageX
=
e
.
pageX
;
ev
.
pageY
=
e
.
pageY
;
e
.
target
.
dispatchEvent
(
ev
);
};
me
.
click
=
function
(
e
)
{
var
target
=
e
.
target
,
ev
;
if
(
!
(
/
(
SELECT|INPUT|TEXTAREA
)
/i
).
test
(
target
.
tagName
)
)
{
ev
=
document
.
createEvent
(
'MouseEvents'
);
ev
.
initMouseEvent
(
'click'
,
true
,
true
,
e
.
view
,
1
,
target
.
screenX
,
target
.
screenY
,
target
.
clientX
,
target
.
clientY
,
e
.
ctrlKey
,
e
.
altKey
,
e
.
shiftKey
,
e
.
metaKey
,
0
,
null
);
ev
.
_constructed
=
true
;
target
.
dispatchEvent
(
ev
);
}
};
return
me
;
})();
function
IScroll
(
el
,
options
)
{
this
.
wrapper
=
typeof
el
==
'string'
?
document
.
querySelector
(
el
)
:
el
;
this
.
scroller
=
this
.
wrapper
.
children
[
0
];
this
.
scrollerStyle
=
this
.
scroller
.
style
;
// cache style for better performance
this
.
options
=
{
resizeScrollbars
:
true
,
mouseWheelSpeed
:
20
,
snapThreshold
:
0.334
,
// INSERT POINT: OPTIONS
disablePointer
:
!
utils
.
hasPointer
,
disableTouch
:
utils
.
hasPointer
||
!
utils
.
hasTouch
,
disableMouse
:
utils
.
hasPointer
||
utils
.
hasTouch
,
startX
:
0
,
startY
:
0
,
scrollY
:
true
,
directionLockThreshold
:
5
,
momentum
:
true
,
bounce
:
true
,
bounceTime
:
600
,
bounceEasing
:
''
,
preventDefault
:
true
,
preventDefaultException
:
{
tagName
:
/^
(
INPUT|TEXTAREA|BUTTON|SELECT
)
$/
},
HWCompositing
:
true
,
useTransition
:
true
,
useTransform
:
true
,
bindToWrapper
:
typeof
window
.
onmousedown
===
"undefined"
};
for
(
var
i
in
options
)
{
this
.
options
[
i
]
=
options
[
i
];
}
// Normalize options
this
.
translateZ
=
this
.
options
.
HWCompositing
&&
utils
.
hasPerspective
?
' translateZ(0)'
:
''
;
this
.
options
.
useTransition
=
utils
.
hasTransition
&&
this
.
options
.
useTransition
;
this
.
options
.
useTransform
=
utils
.
hasTransform
&&
this
.
options
.
useTransform
;
this
.
options
.
eventPassthrough
=
this
.
options
.
eventPassthrough
===
true
?
'vertical'
:
this
.
options
.
eventPassthrough
;
this
.
options
.
preventDefault
=
!
this
.
options
.
eventPassthrough
&&
this
.
options
.
preventDefault
;
// If you want eventPassthrough I have to lock one of the axes
this
.
options
.
scrollY
=
this
.
options
.
eventPassthrough
==
'vertical'
?
false
:
this
.
options
.
scrollY
;
this
.
options
.
scrollX
=
this
.
options
.
eventPassthrough
==
'horizontal'
?
false
:
this
.
options
.
scrollX
;
// With eventPassthrough we also need lockDirection mechanism
this
.
options
.
freeScroll
=
this
.
options
.
freeScroll
&&
!
this
.
options
.
eventPassthrough
;
this
.
options
.
directionLockThreshold
=
this
.
options
.
eventPassthrough
?
0
:
this
.
options
.
directionLockThreshold
;
this
.
options
.
bounceEasing
=
typeof
this
.
options
.
bounceEasing
==
'string'
?
utils
.
ease
[
this
.
options
.
bounceEasing
]
||
utils
.
ease
.
circular
:
this
.
options
.
bounceEasing
;
this
.
options
.
resizePolling
=
this
.
options
.
resizePolling
===
undefined
?
60
:
this
.
options
.
resizePolling
;
if
(
this
.
options
.
tap
===
true
)
{
this
.
options
.
tap
=
'tap'
;
}
if
(
this
.
options
.
shrinkScrollbars
==
'scale'
)
{
this
.
options
.
useTransition
=
false
;
}
this
.
options
.
invertWheelDirection
=
this
.
options
.
invertWheelDirection
?
-
1
:
1
;
// INSERT POINT: NORMALIZATION
// Some defaults
this
.
x
=
0
;
this
.
y
=
0
;
this
.
directionX
=
0
;
this
.
directionY
=
0
;
this
.
_events
=
{};
// INSERT POINT: DEFAULTS
this
.
_init
();
this
.
refresh
();
this
.
scrollTo
(
this
.
options
.
startX
,
this
.
options
.
startY
);
this
.
enable
();
}
IScroll
.
prototype
=
{
version
:
'5.2.0'
,
_init
:
function
()
{
this
.
_initEvents
();
if
(
this
.
options
.
scrollbars
||
this
.
options
.
indicators
)
{
this
.
_initIndicators
();
}
if
(
this
.
options
.
mouseWheel
)
{
this
.
_initWheel
();
}
if
(
this
.
options
.
snap
)
{
this
.
_initSnap
();
}
if
(
this
.
options
.
keyBindings
)
{
this
.
_initKeys
();
}
// INSERT POINT: _init
},
destroy
:
function
()
{
this
.
_initEvents
(
true
);
clearTimeout
(
this
.
resizeTimeout
);
this
.
resizeTimeout
=
null
;
this
.
_execEvent
(
'destroy'
);
},
_transitionEnd
:
function
(
e
)
{
if
(
e
.
target
!=
this
.
scroller
||
!
this
.
isInTransition
)
{
return
;
}
this
.
_transitionTime
();
if
(
!
this
.
resetPosition
(
this
.
options
.
bounceTime
)
)
{
this
.
isInTransition
=
false
;
this
.
_execEvent
(
'scrollEnd'
);
}
},
_start
:
function
(
e
)
{
// React to left mouse button only
if
(
utils
.
eventType
[
e
.
type
]
!=
1
)
{
// for button property
// http://unixpapa.com/js/mouse.html
var
button
;
if
(
!
e
.
which
)
{
/* IE case */
button
=
(
e
.
button
<
2
)
?
0
:
((
e
.
button
==
4
)
?
1
:
2
);
}
else
{
/* All others */
button
=
e
.
button
;
}
if
(
button
!==
0
)
{
return
;
}
}
if
(
!
this
.
enabled
||
(
this
.
initiated
&&
utils
.
eventType
[
e
.
type
]
!==
this
.
initiated
)
)
{
return
;
}
if
(
this
.
options
.
preventDefault
&&
!
utils
.
isBadAndroid
&&
!
utils
.
preventDefaultException
(
e
.
target
,
this
.
options
.
preventDefaultException
)
)
{
e
.
preventDefault
();
}
var
point
=
e
.
touches
?
e
.
touches
[
0
]
:
e
,
pos
;
this
.
initiated
=
utils
.
eventType
[
e
.
type
];
this
.
moved
=
false
;
this
.
distX
=
0
;
this
.
distY
=
0
;
this
.
directionX
=
0
;
this
.
directionY
=
0
;
this
.
directionLocked
=
0
;
this
.
startTime
=
utils
.
getTime
();
if
(
this
.
options
.
useTransition
&&
this
.
isInTransition
)
{
this
.
_transitionTime
();
this
.
isInTransition
=
false
;
pos
=
this
.
getComputedPosition
();
this
.
_translate
(
Math
.
round
(
pos
.
x
),
Math
.
round
(
pos
.
y
));
this
.
_execEvent
(
'scrollEnd'
);
}
else
if
(
!
this
.
options
.
useTransition
&&
this
.
isAnimating
)
{
this
.
isAnimating
=
false
;
this
.
_execEvent
(
'scrollEnd'
);
}
this
.
startX
=
this
.
x
;
this
.
startY
=
this
.
y
;
this
.
absStartX
=
this
.
x
;
this
.
absStartY
=
this
.
y
;
this
.
pointX
=
point
.
pageX
;
this
.
pointY
=
point
.
pageY
;
this
.
_execEvent
(
'beforeScrollStart'
);
},
_move
:
function
(
e
)
{
if
(
!
this
.
enabled
||
utils
.
eventType
[
e
.
type
]
!==
this
.
initiated
)
{
return
;
}
if
(
this
.
options
.
preventDefault
)
{
// increases performance on Android? TODO: check!
e
.
preventDefault
();
}
var
point
=
e
.
touches
?
e
.
touches
[
0
]
:
e
,
deltaX
=
point
.
pageX
-
this
.
pointX
,
deltaY
=
point
.
pageY
-
this
.
pointY
,
timestamp
=
utils
.
getTime
(),
newX
,
newY
,
absDistX
,
absDistY
;
this
.
pointX
=
point
.
pageX
;
this
.
pointY
=
point
.
pageY
;
this
.
distX
+=
deltaX
;
this
.
distY
+=
deltaY
;
absDistX
=
Math
.
abs
(
this
.
distX
);
absDistY
=
Math
.
abs
(
this
.
distY
);
// We need to move at least 10 pixels for the scrolling to initiate
if
(
timestamp
-
this
.
endTime
>
300
&&
(
absDistX
<
10
&&
absDistY
<
10
)
)
{
return
;
}
// If you are scrolling in one direction lock the other
if
(
!
this
.
directionLocked
&&
!
this
.
options
.
freeScroll
)
{
if
(
absDistX
>
absDistY
+
this
.
options
.
directionLockThreshold
)
{
this
.
directionLocked
=
'h'
;
// lock horizontally
}
else
if
(
absDistY
>=
absDistX
+
this
.
options
.
directionLockThreshold
)
{
this
.
directionLocked
=
'v'
;
// lock vertically
}
else
{
this
.
directionLocked
=
'n'
;
// no lock
}
}
if
(
this
.
directionLocked
==
'h'
)
{
if
(
this
.
options
.
eventPassthrough
==
'vertical'
)
{
e
.
preventDefault
();
}
else
if
(
this
.
options
.
eventPassthrough
==
'horizontal'
)
{
this
.
initiated
=
false
;
return
;
}
deltaY
=
0
;
}
else
if
(
this
.
directionLocked
==
'v'
)
{
if
(
this
.
options
.
eventPassthrough
==
'horizontal'
)
{
e
.
preventDefault
();
}
else
if
(
this
.
options
.
eventPassthrough
==
'vertical'
)
{
this
.
initiated
=
false
;
return
;
}
deltaX
=
0
;
}
deltaX
=
this
.
hasHorizontalScroll
?
deltaX
:
0
;
deltaY
=
this
.
hasVerticalScroll
?
deltaY
:
0
;
newX
=
this
.
x
+
deltaX
;
newY
=
this
.
y
+
deltaY
;
// Slow down if outside of the boundaries
if
(
newX
>
0
||
newX
<
this
.
maxScrollX
)
{
newX
=
this
.
options
.
bounce
?
this
.
x
+
deltaX
/
3
:
newX
>
0
?
0
:
this
.
maxScrollX
;
}
if
(
newY
>
0
||
newY
<
this
.
maxScrollY
)
{
newY
=
this
.
options
.
bounce
?
this
.
y
+
deltaY
/
3
:
newY
>
0
?
0
:
this
.
maxScrollY
;
}
this
.
directionX
=
deltaX
>
0
?
-
1
:
deltaX
<
0
?
1
:
0
;
this
.
directionY
=
deltaY
>
0
?
-
1
:
deltaY
<
0
?
1
:
0
;
if
(
!
this
.
moved
)
{
this
.
_execEvent
(
'scrollStart'
);
}
this
.
moved
=
true
;
this
.
_translate
(
newX
,
newY
);
/* REPLACE START: _move */
if
(
timestamp
-
this
.
startTime
>
300
)
{
this
.
startTime
=
timestamp
;
this
.
startX
=
this
.
x
;
this
.
startY
=
this
.
y
;
}
/* REPLACE END: _move */
},
_end
:
function
(
e
)
{
if
(
!
this
.
enabled
||
utils
.
eventType
[
e
.
type
]
!==
this
.
initiated
)
{
return
;
}
if
(
this
.
options
.
preventDefault
&&
!
utils
.
preventDefaultException
(
e
.
target
,
this
.
options
.
preventDefaultException
)
)
{
e
.
preventDefault
();
}
var
point
=
e
.
changedTouches
?
e
.
changedTouches
[
0
]
:
e
,
momentumX
,
momentumY
,
duration
=
utils
.
getTime
()
-
this
.
startTime
,
newX
=
Math
.
round
(
this
.
x
),
newY
=
Math
.
round
(
this
.
y
),
distanceX
=
Math
.
abs
(
newX
-
this
.
startX
),
distanceY
=
Math
.
abs
(
newY
-
this
.
startY
),
time
=
0
,
easing
=
''
;
this
.
isInTransition
=
0
;
this
.
initiated
=
0
;
this
.
endTime
=
utils
.
getTime
();
// reset if we are outside of the boundaries
if
(
this
.
resetPosition
(
this
.
options
.
bounceTime
)
)
{
return
;
}
this
.
scrollTo
(
newX
,
newY
);
// ensures that the last position is rounded
// we scrolled less than 10 pixels
if
(
!
this
.
moved
)
{
if
(
this
.
options
.
tap
)
{
utils
.
tap
(
e
,
this
.
options
.
tap
);
}
if
(
this
.
options
.
click
)
{
utils
.
click
(
e
);
}
this
.
_execEvent
(
'scrollCancel'
);
return
;
}
if
(
this
.
_events
.
flick
&&
duration
<
200
&&
distanceX
<
100
&&
distanceY
<
100
)
{
this
.
_execEvent
(
'flick'
);
return
;
}
// start momentum animation if needed
if
(
this
.
options
.
momentum
&&
duration
<
300
)
{
momentumX
=
this
.
hasHorizontalScroll
?
utils
.
momentum
(
this
.
x
,
this
.
startX
,
duration
,
this
.
maxScrollX
,
this
.
options
.
bounce
?
this
.
wrapperWidth
:
0
,
this
.
options
.
deceleration
)
:
{
destination
:
newX
,
duration
:
0
};
momentumY
=
this
.
hasVerticalScroll
?
utils
.
momentum
(
this
.
y
,
this
.
startY
,
duration
,
this
.
maxScrollY
,
this
.
options
.
bounce
?
this
.
wrapperHeight
:
0
,
this
.
options
.
deceleration
)
:
{
destination
:
newY
,
duration
:
0
};
newX
=
momentumX
.
destination
;
newY
=
momentumY
.
destination
;
time
=
Math
.
max
(
momentumX
.
duration
,
momentumY
.
duration
);
this
.
isInTransition
=
1
;
}
if
(
this
.
options
.
snap
)
{
var
snap
=
this
.
_nearestSnap
(
newX
,
newY
);
this
.
currentPage
=
snap
;
time
=
this
.
options
.
snapSpeed
||
Math
.
max
(
Math
.
max
(
Math
.
min
(
Math
.
abs
(
newX
-
snap
.
x
),
1000
),
Math
.
min
(
Math
.
abs
(
newY
-
snap
.
y
),
1000
)
),
300
);
newX
=
snap
.
x
;
newY
=
snap
.
y
;
this
.
directionX
=
0
;
this
.
directionY
=
0
;
easing
=
this
.
options
.
bounceEasing
;
}
// INSERT POINT: _end
if
(
newX
!=
this
.
x
||
newY
!=
this
.
y
)
{
// change easing function when scroller goes out of the boundaries
if
(
newX
>
0
||
newX
<
this
.
maxScrollX
||
newY
>
0
||
newY
<
this
.
maxScrollY
)
{
easing
=
utils
.
ease
.
quadratic
;
}
this
.
scrollTo
(
newX
,
newY
,
time
,
easing
);
return
;
}
this
.
_execEvent
(
'scrollEnd'
);
},
_resize
:
function
()
{
var
that
=
this
;
clearTimeout
(
this
.
resizeTimeout
);
this
.
resizeTimeout
=
setTimeout
(
function
()
{
that
.
refresh
();
},
this
.
options
.
resizePolling
);
},
resetPosition
:
function
(
time
)
{
var
x
=
this
.
x
,
y
=
this
.
y
;
time
=
time
||
0
;
if
(
!
this
.
hasHorizontalScroll
||
this
.
x
>
0
)
{
x
=
0
;
}
else
if
(
this
.
x
<
this
.
maxScrollX
)
{
x
=
this
.
maxScrollX
;
}
if
(
!
this
.
hasVerticalScroll
||
this
.
y
>
0
)
{
y
=
0
;
}
else
if
(
this
.
y
<
this
.
maxScrollY
)
{
y
=
this
.
maxScrollY
;
}
if
(
x
==
this
.
x
&&
y
==
this
.
y
)
{
return
false
;
}
this
.
scrollTo
(
x
,
y
,
time
,
this
.
options
.
bounceEasing
);
return
true
;
},
disable
:
function
()
{
this
.
enabled
=
false
;
},
enable
:
function
()
{
this
.
enabled
=
true
;
},
refresh
:
function
()
{
var
rf
=
this
.
wrapper
.
offsetHeight
;
// Force reflow
this
.
wrapperWidth
=
this
.
wrapper
.
clientWidth
;
this
.
wrapperHeight
=
this
.
wrapper
.
clientHeight
;
/* REPLACE START: refresh */
this
.
scrollerWidth
=
this
.
scroller
.
offsetWidth
;
this
.
scrollerHeight
=
this
.
scroller
.
offsetHeight
;
this
.
maxScrollX
=
this
.
wrapperWidth
-
this
.
scrollerWidth
;
this
.
maxScrollY
=
this
.
wrapperHeight
-
this
.
scrollerHeight
;
/* REPLACE END: refresh */
this
.
hasHorizontalScroll
=
this
.
options
.
scrollX
&&
this
.
maxScrollX
<
0
;
this
.
hasVerticalScroll
=
this
.
options
.
scrollY
&&
this
.
maxScrollY
<
0
;
if
(
!
this
.
hasHorizontalScroll
)
{
this
.
maxScrollX
=
0
;
this
.
scrollerWidth
=
this
.
wrapperWidth
;
}
if
(
!
this
.
hasVerticalScroll
)
{
this
.
maxScrollY
=
0
;
this
.
scrollerHeight
=
this
.
wrapperHeight
;
}
this
.
endTime
=
0
;
this
.
directionX
=
0
;
this
.
directionY
=
0
;
this
.
wrapperOffset
=
utils
.
offset
(
this
.
wrapper
);
this
.
_execEvent
(
'refresh'
);
this
.
resetPosition
();
// INSERT POINT: _refresh
},
on
:
function
(
type
,
fn
)
{
if
(
!
this
.
_events
[
type
]
)
{
this
.
_events
[
type
]
=
[];
}
this
.
_events
[
type
].
push
(
fn
);
},
off
:
function
(
type
,
fn
)
{
if
(
!
this
.
_events
[
type
]
)
{
return
;
}
var
index
=
this
.
_events
[
type
].
indexOf
(
fn
);
if
(
index
>
-
1
)
{
this
.
_events
[
type
].
splice
(
index
,
1
);
}
},
_execEvent
:
function
(
type
)
{
if
(
!
this
.
_events
[
type
]
)
{
return
;
}
var
i
=
0
,
l
=
this
.
_events
[
type
].
length
;
if
(
!
l
)
{
return
;
}
for
(
;
i
<
l
;
i
++
)
{
this
.
_events
[
type
][
i
].
apply
(
this
,
[].
slice
.
call
(
arguments
,
1
));
}
},
scrollBy
:
function
(
x
,
y
,
time
,
easing
)
{
x
=
this
.
x
+
x
;
y
=
this
.
y
+
y
;
time
=
time
||
0
;
this
.
scrollTo
(
x
,
y
,
time
,
easing
);
},
scrollTo
:
function
(
x
,
y
,
time
,
easing
)
{
easing
=
easing
||
utils
.
ease
.
circular
;
this
.
isInTransition
=
this
.
options
.
useTransition
&&
time
>
0
;
var
transitionType
=
this
.
options
.
useTransition
&&
easing
.
style
;
if
(
!
time
||
transitionType
)
{
if
(
transitionType
)
{
this
.
_transitionTimingFunction
(
easing
.
style
);
this
.
_transitionTime
(
time
);
}
this
.
_translate
(
x
,
y
);
}
else
{
this
.
_animate
(
x
,
y
,
time
,
easing
.
fn
);
}
},
scrollToElement
:
function
(
el
,
time
,
offsetX
,
offsetY
,
easing
)
{
el
=
el
.
nodeType
?
el
:
this
.
scroller
.
querySelector
(
el
);
if
(
!
el
)
{
return
;
}
var
pos
=
utils
.
offset
(
el
);
pos
.
left
-=
this
.
wrapperOffset
.
left
;
pos
.
top
-=
this
.
wrapperOffset
.
top
;
// if offsetX/Y are true we center the element to the screen
if
(
offsetX
===
true
)
{
offsetX
=
Math
.
round
(
el
.
offsetWidth
/
2
-
this
.
wrapper
.
offsetWidth
/
2
);
}
if
(
offsetY
===
true
)
{
offsetY
=
Math
.
round
(
el
.
offsetHeight
/
2
-
this
.
wrapper
.
offsetHeight
/
2
);
}
pos
.
left
-=
offsetX
||
0
;
pos
.
top
-=
offsetY
||
0
;
pos
.
left
=
pos
.
left
>
0
?
0
:
pos
.
left
<
this
.
maxScrollX
?
this
.
maxScrollX
:
pos
.
left
;
pos
.
top
=
pos
.
top
>
0
?
0
:
pos
.
top
<
this
.
maxScrollY
?
this
.
maxScrollY
:
pos
.
top
;
time
=
time
===
undefined
||
time
===
null
||
time
===
'auto'
?
Math
.
max
(
Math
.
abs
(
this
.
x
-
pos
.
left
),
Math
.
abs
(
this
.
y
-
pos
.
top
))
:
time
;
this
.
scrollTo
(
pos
.
left
,
pos
.
top
,
time
,
easing
);
},
_transitionTime
:
function
(
time
)
{
time
=
time
||
0
;
var
durationProp
=
utils
.
style
.
transitionDuration
;
this
.
scrollerStyle
[
durationProp
]
=
time
+
'ms'
;
if
(
!
time
&&
utils
.
isBadAndroid
)
{
this
.
scrollerStyle
[
durationProp
]
=
'0.0001ms'
;
// remove 0.0001ms
var
self
=
this
;
rAF
(
function
()
{
if
(
self
.
scrollerStyle
[
durationProp
]
===
'0.0001ms'
)
{
self
.
scrollerStyle
[
durationProp
]
=
'0s'
;
}
});
}
if
(
this
.
indicators
)
{
for
(
var
i
=
this
.
indicators
.
length
;
i
--
;
)
{
this
.
indicators
[
i
].
transitionTime
(
time
);
}
}
// INSERT POINT: _transitionTime
},
_transitionTimingFunction
:
function
(
easing
)
{
this
.
scrollerStyle
[
utils
.
style
.
transitionTimingFunction
]
=
easing
;
if
(
this
.
indicators
)
{
for
(
var
i
=
this
.
indicators
.
length
;
i
--
;
)
{
this
.
indicators
[
i
].
transitionTimingFunction
(
easing
);
}
}
// INSERT POINT: _transitionTimingFunction
},
_translate
:
function
(
x
,
y
)
{
if
(
this
.
options
.
useTransform
)
{
/* REPLACE START: _translate */
this
.
scrollerStyle
[
utils
.
style
.
transform
]
=
'translate('
+
x
+
'px,'
+
y
+
'px)'
+
this
.
translateZ
;
/* REPLACE END: _translate */
}
else
{
x
=
Math
.
round
(
x
);
y
=
Math
.
round
(
y
);
this
.
scrollerStyle
.
left
=
x
+
'px'
;
this
.
scrollerStyle
.
top
=
y
+
'px'
;
}
this
.
x
=
x
;
this
.
y
=
y
;
if
(
this
.
indicators
)
{
for
(
var
i
=
this
.
indicators
.
length
;
i
--
;
)
{
this
.
indicators
[
i
].
updatePosition
();
}
}
// INSERT POINT: _translate
},
_initEvents
:
function
(
remove
)
{
var
eventType
=
remove
?
utils
.
removeEvent
:
utils
.
addEvent
,
target
=
this
.
options
.
bindToWrapper
?
this
.
wrapper
:
window
;
eventType
(
window
,
'orientationchange'
,
this
);
eventType
(
window
,
'resize'
,
this
);
if
(
this
.
options
.
click
)
{
eventType
(
this
.
wrapper
,
'click'
,
this
,
true
);
}
if
(
!
this
.
options
.
disableMouse
)
{
eventType
(
this
.
wrapper
,
'mousedown'
,
this
);
eventType
(
target
,
'mousemove'
,
this
);
eventType
(
target
,
'mousecancel'
,
this
);
eventType
(
target
,
'mouseup'
,
this
);
}
if
(
utils
.
hasPointer
&&
!
this
.
options
.
disablePointer
)
{
eventType
(
this
.
wrapper
,
utils
.
prefixPointerEvent
(
'pointerdown'
),
this
);
eventType
(
target
,
utils
.
prefixPointerEvent
(
'pointermove'
),
this
);
eventType
(
target
,
utils
.
prefixPointerEvent
(
'pointercancel'
),
this
);
eventType
(
target
,
utils
.
prefixPointerEvent
(
'pointerup'
),
this
);
}
if
(
utils
.
hasTouch
&&
!
this
.
options
.
disableTouch
)
{
eventType
(
this
.
wrapper
,
'touchstart'
,
this
);
eventType
(
target
,
'touchmove'
,
this
);
eventType
(
target
,
'touchcancel'
,
this
);
eventType
(
target
,
'touchend'
,
this
);
}
eventType
(
this
.
scroller
,
'transitionend'
,
this
);
eventType
(
this
.
scroller
,
'webkitTransitionEnd'
,
this
);
eventType
(
this
.
scroller
,
'oTransitionEnd'
,
this
);
eventType
(
this
.
scroller
,
'MSTransitionEnd'
,
this
);
},
getComputedPosition
:
function
()
{
var
matrix
=
window
.
getComputedStyle
(
this
.
scroller
,
null
),
x
,
y
;
if
(
this
.
options
.
useTransform
)
{
matrix
=
matrix
[
utils
.
style
.
transform
].
split
(
')'
)[
0
].
split
(
', '
);
x
=
+
(
matrix
[
12
]
||
matrix
[
4
]);
y
=
+
(
matrix
[
13
]
||
matrix
[
5
]);
}
else
{
x
=
+
matrix
.
left
.
replace
(
/
[^
-
\d
.
]
/g
,
''
);
y
=
+
matrix
.
top
.
replace
(
/
[^
-
\d
.
]
/g
,
''
);
}
return
{
x
:
x
,
y
:
y
};
},
_initIndicators
:
function
()
{
var
interactive
=
this
.
options
.
interactiveScrollbars
,
customStyle
=
typeof
this
.
options
.
scrollbars
!=
'string'
,
indicators
=
[],
indicator
;
var
that
=
this
;
this
.
indicators
=
[];
if
(
this
.
options
.
scrollbars
)
{
// Vertical scrollbar
if
(
this
.
options
.
scrollY
)
{
indicator
=
{
el
:
createDefaultScrollbar
(
'v'
,
interactive
,
this
.
options
.
scrollbars
),
interactive
:
interactive
,
defaultScrollbars
:
true
,
customStyle
:
customStyle
,
resize
:
this
.
options
.
resizeScrollbars
,
shrink
:
this
.
options
.
shrinkScrollbars
,
fade
:
this
.
options
.
fadeScrollbars
,
listenX
:
false
};
this
.
wrapper
.
appendChild
(
indicator
.
el
);
indicators
.
push
(
indicator
);
}
// Horizontal scrollbar
if
(
this
.
options
.
scrollX
)
{
indicator
=
{
el
:
createDefaultScrollbar
(
'h'
,
interactive
,
this
.
options
.
scrollbars
),
interactive
:
interactive
,
defaultScrollbars
:
true
,
customStyle
:
customStyle
,
resize
:
this
.
options
.
resizeScrollbars
,
shrink
:
this
.
options
.
shrinkScrollbars
,
fade
:
this
.
options
.
fadeScrollbars
,
listenY
:
false
};
this
.
wrapper
.
appendChild
(
indicator
.
el
);
indicators
.
push
(
indicator
);
}
}
if
(
this
.
options
.
indicators
)
{
// TODO: check concat compatibility
indicators
=
indicators
.
concat
(
this
.
options
.
indicators
);
}
for
(
var
i
=
indicators
.
length
;
i
--
;
)
{
this
.
indicators
.
push
(
new
Indicator
(
this
,
indicators
[
i
])
);
}
// TODO: check if we can use array.map (wide compatibility and performance issues)
function
_indicatorsMap
(
fn
)
{
if
(
that
.
indicators
)
{
for
(
var
i
=
that
.
indicators
.
length
;
i
--
;
)
{
fn
.
call
(
that
.
indicators
[
i
]);
}
}
}
if
(
this
.
options
.
fadeScrollbars
)
{
this
.
on
(
'scrollEnd'
,
function
()
{
_indicatorsMap
(
function
()
{
this
.
fade
();
});
});
this
.
on
(
'scrollCancel'
,
function
()
{
_indicatorsMap
(
function
()
{
this
.
fade
();
});
});
this
.
on
(
'scrollStart'
,
function
()
{
_indicatorsMap
(
function
()
{
this
.
fade
(
1
);
});
});
this
.
on
(
'beforeScrollStart'
,
function
()
{
_indicatorsMap
(
function
()
{
this
.
fade
(
1
,
true
);
});
});
}
this
.
on
(
'refresh'
,
function
()
{
_indicatorsMap
(
function
()
{
this
.
refresh
();
});
});
this
.
on
(
'destroy'
,
function
()
{
_indicatorsMap
(
function
()
{
this
.
destroy
();
});
delete
this
.
indicators
;
});
},
_initWheel
:
function
()
{
utils
.
addEvent
(
this
.
wrapper
,
'wheel'
,
this
);
utils
.
addEvent
(
this
.
wrapper
,
'mousewheel'
,
this
);
utils
.
addEvent
(
this
.
wrapper
,
'DOMMouseScroll'
,
this
);
this
.
on
(
'destroy'
,
function
()
{
clearTimeout
(
this
.
wheelTimeout
);
this
.
wheelTimeout
=
null
;
utils
.
removeEvent
(
this
.
wrapper
,
'wheel'
,
this
);
utils
.
removeEvent
(
this
.
wrapper
,
'mousewheel'
,
this
);
utils
.
removeEvent
(
this
.
wrapper
,
'DOMMouseScroll'
,
this
);
});
},
_wheel
:
function
(
e
)
{
if
(
!
this
.
enabled
)
{
return
;
}
e
.
preventDefault
();
var
wheelDeltaX
,
wheelDeltaY
,
newX
,
newY
,
that
=
this
;
if
(
this
.
wheelTimeout
===
undefined
)
{
that
.
_execEvent
(
'scrollStart'
);
}
// Execute the scrollEnd event after 400ms the wheel stopped scrolling
clearTimeout
(
this
.
wheelTimeout
);
this
.
wheelTimeout
=
setTimeout
(
function
()
{
if
(
!
that
.
options
.
snap
)
{
that
.
_execEvent
(
'scrollEnd'
);
}
that
.
wheelTimeout
=
undefined
;
},
400
);
if
(
'deltaX'
in
e
)
{
if
(
e
.
deltaMode
===
1
)
{
wheelDeltaX
=
-
e
.
deltaX
*
this
.
options
.
mouseWheelSpeed
;
wheelDeltaY
=
-
e
.
deltaY
*
this
.
options
.
mouseWheelSpeed
;
}
else
{
wheelDeltaX
=
-
e
.
deltaX
;
wheelDeltaY
=
-
e
.
deltaY
;
}
}
else
if
(
'wheelDeltaX'
in
e
)
{
wheelDeltaX
=
e
.
wheelDeltaX
/
120
*
this
.
options
.
mouseWheelSpeed
;
wheelDeltaY
=
e
.
wheelDeltaY
/
120
*
this
.
options
.
mouseWheelSpeed
;
}
else
if
(
'wheelDelta'
in
e
)
{
wheelDeltaX
=
wheelDeltaY
=
e
.
wheelDelta
/
120
*
this
.
options
.
mouseWheelSpeed
;
}
else
if
(
'detail'
in
e
)
{
wheelDeltaX
=
wheelDeltaY
=
-
e
.
detail
/
3
*
this
.
options
.
mouseWheelSpeed
;
}
else
{
return
;
}
wheelDeltaX
*=
this
.
options
.
invertWheelDirection
;
wheelDeltaY
*=
this
.
options
.
invertWheelDirection
;
if
(
!
this
.
hasVerticalScroll
)
{
wheelDeltaX
=
wheelDeltaY
;
wheelDeltaY
=
0
;
}
if
(
this
.
options
.
snap
)
{
newX
=
this
.
currentPage
.
pageX
;
newY
=
this
.
currentPage
.
pageY
;
if
(
wheelDeltaX
>
0
)
{
newX
--
;
}
else
if
(
wheelDeltaX
<
0
)
{
newX
++
;
}
if
(
wheelDeltaY
>
0
)
{
newY
--
;
}
else
if
(
wheelDeltaY
<
0
)
{
newY
++
;
}
this
.
goToPage
(
newX
,
newY
);
return
;
}
newX
=
this
.
x
+
Math
.
round
(
this
.
hasHorizontalScroll
?
wheelDeltaX
:
0
);
newY
=
this
.
y
+
Math
.
round
(
this
.
hasVerticalScroll
?
wheelDeltaY
:
0
);
this
.
directionX
=
wheelDeltaX
>
0
?
-
1
:
wheelDeltaX
<
0
?
1
:
0
;
this
.
directionY
=
wheelDeltaY
>
0
?
-
1
:
wheelDeltaY
<
0
?
1
:
0
;
if
(
newX
>
0
)
{
newX
=
0
;
}
else
if
(
newX
<
this
.
maxScrollX
)
{
newX
=
this
.
maxScrollX
;
}
if
(
newY
>
0
)
{
newY
=
0
;
}
else
if
(
newY
<
this
.
maxScrollY
)
{
newY
=
this
.
maxScrollY
;
}
this
.
scrollTo
(
newX
,
newY
,
0
);
// INSERT POINT: _wheel
},
_initSnap
:
function
()
{
this
.
currentPage
=
{};
if
(
typeof
this
.
options
.
snap
==
'string'
)
{
this
.
options
.
snap
=
this
.
scroller
.
querySelectorAll
(
this
.
options
.
snap
);
}
this
.
on
(
'refresh'
,
function
()
{
var
i
=
0
,
l
,
m
=
0
,
n
,
cx
,
cy
,
x
=
0
,
y
,
stepX
=
this
.
options
.
snapStepX
||
this
.
wrapperWidth
,
stepY
=
this
.
options
.
snapStepY
||
this
.
wrapperHeight
,
el
;
this
.
pages
=
[];
if
(
!
this
.
wrapperWidth
||
!
this
.
wrapperHeight
||
!
this
.
scrollerWidth
||
!
this
.
scrollerHeight
)
{
return
;
}
if
(
this
.
options
.
snap
===
true
)
{
cx
=
Math
.
round
(
stepX
/
2
);
cy
=
Math
.
round
(
stepY
/
2
);
while
(
x
>
-
this
.
scrollerWidth
)
{
this
.
pages
[
i
]
=
[];
l
=
0
;
y
=
0
;
while
(
y
>
-
this
.
scrollerHeight
)
{
this
.
pages
[
i
][
l
]
=
{
x
:
Math
.
max
(
x
,
this
.
maxScrollX
),
y
:
Math
.
max
(
y
,
this
.
maxScrollY
),
width
:
stepX
,
height
:
stepY
,
cx
:
x
-
cx
,
cy
:
y
-
cy
};
y
-=
stepY
;
l
++
;
}
x
-=
stepX
;
i
++
;
}
}
else
{
el
=
this
.
options
.
snap
;
l
=
el
.
length
;
n
=
-
1
;
for
(
;
i
<
l
;
i
++
)
{
if
(
i
===
0
||
el
[
i
].
offsetLeft
<=
el
[
i
-
1
].
offsetLeft
)
{
m
=
0
;
n
++
;
}
if
(
!
this
.
pages
[
m
]
)
{
this
.
pages
[
m
]
=
[];
}
x
=
Math
.
max
(
-
el
[
i
].
offsetLeft
,
this
.
maxScrollX
);
y
=
Math
.
max
(
-
el
[
i
].
offsetTop
,
this
.
maxScrollY
);
cx
=
x
-
Math
.
round
(
el
[
i
].
offsetWidth
/
2
);
cy
=
y
-
Math
.
round
(
el
[
i
].
offsetHeight
/
2
);
this
.
pages
[
m
][
n
]
=
{
x
:
x
,
y
:
y
,
width
:
el
[
i
].
offsetWidth
,
height
:
el
[
i
].
offsetHeight
,
cx
:
cx
,
cy
:
cy
};
if
(
x
>
this
.
maxScrollX
)
{
m
++
;
}
}
}
this
.
goToPage
(
this
.
currentPage
.
pageX
||
0
,
this
.
currentPage
.
pageY
||
0
,
0
);
// Update snap threshold if needed
if
(
this
.
options
.
snapThreshold
%
1
===
0
)
{
this
.
snapThresholdX
=
this
.
options
.
snapThreshold
;
this
.
snapThresholdY
=
this
.
options
.
snapThreshold
;
}
else
{
this
.
snapThresholdX
=
Math
.
round
(
this
.
pages
[
this
.
currentPage
.
pageX
][
this
.
currentPage
.
pageY
].
width
*
this
.
options
.
snapThreshold
);
this
.
snapThresholdY
=
Math
.
round
(
this
.
pages
[
this
.
currentPage
.
pageX
][
this
.
currentPage
.
pageY
].
height
*
this
.
options
.
snapThreshold
);
}
});
this
.
on
(
'flick'
,
function
()
{
var
time
=
this
.
options
.
snapSpeed
||
Math
.
max
(
Math
.
max
(
Math
.
min
(
Math
.
abs
(
this
.
x
-
this
.
startX
),
1000
),
Math
.
min
(
Math
.
abs
(
this
.
y
-
this
.
startY
),
1000
)
),
300
);
this
.
goToPage
(
this
.
currentPage
.
pageX
+
this
.
directionX
,
this
.
currentPage
.
pageY
+
this
.
directionY
,
time
);
});
},
_nearestSnap
:
function
(
x
,
y
)
{
if
(
!
this
.
pages
.
length
)
{
return
{
x
:
0
,
y
:
0
,
pageX
:
0
,
pageY
:
0
};
}
var
i
=
0
,
l
=
this
.
pages
.
length
,
m
=
0
;
// Check if we exceeded the snap threshold
if
(
Math
.
abs
(
x
-
this
.
absStartX
)
<
this
.
snapThresholdX
&&
Math
.
abs
(
y
-
this
.
absStartY
)
<
this
.
snapThresholdY
)
{
return
this
.
currentPage
;
}
if
(
x
>
0
)
{
x
=
0
;
}
else
if
(
x
<
this
.
maxScrollX
)
{
x
=
this
.
maxScrollX
;
}
if
(
y
>
0
)
{
y
=
0
;
}
else
if
(
y
<
this
.
maxScrollY
)
{
y
=
this
.
maxScrollY
;
}
for
(
;
i
<
l
;
i
++
)
{
if
(
x
>=
this
.
pages
[
i
][
0
].
cx
)
{
x
=
this
.
pages
[
i
][
0
].
x
;
break
;
}
}
l
=
this
.
pages
[
i
].
length
;
for
(
;
m
<
l
;
m
++
)
{
if
(
y
>=
this
.
pages
[
0
][
m
].
cy
)
{
y
=
this
.
pages
[
0
][
m
].
y
;
break
;
}
}
if
(
i
==
this
.
currentPage
.
pageX
)
{
i
+=
this
.
directionX
;
if
(
i
<
0
)
{
i
=
0
;
}
else
if
(
i
>=
this
.
pages
.
length
)
{
i
=
this
.
pages
.
length
-
1
;
}
x
=
this
.
pages
[
i
][
0
].
x
;
}
if
(
m
==
this
.
currentPage
.
pageY
)
{
m
+=
this
.
directionY
;
if
(
m
<
0
)
{
m
=
0
;
}
else
if
(
m
>=
this
.
pages
[
0
].
length
)
{
m
=
this
.
pages
[
0
].
length
-
1
;
}
y
=
this
.
pages
[
0
][
m
].
y
;
}
return
{
x
:
x
,
y
:
y
,
pageX
:
i
,
pageY
:
m
};
},
goToPage
:
function
(
x
,
y
,
time
,
easing
)
{
easing
=
easing
||
this
.
options
.
bounceEasing
;
if
(
x
>=
this
.
pages
.
length
)
{
x
=
this
.
pages
.
length
-
1
;
}
else
if
(
x
<
0
)
{
x
=
0
;
}
if
(
y
>=
this
.
pages
[
x
].
length
)
{
y
=
this
.
pages
[
x
].
length
-
1
;
}
else
if
(
y
<
0
)
{
y
=
0
;
}
var
posX
=
this
.
pages
[
x
][
y
].
x
,
posY
=
this
.
pages
[
x
][
y
].
y
;
time
=
time
===
undefined
?
this
.
options
.
snapSpeed
||
Math
.
max
(
Math
.
max
(
Math
.
min
(
Math
.
abs
(
posX
-
this
.
x
),
1000
),
Math
.
min
(
Math
.
abs
(
posY
-
this
.
y
),
1000
)
),
300
)
:
time
;
this
.
currentPage
=
{
x
:
posX
,
y
:
posY
,
pageX
:
x
,
pageY
:
y
};
this
.
scrollTo
(
posX
,
posY
,
time
,
easing
);
},
next
:
function
(
time
,
easing
)
{
var
x
=
this
.
currentPage
.
pageX
,
y
=
this
.
currentPage
.
pageY
;
x
++
;
if
(
x
>=
this
.
pages
.
length
&&
this
.
hasVerticalScroll
)
{
x
=
0
;
y
++
;
}
this
.
goToPage
(
x
,
y
,
time
,
easing
);
},
prev
:
function
(
time
,
easing
)
{
var
x
=
this
.
currentPage
.
pageX
,
y
=
this
.
currentPage
.
pageY
;
x
--
;
if
(
x
<
0
&&
this
.
hasVerticalScroll
)
{
x
=
0
;
y
--
;
}
this
.
goToPage
(
x
,
y
,
time
,
easing
);
},
_initKeys
:
function
(
e
)
{
// default key bindings
var
keys
=
{
pageUp
:
33
,
pageDown
:
34
,
end
:
35
,
home
:
36
,
left
:
37
,
up
:
38
,
right
:
39
,
down
:
40
};
var
i
;
// if you give me characters I give you keycode
if
(
typeof
this
.
options
.
keyBindings
==
'object'
)
{
for
(
i
in
this
.
options
.
keyBindings
)
{
if
(
typeof
this
.
options
.
keyBindings
[
i
]
==
'string'
)
{
this
.
options
.
keyBindings
[
i
]
=
this
.
options
.
keyBindings
[
i
].
toUpperCase
().
charCodeAt
(
0
);
}
}
}
else
{
this
.
options
.
keyBindings
=
{};
}
for
(
i
in
keys
)
{
this
.
options
.
keyBindings
[
i
]
=
this
.
options
.
keyBindings
[
i
]
||
keys
[
i
];
}
utils
.
addEvent
(
window
,
'keydown'
,
this
);
this
.
on
(
'destroy'
,
function
()
{
utils
.
removeEvent
(
window
,
'keydown'
,
this
);
});
},
_key
:
function
(
e
)
{
if
(
!
this
.
enabled
)
{
return
;
}
var
snap
=
this
.
options
.
snap
,
// we are using this alot, better to cache it
newX
=
snap
?
this
.
currentPage
.
pageX
:
this
.
x
,
newY
=
snap
?
this
.
currentPage
.
pageY
:
this
.
y
,
now
=
utils
.
getTime
(),
prevTime
=
this
.
keyTime
||
0
,
acceleration
=
0.250
,
pos
;
if
(
this
.
options
.
useTransition
&&
this
.
isInTransition
)
{
pos
=
this
.
getComputedPosition
();
this
.
_translate
(
Math
.
round
(
pos
.
x
),
Math
.
round
(
pos
.
y
));
this
.
isInTransition
=
false
;
}
this
.
keyAcceleration
=
now
-
prevTime
<
200
?
Math
.
min
(
this
.
keyAcceleration
+
acceleration
,
50
)
:
0
;
switch
(
e
.
keyCode
)
{
case
this
.
options
.
keyBindings
.
pageUp
:
if
(
this
.
hasHorizontalScroll
&&
!
this
.
hasVerticalScroll
)
{
newX
+=
snap
?
1
:
this
.
wrapperWidth
;
}
else
{
newY
+=
snap
?
1
:
this
.
wrapperHeight
;
}
break
;
case
this
.
options
.
keyBindings
.
pageDown
:
if
(
this
.
hasHorizontalScroll
&&
!
this
.
hasVerticalScroll
)
{
newX
-=
snap
?
1
:
this
.
wrapperWidth
;
}
else
{
newY
-=
snap
?
1
:
this
.
wrapperHeight
;
}
break
;
case
this
.
options
.
keyBindings
.
end
:
newX
=
snap
?
this
.
pages
.
length
-
1
:
this
.
maxScrollX
;
newY
=
snap
?
this
.
pages
[
0
].
length
-
1
:
this
.
maxScrollY
;
break
;
case
this
.
options
.
keyBindings
.
home
:
newX
=
0
;
newY
=
0
;
break
;
case
this
.
options
.
keyBindings
.
left
:
newX
+=
snap
?
-
1
:
5
+
this
.
keyAcceleration
>>
0
;
break
;
case
this
.
options
.
keyBindings
.
up
:
newY
+=
snap
?
1
:
5
+
this
.
keyAcceleration
>>
0
;
break
;
case
this
.
options
.
keyBindings
.
right
:
newX
-=
snap
?
-
1
:
5
+
this
.
keyAcceleration
>>
0
;
break
;
case
this
.
options
.
keyBindings
.
down
:
newY
-=
snap
?
1
:
5
+
this
.
keyAcceleration
>>
0
;
break
;
default
:
return
;
}
if
(
snap
)
{
this
.
goToPage
(
newX
,
newY
);
return
;
}
if
(
newX
>
0
)
{
newX
=
0
;
this
.
keyAcceleration
=
0
;
}
else
if
(
newX
<
this
.
maxScrollX
)
{
newX
=
this
.
maxScrollX
;
this
.
keyAcceleration
=
0
;
}
if
(
newY
>
0
)
{
newY
=
0
;
this
.
keyAcceleration
=
0
;
}
else
if
(
newY
<
this
.
maxScrollY
)
{
newY
=
this
.
maxScrollY
;
this
.
keyAcceleration
=
0
;
}
this
.
scrollTo
(
newX
,
newY
,
0
);
this
.
keyTime
=
now
;
},
_animate
:
function
(
destX
,
destY
,
duration
,
easingFn
)
{
var
that
=
this
,
startX
=
this
.
x
,
startY
=
this
.
y
,
startTime
=
utils
.
getTime
(),
destTime
=
startTime
+
duration
;
function
step
()
{
var
now
=
utils
.
getTime
(),
newX
,
newY
,
easing
;
if
(
now
>=
destTime
)
{
that
.
isAnimating
=
false
;
that
.
_translate
(
destX
,
destY
);
if
(
!
that
.
resetPosition
(
that
.
options
.
bounceTime
)
)
{
that
.
_execEvent
(
'scrollEnd'
);
}
return
;
}
now
=
(
now
-
startTime
)
/
duration
;
easing
=
easingFn
(
now
);
newX
=
(
destX
-
startX
)
*
easing
+
startX
;
newY
=
(
destY
-
startY
)
*
easing
+
startY
;
that
.
_translate
(
newX
,
newY
);
if
(
that
.
isAnimating
)
{
rAF
(
step
);
}
}
this
.
isAnimating
=
true
;
step
();
},
handleEvent
:
function
(
e
)
{
switch
(
e
.
type
)
{
case
'touchstart'
:
case
'pointerdown'
:
case
'MSPointerDown'
:
case
'mousedown'
:
this
.
_start
(
e
);
break
;
case
'touchmove'
:
case
'pointermove'
:
case
'MSPointerMove'
:
case
'mousemove'
:
this
.
_move
(
e
);
break
;
case
'touchend'
:
case
'pointerup'
:
case
'MSPointerUp'
:
case
'mouseup'
:
case
'touchcancel'
:
case
'pointercancel'
:
case
'MSPointerCancel'
:
case
'mousecancel'
:
this
.
_end
(
e
);
break
;
case
'orientationchange'
:
case
'resize'
:
this
.
_resize
();
break
;
case
'transitionend'
:
case
'webkitTransitionEnd'
:
case
'oTransitionEnd'
:
case
'MSTransitionEnd'
:
this
.
_transitionEnd
(
e
);
break
;
case
'wheel'
:
case
'DOMMouseScroll'
:
case
'mousewheel'
:
this
.
_wheel
(
e
);
break
;
case
'keydown'
:
this
.
_key
(
e
);
break
;
case
'click'
:
if
(
this
.
enabled
&&
!
e
.
_constructed
)
{
e
.
preventDefault
();
e
.
stopPropagation
();
}
break
;
}
}
};
function
createDefaultScrollbar
(
direction
,
interactive
,
type
)
{
var
scrollbar
=
document
.
createElement
(
'div'
),
indicator
=
document
.
createElement
(
'div'
);
if
(
type
===
true
)
{
scrollbar
.
style
.
cssText
=
'position:absolute;z-index:9999'
;
indicator
.
style
.
cssText
=
'-webkit-box-sizing:border-box;-moz-box-sizing:border-box;box-sizing:border-box;position:absolute;background:rgba(0,0,0,0.5);border:1px solid rgba(255,255,255,0.9);border-radius:3px'
;
}
indicator
.
className
=
'iScrollIndicator'
;
if
(
direction
==
'h'
)
{
if
(
type
===
true
)
{
scrollbar
.
style
.
cssText
+=
';height:7px;left:2px;right:2px;bottom:0'
;
indicator
.
style
.
height
=
'100%'
;
}
scrollbar
.
className
=
'iScrollHorizontalScrollbar'
;
}
else
{
if
(
type
===
true
)
{
scrollbar
.
style
.
cssText
+=
';width:7px;bottom:2px;top:2px;right:1px'
;
indicator
.
style
.
width
=
'100%'
;
}
scrollbar
.
className
=
'iScrollVerticalScrollbar'
;
}
scrollbar
.
style
.
cssText
+=
';overflow:hidden'
;
if
(
!
interactive
)
{
scrollbar
.
style
.
pointerEvents
=
'none'
;
}
scrollbar
.
appendChild
(
indicator
);
return
scrollbar
;
}
function
Indicator
(
scroller
,
options
)
{
this
.
wrapper
=
typeof
options
.
el
==
'string'
?
document
.
querySelector
(
options
.
el
)
:
options
.
el
;
this
.
wrapperStyle
=
this
.
wrapper
.
style
;
this
.
indicator
=
this
.
wrapper
.
children
[
0
];
this
.
indicatorStyle
=
this
.
indicator
.
style
;
this
.
scroller
=
scroller
;
this
.
options
=
{
listenX
:
true
,
listenY
:
true
,
interactive
:
false
,
resize
:
true
,
defaultScrollbars
:
false
,
shrink
:
false
,
fade
:
false
,
speedRatioX
:
0
,
speedRatioY
:
0
};
for
(
var
i
in
options
)
{
this
.
options
[
i
]
=
options
[
i
];
}
this
.
sizeRatioX
=
1
;
this
.
sizeRatioY
=
1
;
this
.
maxPosX
=
0
;
this
.
maxPosY
=
0
;
if
(
this
.
options
.
interactive
)
{
if
(
!
this
.
options
.
disableTouch
)
{
utils
.
addEvent
(
this
.
indicator
,
'touchstart'
,
this
);
utils
.
addEvent
(
window
,
'touchend'
,
this
);
}
if
(
!
this
.
options
.
disablePointer
)
{
utils
.
addEvent
(
this
.
indicator
,
utils
.
prefixPointerEvent
(
'pointerdown'
),
this
);
utils
.
addEvent
(
window
,
utils
.
prefixPointerEvent
(
'pointerup'
),
this
);
}
if
(
!
this
.
options
.
disableMouse
)
{
utils
.
addEvent
(
this
.
indicator
,
'mousedown'
,
this
);
utils
.
addEvent
(
window
,
'mouseup'
,
this
);
}
}
if
(
this
.
options
.
fade
)
{
this
.
wrapperStyle
[
utils
.
style
.
transform
]
=
this
.
scroller
.
translateZ
;
var
durationProp
=
utils
.
style
.
transitionDuration
;
this
.
wrapperStyle
[
durationProp
]
=
utils
.
isBadAndroid
?
'0.0001ms'
:
'0ms'
;
// remove 0.0001ms
var
self
=
this
;
if
(
utils
.
isBadAndroid
)
{
rAF
(
function
()
{
if
(
self
.
wrapperStyle
[
durationProp
]
===
'0.0001ms'
)
{
self
.
wrapperStyle
[
durationProp
]
=
'0s'
;
}
});
}
this
.
wrapperStyle
.
opacity
=
'0'
;
}
}
Indicator
.
prototype
=
{
handleEvent
:
function
(
e
)
{
switch
(
e
.
type
)
{
case
'touchstart'
:
case
'pointerdown'
:
case
'MSPointerDown'
:
case
'mousedown'
:
this
.
_start
(
e
);
break
;
case
'touchmove'
:
case
'pointermove'
:
case
'MSPointerMove'
:
case
'mousemove'
:
this
.
_move
(
e
);
break
;
case
'touchend'
:
case
'pointerup'
:
case
'MSPointerUp'
:
case
'mouseup'
:
case
'touchcancel'
:
case
'pointercancel'
:
case
'MSPointerCancel'
:
case
'mousecancel'
:
this
.
_end
(
e
);
break
;
}
},
destroy
:
function
()
{
if
(
this
.
options
.
fadeScrollbars
)
{
clearTimeout
(
this
.
fadeTimeout
);
this
.
fadeTimeout
=
null
;
}
if
(
this
.
options
.
interactive
)
{
utils
.
removeEvent
(
this
.
indicator
,
'touchstart'
,
this
);
utils
.
removeEvent
(
this
.
indicator
,
utils
.
prefixPointerEvent
(
'pointerdown'
),
this
);
utils
.
removeEvent
(
this
.
indicator
,
'mousedown'
,
this
);
utils
.
removeEvent
(
window
,
'touchmove'
,
this
);
utils
.
removeEvent
(
window
,
utils
.
prefixPointerEvent
(
'pointermove'
),
this
);
utils
.
removeEvent
(
window
,
'mousemove'
,
this
);
utils
.
removeEvent
(
window
,
'touchend'
,
this
);
utils
.
removeEvent
(
window
,
utils
.
prefixPointerEvent
(
'pointerup'
),
this
);
utils
.
removeEvent
(
window
,
'mouseup'
,
this
);
}
if
(
this
.
options
.
defaultScrollbars
)
{
this
.
wrapper
.
parentNode
.
removeChild
(
this
.
wrapper
);
}
},
_start
:
function
(
e
)
{
var
point
=
e
.
touches
?
e
.
touches
[
0
]
:
e
;
e
.
preventDefault
();
e
.
stopPropagation
();
this
.
transitionTime
();
this
.
initiated
=
true
;
this
.
moved
=
false
;
this
.
lastPointX
=
point
.
pageX
;
this
.
lastPointY
=
point
.
pageY
;
this
.
startTime
=
utils
.
getTime
();
if
(
!
this
.
options
.
disableTouch
)
{
utils
.
addEvent
(
window
,
'touchmove'
,
this
);
}
if
(
!
this
.
options
.
disablePointer
)
{
utils
.
addEvent
(
window
,
utils
.
prefixPointerEvent
(
'pointermove'
),
this
);
}
if
(
!
this
.
options
.
disableMouse
)
{
utils
.
addEvent
(
window
,
'mousemove'
,
this
);
}
this
.
scroller
.
_execEvent
(
'beforeScrollStart'
);
},
_move
:
function
(
e
)
{
var
point
=
e
.
touches
?
e
.
touches
[
0
]
:
e
,
deltaX
,
deltaY
,
newX
,
newY
,
timestamp
=
utils
.
getTime
();
if
(
!
this
.
moved
)
{
this
.
scroller
.
_execEvent
(
'scrollStart'
);
}
this
.
moved
=
true
;
deltaX
=
point
.
pageX
-
this
.
lastPointX
;
this
.
lastPointX
=
point
.
pageX
;
deltaY
=
point
.
pageY
-
this
.
lastPointY
;
this
.
lastPointY
=
point
.
pageY
;
newX
=
this
.
x
+
deltaX
;
newY
=
this
.
y
+
deltaY
;
this
.
_pos
(
newX
,
newY
);
// INSERT POINT: indicator._move
e
.
preventDefault
();
e
.
stopPropagation
();
},
_end
:
function
(
e
)
{
if
(
!
this
.
initiated
)
{
return
;
}
this
.
initiated
=
false
;
e
.
preventDefault
();
e
.
stopPropagation
();
utils
.
removeEvent
(
window
,
'touchmove'
,
this
);
utils
.
removeEvent
(
window
,
utils
.
prefixPointerEvent
(
'pointermove'
),
this
);
utils
.
removeEvent
(
window
,
'mousemove'
,
this
);
if
(
this
.
scroller
.
options
.
snap
)
{
var
snap
=
this
.
scroller
.
_nearestSnap
(
this
.
scroller
.
x
,
this
.
scroller
.
y
);
var
time
=
this
.
options
.
snapSpeed
||
Math
.
max
(
Math
.
max
(
Math
.
min
(
Math
.
abs
(
this
.
scroller
.
x
-
snap
.
x
),
1000
),
Math
.
min
(
Math
.
abs
(
this
.
scroller
.
y
-
snap
.
y
),
1000
)
),
300
);
if
(
this
.
scroller
.
x
!=
snap
.
x
||
this
.
scroller
.
y
!=
snap
.
y
)
{
this
.
scroller
.
directionX
=
0
;
this
.
scroller
.
directionY
=
0
;
this
.
scroller
.
currentPage
=
snap
;
this
.
scroller
.
scrollTo
(
snap
.
x
,
snap
.
y
,
time
,
this
.
scroller
.
options
.
bounceEasing
);
}
}
if
(
this
.
moved
)
{
this
.
scroller
.
_execEvent
(
'scrollEnd'
);
}
},
transitionTime
:
function
(
time
)
{
time
=
time
||
0
;
var
durationProp
=
utils
.
style
.
transitionDuration
;
this
.
indicatorStyle
[
durationProp
]
=
time
+
'ms'
;
if
(
!
time
&&
utils
.
isBadAndroid
)
{
this
.
indicatorStyle
[
durationProp
]
=
'0.0001ms'
;
// remove 0.0001ms
var
self
=
this
;
rAF
(
function
()
{
if
(
self
.
indicatorStyle
[
durationProp
]
===
'0.0001ms'
)
{
self
.
indicatorStyle
[
durationProp
]
=
'0s'
;
}
});
}
},
transitionTimingFunction
:
function
(
easing
)
{
this
.
indicatorStyle
[
utils
.
style
.
transitionTimingFunction
]
=
easing
;
},
refresh
:
function
()
{
this
.
transitionTime
();
if
(
this
.
options
.
listenX
&&
!
this
.
options
.
listenY
)
{
this
.
indicatorStyle
.
display
=
this
.
scroller
.
hasHorizontalScroll
?
'block'
:
'none'
;
}
else
if
(
this
.
options
.
listenY
&&
!
this
.
options
.
listenX
)
{
this
.
indicatorStyle
.
display
=
this
.
scroller
.
hasVerticalScroll
?
'block'
:
'none'
;
}
else
{
this
.
indicatorStyle
.
display
=
this
.
scroller
.
hasHorizontalScroll
||
this
.
scroller
.
hasVerticalScroll
?
'block'
:
'none'
;
}
if
(
this
.
scroller
.
hasHorizontalScroll
&&
this
.
scroller
.
hasVerticalScroll
)
{
utils
.
addClass
(
this
.
wrapper
,
'iScrollBothScrollbars'
);
utils
.
removeClass
(
this
.
wrapper
,
'iScrollLoneScrollbar'
);
if
(
this
.
options
.
defaultScrollbars
&&
this
.
options
.
customStyle
)
{
if
(
this
.
options
.
listenX
)
{
this
.
wrapper
.
style
.
right
=
'8px'
;
}
else
{
this
.
wrapper
.
style
.
bottom
=
'8px'
;
}
}
}
else
{
utils
.
removeClass
(
this
.
wrapper
,
'iScrollBothScrollbars'
);
utils
.
addClass
(
this
.
wrapper
,
'iScrollLoneScrollbar'
);
if
(
this
.
options
.
defaultScrollbars
&&
this
.
options
.
customStyle
)
{
if
(
this
.
options
.
listenX
)
{
this
.
wrapper
.
style
.
right
=
'2px'
;
}
else
{
this
.
wrapper
.
style
.
bottom
=
'2px'
;
}
}
}
var
r
=
this
.
wrapper
.
offsetHeight
;
// force refresh
if
(
this
.
options
.
listenX
)
{
this
.
wrapperWidth
=
this
.
wrapper
.
clientWidth
;
if
(
this
.
options
.
resize
)
{
this
.
indicatorWidth
=
Math
.
max
(
Math
.
round
(
this
.
wrapperWidth
*
this
.
wrapperWidth
/
(
this
.
scroller
.
scrollerWidth
||
this
.
wrapperWidth
||
1
)),
8
);
this
.
indicatorStyle
.
width
=
this
.
indicatorWidth
+
'px'
;
}
else
{
this
.
indicatorWidth
=
this
.
indicator
.
clientWidth
;
}
this
.
maxPosX
=
this
.
wrapperWidth
-
this
.
indicatorWidth
;
if
(
this
.
options
.
shrink
==
'clip'
)
{
this
.
minBoundaryX
=
-
this
.
indicatorWidth
+
8
;
this
.
maxBoundaryX
=
this
.
wrapperWidth
-
8
;
}
else
{
this
.
minBoundaryX
=
0
;
this
.
maxBoundaryX
=
this
.
maxPosX
;
}
this
.
sizeRatioX
=
this
.
options
.
speedRatioX
||
(
this
.
scroller
.
maxScrollX
&&
(
this
.
maxPosX
/
this
.
scroller
.
maxScrollX
));
}
if
(
this
.
options
.
listenY
)
{
this
.
wrapperHeight
=
this
.
wrapper
.
clientHeight
;
if
(
this
.
options
.
resize
)
{
this
.
indicatorHeight
=
Math
.
max
(
Math
.
round
(
this
.
wrapperHeight
*
this
.
wrapperHeight
/
(
this
.
scroller
.
scrollerHeight
||
this
.
wrapperHeight
||
1
)),
8
);
this
.
indicatorStyle
.
height
=
this
.
indicatorHeight
+
'px'
;
}
else
{
this
.
indicatorHeight
=
this
.
indicator
.
clientHeight
;
}
this
.
maxPosY
=
this
.
wrapperHeight
-
this
.
indicatorHeight
;
if
(
this
.
options
.
shrink
==
'clip'
)
{
this
.
minBoundaryY
=
-
this
.
indicatorHeight
+
8
;
this
.
maxBoundaryY
=
this
.
wrapperHeight
-
8
;
}
else
{
this
.
minBoundaryY
=
0
;
this
.
maxBoundaryY
=
this
.
maxPosY
;
}
this
.
maxPosY
=
this
.
wrapperHeight
-
this
.
indicatorHeight
;
this
.
sizeRatioY
=
this
.
options
.
speedRatioY
||
(
this
.
scroller
.
maxScrollY
&&
(
this
.
maxPosY
/
this
.
scroller
.
maxScrollY
));
}
this
.
updatePosition
();
},
updatePosition
:
function
()
{
var
x
=
this
.
options
.
listenX
&&
Math
.
round
(
this
.
sizeRatioX
*
this
.
scroller
.
x
)
||
0
,
y
=
this
.
options
.
listenY
&&
Math
.
round
(
this
.
sizeRatioY
*
this
.
scroller
.
y
)
||
0
;
if
(
!
this
.
options
.
ignoreBoundaries
)
{
if
(
x
<
this
.
minBoundaryX
)
{
if
(
this
.
options
.
shrink
==
'scale'
)
{
this
.
width
=
Math
.
max
(
this
.
indicatorWidth
+
x
,
8
);
this
.
indicatorStyle
.
width
=
this
.
width
+
'px'
;
}
x
=
this
.
minBoundaryX
;
}
else
if
(
x
>
this
.
maxBoundaryX
)
{
if
(
this
.
options
.
shrink
==
'scale'
)
{
this
.
width
=
Math
.
max
(
this
.
indicatorWidth
-
(
x
-
this
.
maxPosX
),
8
);
this
.
indicatorStyle
.
width
=
this
.
width
+
'px'
;
x
=
this
.
maxPosX
+
this
.
indicatorWidth
-
this
.
width
;
}
else
{
x
=
this
.
maxBoundaryX
;
}
}
else
if
(
this
.
options
.
shrink
==
'scale'
&&
this
.
width
!=
this
.
indicatorWidth
)
{
this
.
width
=
this
.
indicatorWidth
;
this
.
indicatorStyle
.
width
=
this
.
width
+
'px'
;
}
if
(
y
<
this
.
minBoundaryY
)
{
if
(
this
.
options
.
shrink
==
'scale'
)
{
this
.
height
=
Math
.
max
(
this
.
indicatorHeight
+
y
*
3
,
8
);
this
.
indicatorStyle
.
height
=
this
.
height
+
'px'
;
}
y
=
this
.
minBoundaryY
;
}
else
if
(
y
>
this
.
maxBoundaryY
)
{
if
(
this
.
options
.
shrink
==
'scale'
)
{
this
.
height
=
Math
.
max
(
this
.
indicatorHeight
-
(
y
-
this
.
maxPosY
)
*
3
,
8
);
this
.
indicatorStyle
.
height
=
this
.
height
+
'px'
;
y
=
this
.
maxPosY
+
this
.
indicatorHeight
-
this
.
height
;
}
else
{
y
=
this
.
maxBoundaryY
;
}
}
else
if
(
this
.
options
.
shrink
==
'scale'
&&
this
.
height
!=
this
.
indicatorHeight
)
{
this
.
height
=
this
.
indicatorHeight
;
this
.
indicatorStyle
.
height
=
this
.
height
+
'px'
;
}
}
this
.
x
=
x
;
this
.
y
=
y
;
if
(
this
.
scroller
.
options
.
useTransform
)
{
this
.
indicatorStyle
[
utils
.
style
.
transform
]
=
'translate('
+
x
+
'px,'
+
y
+
'px)'
+
this
.
scroller
.
translateZ
;
}
else
{
this
.
indicatorStyle
.
left
=
x
+
'px'
;
this
.
indicatorStyle
.
top
=
y
+
'px'
;
}
},
_pos
:
function
(
x
,
y
)
{
if
(
x
<
0
)
{
x
=
0
;
}
else
if
(
x
>
this
.
maxPosX
)
{
x
=
this
.
maxPosX
;
}
if
(
y
<
0
)
{
y
=
0
;
}
else
if
(
y
>
this
.
maxPosY
)
{
y
=
this
.
maxPosY
;
}
x
=
this
.
options
.
listenX
?
Math
.
round
(
x
/
this
.
sizeRatioX
)
:
this
.
scroller
.
x
;
y
=
this
.
options
.
listenY
?
Math
.
round
(
y
/
this
.
sizeRatioY
)
:
this
.
scroller
.
y
;
this
.
scroller
.
scrollTo
(
x
,
y
);
},
fade
:
function
(
val
,
hold
)
{
if
(
hold
&&
!
this
.
visible
)
{
return
;
}
clearTimeout
(
this
.
fadeTimeout
);
this
.
fadeTimeout
=
null
;
var
time
=
val
?
250
:
500
,
delay
=
val
?
0
:
300
;
val
=
val
?
'1'
:
'0'
;
this
.
wrapperStyle
[
utils
.
style
.
transitionDuration
]
=
time
+
'ms'
;
this
.
fadeTimeout
=
setTimeout
((
function
(
val
)
{
this
.
wrapperStyle
.
opacity
=
val
;
this
.
visible
=
+
val
;
}).
bind
(
this
,
val
),
delay
);
}
};
IScroll
.
utils
=
utils
;
if
(
typeof
module
!=
'undefined'
&&
module
.
exports
)
{
module
.
exports
=
IScroll
;
}
else
if
(
typeof
define
==
'function'
&&
define
.
amd
)
{
define
(
function
()
{
return
IScroll
;
}
);
}
else
{
window
.
IScroll
=
IScroll
;
}
})(
window
,
document
,
Math
);
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment