(
function
($){
var
defaultSettings = {
hasArrivedEnd:
false
,
pulldownCallback:
function
(){
console.log(
"pull down ... "
);
},
pullupCallback:
function
(){
console.log(
"pull up ... "
);
}
};
function
render(target,settings){
var
container = target;
var
childrenNode = $(container).children().remove();
$(container).addClass(
"ys-scroll-wrapper"
);
$(container).append(
"<div class='loading-top'>加载中...</div>"
);
$(container).append(
"<div class='ys-scroll-content'></div>"
);
$(container).append(
"<div class='loading-bottom'>加载更多...</div>"
);
$(container).append(
"<div class='loading-end'>已经到底了</div>"
);
$(container).find(
".ys-scroll-content"
).append(childrenNode);
$(container).scrollTop(LOADING_BAR_HEIGHT);
$(container).data(
"settings"
,settings);
return
container;
}
function
bindEventHandlers(target,container,settings){
var
loadingTopRevertTimeout =
null
;
var
loadingTopEndTimeout =
null
;
var
loadingBottomRevertTimeout =
null
;
var
loadingBottomTimeout =
null
;
var
pulldownCallback = settings.pulldownCallback;
var
pullupCallback = settings.pullupCallback;
function
clearTimeouts(){
clearTimeout(loadingTopRevertTimeout);
clearTimeout(loadingTopEndTimeout);
clearTimeout(loadingBottomRevertTimeout);
clearTimeout(loadingBottomTimeout);
}
function
scrollHandler(){
clearTimeouts();
var
loadingTop =
false
;
if
(arriveLoadingTopStart(container)){
loadingTopRevertTimeout = setTimeout(
function
(){
loadingTopRevert(container);
},RESPONSE_DELAY);
loadingTop =
true
;
}
if
(arriveLoadingTopEnd(container)){
clearTimeouts();
loadingTopEndTimeout = setTimeout(
function
(){
resetLoading(container);
pulldownCallback();
},RESPONSE_DELAY);
loadingTop =
true
;
}
var
hasArrivedEnd = $(container).data(
"settings"
).hasArrivedEnd;
if
(hasArrivedEnd||loadingTop){
return
;
}
if
(arriveLoadingBottomStart(container)){
loadingBottomRevertTimeout = setTimeout(
function
(){
loadingBottomRevert(container);
},RESPONSE_DELAY);
}
if
(arriveLoadingBottomEnd(container)){
clearTimeouts();
loadingBottomTimeout = setTimeout(
function
(){
pullupCallback();
},RESPONSE_DELAY)
}
}
var
hasPressed =
false
;
$(container).on(
"touchstart"
,
function
(event){
hasPressed =
true
;
clearTimeouts();
stopAnimation(container);
});
$(container).on(
"touchmove"
,
function
(event){
hasPressed =
true
;
clearTimeouts();
stopAnimation(container);
var
clientX = event.originalEvent.changedTouches[0].clientX;
var
clientY = event.originalEvent.changedTouches[0].clientY;
if
(clientY<0||clientX<0){
scrollHandler();
}
});
$(container).on(
"touchend touchcancel"
,
function
(event){
scrollHandler();
hasPressed =
false
;
});
$(container).scroll(
function
(){
if
(hasPressed||reverting){
return
;
}
scrollHandler();
});
}
var
RESPONSE_DELAY = 800;
var
ANIMATION_DURATION = 300;
var
LOADING_BAR_HEIGHT = 40;
var
reverting =
false
;
function
stopAnimation(container){
$(container).stop(
true
);
reverting =
false
;
}
function
loadingTopRevert(container){
reverting =
true
;
$(container).animate({
"scrollTop"
:LOADING_BAR_HEIGHT+
"px"
},ANIMATION_DURATION,
function
(){
reverting =
false
;
});
}
function
arriveLoadingTopStart(container){
var
scrollTop = $(container).scrollTop();
if
(scrollTop<LOADING_BAR_HEIGHT){
return
true
;
}
return
false
;
}
function
arriveLoadingTopEnd(container){
var
scrollTop = $(container).scrollTop();
if
(scrollTop<1) {
return
true
;
}
return
false
;
}
function
loadingBottomRevert(container){
reverting =
true
;
var
clientHeight = $(container).height();
var
scrollTop = $(container)[0].scrollHeight-LOADING_BAR_HEIGHT-clientHeight;
$(container).animate({
"scrollTop"
:scrollTop+
"px"
},ANIMATION_DURATION,
function
(){
reverting =
false
;
});
}
function
arriveLoadingBottomStart(container){
var
scrollTop = $(container).scrollTop();
var
scrollHeight = $(container)[0].scrollHeight;
var
clientHeight = $(container).height();
if
(scrollTop + clientHeight+LOADING_BAR_HEIGHT>= scrollHeight) {
return
true
;
}
return
false
;
}
function
arriveLoadingBottomEnd(container){
var
scrollTop = $(container).scrollTop();
var
scrollHeight = $(container)[0].scrollHeight;
var
clientHeight = $(container).height();
if
(scrollTop + clientHeight+1> scrollHeight) {
return
true
;
}
return
false
;
}
function
resetLoading(container){
$(container).data(
"settings"
).hasArrivedEnd=
false
;
$(container).find(
".loading-bottom"
).show();
$(container).find(
".loading-end"
).hide();
}
function
setLoadingEnd(container){
$(container).data(
"settings"
).hasArrivedEnd=
true
;
$(container).find(
".loading-bottom"
).hide();
$(container).find(
".loading-end"
).show();
}
var
options = {
ysScroll:
function
(settings) {
var
mergedSettings = {};
$.extend(mergedSettings,defaultSettings,settings);
$(
this
).each(
function
(){
var
container = render(
this
,settings);
$(container).data(
"settings"
,settings);
bindEventHandlers(
this
,container,mergedSettings);
});
},
ysScrollRefresh:
function
(){
if
(arriveLoadingTopStart(
this
)){
loadingTopRevert(
this
);
}
if
(arriveLoadingBottomStart(
this
)){
loadingBottomRevert(
this
);
}
},
ysScrollLoadEnd:
function
(){
setLoadingEnd(
this
);
}
};
$.fn.extend(options);
})(jQuery);