\
-
\
-
\
-
\
-
\
+(function() {
+ "use strict";
+ (function() {
+ var refreshMain, spinnerWrapper, arrowWrapper, arrowMain;
+ var scrollEl = document.body;
+
+ var noShowClass = 'mui-refresh-noshow';
+ var mainAnimatClass = 'mui-refresh-main-animat';
+ var blueThemeClass = 'mui-blue-theme';
+
+ var isShowLoading = false;
+ var isStoping = false;
+ var isBtnAction = false;
+
+ var NUM_POS_START_Y = -85;
+ var NUM_POS_TARGET_Y = 0; // Where to stop
+ var NUM_POS_MAX_Y = 65; // Max position for the moving distance
+ var NUM_POS_MIN_Y = -25; // Min position for the moving distance
+ var NUM_NAV_TARGET_ADDY = 20; // For custom nav bar
+
+ var touchCurrentY;
+ var touchStartY = 0;
+ var customNavTop = 0;
+ var verticalThreshold = 2;
+ var maxRotateTime = 6000; //Max time to stop rotate
+ var basePosY = 60;
+
+ var onBegin = null;
+ var onBtnBegin= null;
+ var onEnd = null;
+ var onBtnEnd = null;
+ var stopAnimatTimeout = null;
+
+ var refreshNav = '';
+
+ var lastTime = new Date().getTime();
+
+ var isIOS = /ip(hone|ad|od)/i.test(navigator.userAgent);
+
+ var tmpl = '
\
-
';
-
- // Defined the object to improve performance
- var touchPos = {
- top: 0,
- x1: 0,
- x2: 0,
- y1: 0,
- y2: 0
- }
-
- // Default options
- /* var opts = { */
- /* scrollEl: '', //String */
- /* nav: '', //String */
- /* top: '0px', //String */
- /* theme: '', //String */
- /* index: 10001, //Number*/
- /* maxTime: 3000, //Number */
- /* freeze: false, //Boolen */
- /* onBegin: null, //Function */
- /* onEnd: null //Function */
- /* } */
-
-
- /* Known issue:
- * 1. iOS feature when scrolling ,animation will stop
- * 2. Animation display issue in anfroid like miui小米
- *
- *
- * TODO list:
- * 1. Using translate and scale together to replace top
- * 2. Optimize circle rotate animation
- */
-
- // Main function to init the refresh style
- function mRefresh(options) {
- options = options || {};
-
- scrollEl = options.scrollEl ? options.scrollEl :
- isIOS ? scrollEl : document;
- $scrollEl = $(scrollEl);
-
- // extend options
- onBegin = options.onBegin;
- onEnd = options.onEnd;
- maxRotateTime = options.maxTime || maxRotateTime;
- refreshNav = options.nav || refreshNav;
-
- if ($('#muirefresh').length === 0) {
- renderTmpl();
+
';
+
+ // Defined the object to improve performance
+ var touchPos = {
+ top: 0,
+ x1: 0,
+ x2: 0,
+ y1: 0,
+ y2: 0
}
- $refreshMain = $('#muiRefresh');
- $spinnerWrapper = $('.mui-spinner-wrapper', $refreshMain);
- $arrowWrapper = $('.mui-arrow-wrapper', $refreshMain);
- $arrowMain = $('.mui-arrow-main', $refreshMain);
-
- // Custom nav bar
- if (!isDefaultType()) {
- $refreshMain.addClass('mui-refresh-nav');
- basePosY = $(refreshNav).height() + 20;
- if($(refreshNav).offset()){
- customNavTop = $(refreshNav).offset().top;
- // Handle position fix
- if($(refreshNav).css('position') !== 'fixed'){
- basePosY += customNavTop;
- }
- // Set the first Y position
- $refreshMain.css('top', customNavTop + 'px');
+ // Default options
+ /* var opts = { */
+ /* scrollEl: '', //String */
+ /* nav: '', //String */
+ /* top: '0px', //String */
+ /* theme: '', //String */
+ /* index: 10001, //Number*/
+ /* maxTime: 3000, //Number */
+ /* freeze: false, //Boolen */
+ /* onBegin: null, //Function */
+ /* onEnd: null //Function */
+ /* } */
+
+
+ /* Known issue:
+ * 1. iOS feature when scrolling ,animation will stop
+ * 2. Animation display issue in anfroid like miui小米
+ *
+ *
+ * TODO list:
+ * 1. Using translate and scale together to replace top
+ * 2. Optimize circle rotate animation
+ */
+
+ var $ = function() {
+ var parent, el;
+
+ if (arguments.length === 1) {
+ el = arguments[0];
+ parent = document;
+ } else {
+ parent = arguments[0];
+ el = arguments[1];
}
- //Set z-index to make sure ablow the nav bar
- var navIndex = $(refreshNav).css('z-index');
- $refreshMain.css('z-index', navIndex - 1);
+ return el && (typeof el) === 'string' ? parent.querySelector(el)
+ : el instanceof HTMLElement ? el
+ : null;
}
- //Set custom z-index
- if(options.index){
- $refreshMain.css('z-index', ~~options.index);
- }
+ // Main function to init the refresh style
+ function mRefresh(options) {
+ options = options || {};
- //Set custom top, to change the position
- if(options.top){
- $refreshMain.css('top', options.top);
- }
+ scrollEl = $(options.scrollEl || (isIOS ? scrollEl : document));
- // Extract theme
- if (options.theme) {
- $refreshMain.addClass(options.theme);
- } else {
- $refreshMain.addClass(blueThemeClass);
- }
+ // extend options
+ onBegin = options.onBegin;
+ onEnd = options.onEnd;
+ maxRotateTime = options.maxTime || maxRotateTime;
+ refreshNav = $(options.nav || refreshNav);
+
+ if (!$('#muirefresh')) {
+ renderTmpl();
+ }
- // Add Animation Class
- $refreshMain.addClass(mainAnimatClass);
+ refreshMain = $('#muiRefresh');
+ spinnerWrapper = $(refreshMain, '.mui-spinner-wrapper');
+ arrowWrapper = $(refreshMain, '.mui-arrow-wrapper');
+ arrowMain = $(refreshMain, '.mui-arrow-main');
- if(!options.freeze){
- bindEvents();
+ // Custom nav bar
+ if (!isDefaultType()) {
+ refreshMain.classList.add('mui-refresh-nav');
+ basePosY = refreshNav.clientHeight + 20;
+ var rect;
+ if(rect = refreshNav.getBoundingClientRect()){
+ var top = rect.top + document.body.scrollTop,
+ left = rect.left + document.body.scrollLeft;
+
+ customNavTop = top;
+ // Handle position fix
+ if(refreshNav.style.position !== 'fixed'){
+ basePosY += customNavTop;
+ }
+ // Set the first Y position
+ refreshMain.style.top = customNavTop + 'px';
+ }
+
+ //Set z-index to make sure ablow the nav bar
+ var navIndex = window.getComputedStyle(refreshNav).zIndex;
+ refreshMain.style.zIndex = Math.max(1, parseInt(navIndex) - 1);
+ }
+
+ //Set custom z-index
+ if(options.index){
+ refreshMain.style.zIndex = ~~options.index;
+ }
+
+ //Set custom top, to change the position
+ if(options.top){
+ refreshMain.style.top = options.top;
+ }
+
+ // Extract theme
+ if (options.theme) {
+ refreshMain.classList.add(options.theme);
+ } else {
+ refreshMain.classList.add(blueThemeClass);
+ }
+
+ // Add Animation Class
+ refreshMain.classList.add(mainAnimatClass);
+
+ if(!options.freeze){
+ bindEvents();
+ }
}
- }
- // Public Methods
+ // Public Methods
- // Finish loading
- mRefresh.resolve = function() {
- if(!isStoping && stopAnimatTimeout){
- clearTimeout(stopAnimatTimeout);
- stopAnimatTimeout = null;
+ // Finish loading
+ mRefresh.resolve = function() {
+ if(!isStoping && stopAnimatTimeout){
+ clearTimeout(stopAnimatTimeout);
+ stopAnimatTimeout = null;
- recoverRefresh();
+ recoverRefresh();
+ }
}
- }
- // Destory refresh
- mRefresh.destroy = function(){
- unbindEvents();
- $refreshMain.remove();
+ // Destory refresh
+ mRefresh.destroy = function(){
+ unbindEvents();
+ refreshMain.parentNode.removeChild(refreshMain);
- }
+ }
- // Type3: Button action refresh
- mRefresh.refresh = function(opt) {
- // Do rotate
- if(!isShowLoading){
- var realTargetPos = basePosY + NUM_POS_TARGET_Y - 20;
- isShowLoading = true;
- isBtnAction = true;
+ // Type3: Button action refresh
+ mRefresh.refresh = function(opt) {
+ // Do rotate
+ if(!isShowLoading){
+ var realTargetPos = basePosY + NUM_POS_TARGET_Y - 20;
+ isShowLoading = true;
+ isBtnAction = true;
- opt = opt || {};
- onBtnBegin = opt.onBegin;
- onBtnEnd = opt.onEnd;
+ opt = opt || {};
+ onBtnBegin = opt.onBegin;
+ onBtnEnd = opt.onEnd;
- if (!isDefaultType()) {
- realTargetPos = realTargetPos + NUM_NAV_TARGET_ADDY;
+ if (!isDefaultType()) {
+ realTargetPos = realTargetPos + NUM_NAV_TARGET_ADDY;
+ }
+
+ // Handle freeze
+ refreshMain.style.display = '';
+ //Romove animat time
+ refreshMain.classList.remove(mainAnimatClass);
+ // move to target position
+ refreshMain.style.top = realTargetPos + 'px';
+ // make it small
+ refreshMain.style.webkitTransform = 'scale(' + 0.01 + ')';
+
+ setTimeout(doRotate, 60);
}
-
- // Handle freeze
- $refreshMain.show();
- //Romove animat time
- $refreshMain.removeClass(mainAnimatClass);
- // move to target position
- $refreshMain.css('top', realTargetPos + 'px');
- // make it small
- $refreshMain.css('-webkit-transform', 'scale(' + 0.01 + ')');
-
- setTimeout(doRotate, 60);
}
- }
-
- // Unbind touch events,for freeze type1 and type2
- mRefresh.unbindEvents = function(){
- unbindEvents();
- }
-
- mRefresh.bindEvents = function(){
- bindEvents();
- }
-
- // Render html template
- function renderTmpl(){
- document.body.insertAdjacentHTML('beforeend', tmpl);
- }
-
-
- function touchStart(e){
- if(isIOS && scrollEl == document.body){
- touchPos.top = window.scrollY;
- }else if(scrollEl != document){
- touchPos.top = document.querySelector(scrollEl).scrollTop;
- } else {
- touchPos.top = (document.documentElement || document.body.parentNode || document.body).scrollTop;
+
+ // Unbind touch events,for freeze type1 and type2
+ mRefresh.unbindEvents = function(){
+ unbindEvents();
}
- if (touchPos.top > 0 || isShowLoading) {
- return;
+ mRefresh.bindEvents = function(){
+ bindEvents();
}
- touchCurrentY = basePosY + NUM_POS_START_Y;
- $refreshMain.show();
-
- if (e.touches[0]) {
- touchPos.x1 = e.touches[0].pageX;
- touchStartY = touchPos.y1 = e.touches[0].pageY;
+ // Render html template
+ function renderTmpl(){
+ document.body.insertAdjacentHTML('beforeend', tmpl);
}
- }
- function touchMove(e){
- var thisTouch, distanceY;
- var now = new Date().getTime();
- if (touchPos.top > 0 || isShowLoading || !e.touches || e.touches.length !== 1) {
- // Just allow one finger
- return;
- }
+ function touchStart(e){
+ if(isIOS && scrollEl == document.body){
+ touchPos.top = window.scrollY;
+ }else if(scrollEl != document){
+ touchPos.top = scrollEl.scrollTop;
+ } else {
+ touchPos.top = (document.documentElement || document.body.parentNode || document.body).scrollTop;
+ }
- thisTouch = e.touches[0];
+ if (touchPos.top > 0 || isShowLoading) {
+ return;
+ }
- touchPos.x2 = thisTouch.pageX;
- touchPos.y2 = thisTouch.pageY;
+ touchCurrentY = basePosY + NUM_POS_START_Y;
+ refreshMain.style.display = '';
- // Distance for pageY change
- distanceY = touchPos.y2 - touchPos.y1;
+ if (e.touches[0]) {
+ touchPos.x1 = e.touches[0].pageX;
+ touchStartY = touchPos.y1 = e.touches[0].pageY;
+ }
+ }
- if (touchPos.y2 - touchStartY + verticalThreshold > 0) {
- e.preventDefault();
+ function touchMove(e){
+ var thisTouch, distanceY;
+ var now = new Date().getTime();
- // Some android phone
- // Throttle, aviod jitter
- if (now - lastTime < 90) {
+ if (touchPos.top > 0 || isShowLoading || !e.touches || e.touches.length !== 1) {
+ // Just allow one finger
return;
}
- if (touchCurrentY < basePosY - customNavTop + NUM_POS_MAX_Y) {
- touchCurrentY += distanceY ;
- moveCircle(touchCurrentY);
- } else {
- // Move over the max position will do the rotate
- doRotate();
- return;
+ thisTouch = e.touches[0];
+
+ touchPos.x2 = thisTouch.pageX;
+ touchPos.y2 = thisTouch.pageY;
+
+ // Distance for pageY change
+ distanceY = touchPos.y2 - touchPos.y1;
+
+ if (touchPos.y2 - touchStartY + verticalThreshold > 0) {
+ e.preventDefault();
+
+ // Some android phone
+ // Throttle, aviod jitter
+ if (now - lastTime < 90) {
+ return;
+ }
+
+ if (touchCurrentY < basePosY - customNavTop + NUM_POS_MAX_Y) {
+ touchCurrentY += distanceY ;
+ moveCircle(touchCurrentY);
+ } else {
+ // Move over the max position will do the rotate
+ doRotate();
+ return;
+ }
+
}
+ // y1 always is the current pageY
+ touchPos.y1 = thisTouch.pageY;
+ lastTime = now;
}
- // y1 always is the current pageY
- touchPos.y1 = thisTouch.pageY;
- lastTime = now;
- }
+ function touchEnd(e){
+ if (touchPos.top > 0 || isShowLoading) {
+ return;
+ }
+ e.preventDefault();
- function touchEnd(e){
- if (touchPos.top > 0 || isShowLoading) {
- return;
- }
- e.preventDefault();
-
- if (touchCurrentY > basePosY - customNavTop + NUM_POS_MIN_Y) {
- // Should move over the min position
- doRotate();
- } else {
- backToStart();
- }
- }
-
- /**
- * backToStart
- * Return to start position
- */
- function backToStart() {
- var realStartPos = basePosY + NUM_POS_START_Y;
- if ( isDefaultType() ) {
- $refreshMain.css('top', realStartPos + 'px');
- $refreshMain.css('-webkit-transform', 'scale(' + 0 + ')');
- } else {
- // Distance must greater than NUM_POS_MIN_Y
- $refreshMain.css('top', customNavTop + 'px');
- /* $refreshMain.css('-webkit-transform', 'translateY(' + realStartPos + 'px)'); */
+ if (touchCurrentY > basePosY - customNavTop + NUM_POS_MIN_Y) {
+ // Should move over the min position
+ doRotate();
+ } else {
+ backToStart();
+ }
}
- setTimeout(function(){
- // Handle button action
- if(!isShowLoading){
- $refreshMain.css('opacity', 0);
- $refreshMain.hide();
+
+ /**
+ * backToStart
+ * Return to start position
+ */
+ function backToStart() {
+ var realStartPos = basePosY + NUM_POS_START_Y;
+ if ( isDefaultType() ) {
+ refreshMain.style.top = realStartPos + 'px';
+ refreshMain.style.webkitTransform = 'scale(' + 0 + ')';
+ } else {
+ // Distance must greater than NUM_POS_MIN_Y
+ refreshMain.style.top = customNavTop + 'px';
+ /* refreshMain.style.webkitTransform = 'translateY(' + realStartPos + 'px)'; */
}
- }, 300);
- }
-
- /**
- * moveCircle
- * touchmove change the circle style
- *
- * @param {number} y
- */
- function moveCircle(y){
- var scaleRate = 40;
- var scalePer = y / scaleRate > 1 ? 1 : y / scaleRate < 0 ? 0 : y / scaleRate;
- var currMoveY = basePosY + NUM_POS_START_Y + y;
-
- if (isDefaultType()) {
- // Small to Big
- $refreshMain.css('-webkit-transform', 'scale(' + scalePer + ')');
+ setTimeout(function(){
+ // Handle button action
+ if(!isShowLoading){
+ refreshMain.style.opacity = 0;
+ refreshMain.style.display = 'none';
+ }
+ }, 300);
}
- /* $refreshMain.css('-webkit-transform', 'translateY('+ y + 'px)'); */
-
- $refreshMain.css('opacity', scalePer);
- // Change the position
- $refreshMain.css('top', currMoveY + 'px');
- $arrowMain.css('-webkit-transform', 'rotate(' + -(y * 3) + 'deg)');
- /* $arrowMain.css('transform', 'rotate(' + -(y * 3) + 'deg)'); */
-
- }
-
-
- /**
- * doRotate
- * Rotate the circle,and you can stop it by `mRefresh.resolve()`
- * or it wil stop within the time: `maxRotateTime`
- */
- function doRotate(){
- isShowLoading = true;
- // Do button action callback
- if (isBtnAction && typeof onBtnBegin === 'function') {
- onBtnBegin();
- } else if (typeof onBegin === 'function') {
- // Do onBegin callback
- onBegin();
+
+ /**
+ * moveCircle
+ * touchmove change the circle style
+ *
+ * @param {number} y
+ */
+ function moveCircle(y){
+ var scaleRate = 40;
+ var scalePer = y / scaleRate > 1 ? 1 : y / scaleRate < 0 ? 0 : y / scaleRate;
+ var currMoveY = basePosY + NUM_POS_START_Y + y;
+
+ if (isDefaultType()) {
+ // Small to Big
+ refreshMain.style.webkitTransform = 'scale(' + scalePer + ')';
+ }
+ /* refreshMain.style.webkitTransform = 'translateY('+ y + 'px)'; */
+
+ refreshMain.style.opacity = scalePer;
+ // Change the position
+ refreshMain.style.top = currMoveY + 'px';
+ arrowMain.style.webkitTransform = 'rotate(' + -(y * 3) + 'deg)';
+ /* arrowMain.style.transform = 'rotate(' + -(y * 3) + 'deg)'; */
+
}
- // Make sure display entirely
- $refreshMain.css('opacity', 1);
- if (!isBtnAction) {
- var realTargetPos = basePosY + NUM_POS_TARGET_Y - 20;
- if (!isDefaultType()) {
- realTargetPos = realTargetPos + NUM_NAV_TARGET_ADDY;
+ /**
+ * doRotate
+ * Rotate the circle,and you can stop it by `mRefresh.resolve()`
+ * or it wil stop within the time: `maxRotateTime`
+ */
+ function doRotate(){
+ isShowLoading = true;
+ // Do button action callback
+ if (isBtnAction && typeof onBtnBegin === 'function') {
+ onBtnBegin();
+ } else if (typeof onBegin === 'function') {
+ // Do onBegin callback
+ onBegin();
}
- $refreshMain.css('top', realTargetPos + 'px');
- /* $refreshMain.css('-webkit-transform', 'translateY(' + realTargetPos + 'px)'); */
- } else {
- $refreshMain.addClass(mainAnimatClass);
- $refreshMain.css('-webkit-transform', 'scale(' + 1 + ')');
+
+ // Make sure display entirely
+ refreshMain.style.opacity = 1;
+
+ if (!isBtnAction) {
+ var realTargetPos = basePosY + NUM_POS_TARGET_Y - 20;
+ if (!isDefaultType()) {
+ realTargetPos = realTargetPos + NUM_NAV_TARGET_ADDY;
+ }
+ refreshMain.style.top = realTargetPos + 'px';
+ /* refreshMain.style.webkitTransform = 'translateY(' + realTargetPos + 'px)'; */
+ } else {
+ refreshMain.classList.add(mainAnimatClass);
+ refreshMain.style.webkitTransform = 'scale(' + 1 + ')';
+ }
+
+ arrowWrapper.style.display = 'none';
+
+ // Start animation
+ spinnerWrapper.style.display = '';
+
+ // Timeout to stop animation
+ stopAnimatTimeout = setTimeout(recoverRefresh, maxRotateTime);
}
- $arrowWrapper.hide();
+ /**
+ * Recover Refresh
+ * Hide the circle
+ */
+ function recoverRefresh(){
+ // For aviod resolve
+ isStoping = true;
- // Start animation
- $spinnerWrapper.show();
+ // Stop animation
+ refreshMain.classList.add(noShowClass);
- // Timeout to stop animation
- stopAnimatTimeout = setTimeout(recoverRefresh, maxRotateTime);
- }
+ spinnerWrapper.style.display = 'none';
- /**
- * Recover Refresh
- * Hide the circle
- */
- function recoverRefresh(){
- // For aviod resolve
- isStoping = true;
+ setTimeout(function(){
+ refreshMain.classList.remove(noShowClass);
+ refreshMain.style.display = 'none';
- // Stop animation
- $refreshMain.addClass(noShowClass);
+ backToStart();
- $spinnerWrapper.hide();
+ arrowWrapper.style.display = '';
- setTimeout(function(){
- $refreshMain.removeClass(noShowClass);
- $refreshMain.hide();
-
- backToStart();
+ isShowLoading = false;
+ isStoping = false;
- $arrowWrapper.show();
+ if (isBtnAction && typeof onBtnEnd === 'function') {
+ onBtnEnd();
+ } else if (typeof onEnd === 'function') {
+ onEnd();
+ }
- isShowLoading = false;
- isStoping = false;
+ isBtnAction = false;
- if (isBtnAction && typeof onBtnEnd === 'function') {
- onBtnEnd();
- } else if (typeof onEnd === 'function') {
- onEnd();
- }
-
- isBtnAction = false;
-
- }, 500);
- }
-
- /**
- * isDefaultType
- * Check is type1: Above surface
- *
- * @return {Boolen}
- */
- function isDefaultType() {
- return $(refreshNav).length === 0;
- }
-
- function bindEvents() {
- $scrollEl.on('touchstart', touchStart);
- $scrollEl.on('touchmove', touchMove);
- $scrollEl.on('touchend', touchEnd);
- }
-
- function unbindEvents() {
- $scrollEl.off('touchstart', touchStart);
- $scrollEl.off('touchmove', touchMove);
- $scrollEl.off('touchend', touchEnd);
- }
-
-
- window.mRefresh = mRefresh;
-
-})(Zepto || jQuery);
+ }, 500);
+ }
+
+ /**
+ * isDefaultType
+ * Check is type1: Above surface
+ *
+ * @return {Boolen}
+ */
+ function isDefaultType() {
+ return !refreshNav;
+ }
+
+ function bindEvents() {
+ scrollEl.addEventListener('touchstart', touchStart);
+ scrollEl.addEventListener('touchmove', touchMove);
+ scrollEl.addEventListener('touchend', touchEnd);
+ }
+
+ function unbindEvents() {
+ scrollEl.removeEventListener('touchstart', touchStart);
+ scrollEl.removeEventListener('touchmove', touchMove);
+ scrollEl.removeEventListener('touchend', touchEnd);
+ }
+
+
+ window.mRefresh = mRefresh;
+ })();
+}).call(this);
\ No newline at end of file
diff --git a/material-refresh.min.js b/material-refresh.min.js
index 55c88b1..a7bef5e 100644
--- a/material-refresh.min.js
+++ b/material-refresh.min.js
@@ -1 +1 @@
-(function(){"use strict";!function(e){function o(o){if(o=o||{},x=o.scrollEl?o.scrollEl:G?x:document,w=e(x),L=o.onBegin,N=o.onEnd,A=o.maxTime||A,Z=o.nav||Z,0===e("#muirefresh").length&&n(),m=e("#muiRefresh"),p=e(".mui-spinner-wrapper",m),h=e(".mui-arrow-wrapper",m),v=e(".mui-arrow-main",m),!d()){m.addClass("mui-refresh-nav"),H=e(Z).height()+20,e(Z).offset()&&(X=e(Z).offset().top,"fixed"!==e(Z).css("position")&&(H+=X),m.css("top",X+"px"));var s=e(Z).css("z-index");m.css("z-index",s-1)}o.index&&m.css("z-index",~~o.index),o.top&&m.css("top",o.top),m.addClass(o.theme?o.theme:T),m.addClass(g),o.freeze||f()}function n(){document.body.insertAdjacentHTML("beforeend",I)}function s(e){J.top=G&&x==document.body?window.scrollY:x!=document?document.querySelector(x).scrollTop:(document.documentElement||document.body.parentNode||document.body).scrollTop,J.top>0||C||(y=H+z,m.show(),e.touches[0]&&(J.x1=e.touches[0].pageX,B=J.y1=e.touches[0].pageY))}function t(e){var o,n,s=(new Date).getTime();if(!(J.top>0||C)&&e.touches&&1===e.touches.length){if(o=e.touches[0],J.x2=o.pageX,J.y2=o.pageY,n=J.y2-J.y1,J.y2-B+q>0){if(e.preventDefault(),90>s-F)return;if(!(H-X+Y>y))return void u();y+=n,r(y)}J.y1=o.pageY,F=s}}function i(e){J.top>0||C||(e.preventDefault(),y>H-X+R?u():c())}function c(){var e=H+z;d()?(m.css("top",e+"px"),m.css("-webkit-transform","scale(0)")):m.css("top",X+"px"),setTimeout(function(){C||(m.css("opacity",0),m.hide())},300)}function r(e){var o=40,n=e/o>1?1:0>e/o?0:e/o,s=H+z+e;d()&&m.css("-webkit-transform","scale("+n+")"),m.css("opacity",n),m.css("top",s+"px"),v.css("-webkit-transform","rotate("+-(3*e)+"deg)")}function u(){if(C=!0,k&&"function"==typeof M?M():"function"==typeof L&&L(),m.css("opacity",1),k)m.addClass(g),m.css("-webkit-transform","scale(1)");else{var e=H+D-20;d()||(e+=j),m.css("top",e+"px")}h.hide(),p.show(),S=setTimeout(a,A)}function a(){E=!0,m.addClass(b),p.hide(),setTimeout(function(){m.removeClass(b),m.hide(),c(),h.show(),C=!1,E=!1,k&&"function"==typeof Q?Q():"function"==typeof N&&N(),k=!1},500)}function d(){return 0===e(Z).length}function f(){w.on("touchstart",s),w.on("touchmove",t),w.on("touchend",i)}function l(){w.off("touchstart",s),w.off("touchmove",t),w.off("touchend",i)}var m,p,h,v,y,w=e(document.body),x=document.body,b="mui-refresh-noshow",g="mui-refresh-main-animat",T="mui-blue-theme",C=!1,E=!1,k=!1,z=-85,D=0,Y=65,R=-25,j=20,B=0,X=0,q=2,A=6e3,H=60,L=null,M=null,N=null,Q=null,S=null,Z="",F=(new Date).getTime(),G=e.os.ios,I='
',J={top:0,x1:0,x2:0,y1:0,y2:0};o.resolve=function(){!E&&S&&(clearTimeout(S),S=null,a())},o.destroy=function(){l(),m.remove()},o.refresh=function(e){if(!C){var o=H+D-20;C=!0,k=!0,e=e||{},M=e.onBegin,Q=e.onEnd,d()||(o+=j),m.show(),m.removeClass(g),m.css("top",o+"px"),m.css("-webkit-transform","scale(0.01)"),setTimeout(u,60)}},o.unbindEvents=function(){l()},o.bindEvents=function(){f()},window.mRefresh=o}(Zepto||jQuery)}).call(this);
\ No newline at end of file
+(function(){"use strict";!function(){function e(e){if(e=e||{},h=K(e.scrollEl||(F?h:document)),M=e.onBegin,N=e.onEnd,C=e.maxTime||C,j=K(e.nav||j),K("#muirefresh")||t(),p=K("#muiRefresh"),m=K(p,".mui-spinner-wrapper"),f=K(p,".mui-arrow-wrapper"),y=K(p,".mui-arrow-main"),!u()){p.classList.add("mui-refresh-nav"),H=j.clientHeight+20;var n;if(n=j.getBoundingClientRect()){var i=n.top+document.body.scrollTop;n.left+document.body.scrollLeft;Y=i,"fixed"!==j.style.position&&(H+=Y),p.style.top=Y+"px"}var s=window.getComputedStyle(j).zIndex;p.style.zIndex=Math.max(1,parseInt(s)-1)}e.index&&(p.style.zIndex=~~e.index),e.top&&(p.style.top=e.top),e.theme?p.classList.add(e.theme):p.classList.add(x),p.classList.add(g),e.freeze||d()}function t(){document.body.insertAdjacentHTML("beforeend",G)}function n(e){F&&h==document.body?J.top=window.scrollY:h!=document?J.top=h.scrollTop:J.top=(document.documentElement||document.body.parentNode||document.body).scrollTop,J.top>0||T||(v=H+E,p.style.display="",e.touches[0]&&(J.x1=e.touches[0].pageX,R=J.y1=e.touches[0].pageY))}function i(e){var t,n,i=(new Date).getTime();if(!(J.top>0||T)&&e.touches&&1===e.touches.length){if(t=e.touches[0],J.x2=t.pageX,J.y2=t.pageY,n=J.y2-J.y1,J.y2-R+B>0){if(e.preventDefault(),i-q<90)return;if(!(v
0||T||(e.preventDefault(),v>H-Y+D?l():o())}function o(){var e=H+E;u()?(p.style.top=e+"px",p.style.webkitTransform="scale(0)"):p.style.top=Y+"px",setTimeout(function(){T||(p.style.opacity=0,p.style.display="none")},300)}function r(e){var t=40,n=e/t>1?1:e/t<0?0:e/t,i=H+E+e;u()&&(p.style.webkitTransform="scale("+n+")"),p.style.opacity=n,p.style.top=i+"px",y.style.webkitTransform="rotate("+-(3*e)+"deg)"}function l(){if(T=!0,b&&"function"==typeof A?A():"function"==typeof M&&M(),p.style.opacity=1,b)p.classList.add(g),p.style.webkitTransform="scale(1)";else{var e=H+k-20;u()||(e+=I),p.style.top=e+"px"}f.style.display="none",m.style.display="",X=setTimeout(a,C)}function a(){L=!0,p.classList.add(w),m.style.display="none",setTimeout(function(){p.classList.remove(w),p.style.display="none",o(),f.style.display="",T=!1,L=!1,b&&"function"==typeof S?S():"function"==typeof N&&N(),b=!1},500)}function u(){return!j}function d(){h.addEventListener("touchstart",n),h.addEventListener("touchmove",i),h.addEventListener("touchend",s)}function c(){h.removeEventListener("touchstart",n),h.removeEventListener("touchmove",i),h.removeEventListener("touchend",s)}var p,m,f,y,v,h=document.body,w="mui-refresh-noshow",g="mui-refresh-main-animat",x="mui-blue-theme",T=!1,L=!1,b=!1,E=-85,k=0,z=65,D=-25,I=20,R=0,Y=0,B=2,C=6e3,H=60,M=null,A=null,N=null,S=null,X=null,j="",q=(new Date).getTime(),F=/ip(hone|ad|od)/i.test(navigator.userAgent),G='',J={top:0,x1:0,x2:0,y1:0,y2:0},K=function(){var e,t;return 1===arguments.length?(t=arguments[0],e=document):(e=arguments[0],t=arguments[1]),t&&"string"==typeof t?e.querySelector(t):t instanceof HTMLElement?t:null};e.resolve=function(){!L&&X&&(clearTimeout(X),X=null,a())},e.destroy=function(){c(),p.parentNode.removeChild(p)},e.refresh=function(e){if(!T){var t=H+k-20;T=!0,b=!0,e=e||{},A=e.onBegin,S=e.onEnd,u()||(t+=I),p.style.display="",p.classList.remove(g),p.style.top=t+"px",p.style.webkitTransform="scale(0.01)",setTimeout(l,60)}},e.unbindEvents=function(){c()},e.bindEvents=function(){d()},window.mRefresh=e}()}).call(this);
\ No newline at end of file
diff --git a/src/js/main.js b/src/js/main.js
index ed5546c..3ba0dd0 100644
--- a/src/js/main.js
+++ b/src/js/main.js
@@ -1,17 +1,16 @@
/**
- * Google Material Design Swipe To Refresh.
+ * Google Material Design Swipe To Refresh.
* By Gctang(https://github.com/lightningtgc)
*
* Three types of refresh:
* 1. Above or coplanar with another surface
- * 2. Below another surface in z-space.
+ * 2. Below another surface in z-space.
* 3. Button action refresh
*
*/
-;(function($){
- var $scrollEl = $(document.body);
- var $refreshMain, $spinnerWrapper, $arrowWrapper, $arrowMain;
+;(function() {
+ var refreshMain, spinnerWrapper, arrowWrapper, arrowMain;
var scrollEl = document.body;
var noShowClass = 'mui-refresh-noshow';
@@ -40,12 +39,12 @@
var onEnd = null;
var onBtnEnd = null;
var stopAnimatTimeout = null;
-
+
var refreshNav = '';
var lastTime = new Date().getTime();
- var isIOS = $.os.ios;
+ var isIOS = /ip(hone|ad|od)/i.test(navigator.userAgent);
var tmpl = '\
\
@@ -74,7 +73,7 @@
y2: 0
}
- // Default options
+ // Default options
/* var opts = { */
/* scrollEl: '', //String */
/* nav: '', //String */
@@ -87,78 +86,96 @@
/* onEnd: null //Function */
/* } */
-
- /* Known issue:
- * 1. iOS feature when scrolling ,animation will stop
+
+ /* Known issue:
+ * 1. iOS feature when scrolling ,animation will stop
* 2. Animation display issue in anfroid like miui小米
*
*
* TODO list:
- * 1. Using translate and scale together to replace top
+ * 1. Using translate and scale together to replace top
* 2. Optimize circle rotate animation
*/
+ var $ = function() {
+ var parent, el;
+
+ if (arguments.length === 1) {
+ el = arguments[0];
+ parent = document;
+ } else {
+ parent = arguments[0];
+ el = arguments[1];
+ }
+
+ return el && (typeof el) === 'string' ? parent.querySelector(el)
+ : el instanceof HTMLElement ? el
+ : null;
+ }
+
// Main function to init the refresh style
function mRefresh(options) {
options = options || {};
- scrollEl = options.scrollEl ? options.scrollEl :
- isIOS ? scrollEl : document;
- $scrollEl = $(scrollEl);
+ scrollEl = $(options.scrollEl || (isIOS ? scrollEl : document));
// extend options
onBegin = options.onBegin;
onEnd = options.onEnd;
maxRotateTime = options.maxTime || maxRotateTime;
- refreshNav = options.nav || refreshNav;
+ refreshNav = $(options.nav || refreshNav);
- if ($('#muirefresh').length === 0) {
+ if (!$('#muirefresh')) {
renderTmpl();
}
- $refreshMain = $('#muiRefresh');
- $spinnerWrapper = $('.mui-spinner-wrapper', $refreshMain);
- $arrowWrapper = $('.mui-arrow-wrapper', $refreshMain);
- $arrowMain = $('.mui-arrow-main', $refreshMain);
+ refreshMain = $('#muiRefresh');
+ spinnerWrapper = $(refreshMain, '.mui-spinner-wrapper');
+ arrowWrapper = $(refreshMain, '.mui-arrow-wrapper');
+ arrowMain = $(refreshMain, '.mui-arrow-main');
- // Custom nav bar
+ // Custom nav bar
if (!isDefaultType()) {
- $refreshMain.addClass('mui-refresh-nav');
- basePosY = $(refreshNav).height() + 20;
- if($(refreshNav).offset()){
- customNavTop = $(refreshNav).offset().top;
+ refreshMain.classList.add('mui-refresh-nav');
+ basePosY = refreshNav.clientHeight + 20;
+ var rect;
+ if(rect = refreshNav.getBoundingClientRect()){
+ var top = rect.top + document.body.scrollTop,
+ left = rect.left + document.body.scrollLeft;
+
+ customNavTop = top;
// Handle position fix
- if($(refreshNav).css('position') !== 'fixed'){
+ if(refreshNav.style.position !== 'fixed'){
basePosY += customNavTop;
}
// Set the first Y position
- $refreshMain.css('top', customNavTop + 'px');
+ refreshMain.style.top = customNavTop + 'px';
}
//Set z-index to make sure ablow the nav bar
- var navIndex = $(refreshNav).css('z-index');
- $refreshMain.css('z-index', navIndex - 1);
+ var navIndex = window.getComputedStyle(refreshNav).zIndex;
+ refreshMain.style.zIndex = Math.max(1, parseInt(navIndex) - 1);
}
//Set custom z-index
if(options.index){
- $refreshMain.css('z-index', ~~options.index);
+ refreshMain.style.zIndex = ~~options.index;
}
//Set custom top, to change the position
if(options.top){
- $refreshMain.css('top', options.top);
+ refreshMain.style.top = options.top;
}
- // Extract theme
+ // Extract theme
if (options.theme) {
- $refreshMain.addClass(options.theme);
+ refreshMain.classList.add(options.theme);
} else {
- $refreshMain.addClass(blueThemeClass);
+ refreshMain.classList.add(blueThemeClass);
}
// Add Animation Class
- $refreshMain.addClass(mainAnimatClass);
+ refreshMain.classList.add(mainAnimatClass);
if(!options.freeze){
bindEvents();
@@ -180,7 +197,7 @@
// Destory refresh
mRefresh.destroy = function(){
unbindEvents();
- $refreshMain.remove();
+ refreshMain.parentNode.removeChild(refreshMain);
}
@@ -199,16 +216,16 @@
if (!isDefaultType()) {
realTargetPos = realTargetPos + NUM_NAV_TARGET_ADDY;
}
-
+
// Handle freeze
- $refreshMain.show();
+ refreshMain.style.display = '';
//Romove animat time
- $refreshMain.removeClass(mainAnimatClass);
+ refreshMain.classList.remove(mainAnimatClass);
// move to target position
- $refreshMain.css('top', realTargetPos + 'px');
+ refreshMain.style.top = realTargetPos + 'px';
// make it small
- $refreshMain.css('-webkit-transform', 'scale(' + 0.01 + ')');
-
+ refreshMain.style.webkitTransform = 'scale(' + 0.01 + ')';
+
setTimeout(doRotate, 60);
}
}
@@ -232,7 +249,7 @@
if(isIOS && scrollEl == document.body){
touchPos.top = window.scrollY;
}else if(scrollEl != document){
- touchPos.top = document.querySelector(scrollEl).scrollTop;
+ touchPos.top = scrollEl.scrollTop;
} else {
touchPos.top = (document.documentElement || document.body.parentNode || document.body).scrollTop;
}
@@ -242,8 +259,8 @@
}
touchCurrentY = basePosY + NUM_POS_START_Y;
- $refreshMain.show();
-
+ refreshMain.style.display = '';
+
if (e.touches[0]) {
touchPos.x1 = e.touches[0].pageX;
touchStartY = touchPos.y1 = e.touches[0].pageY;
@@ -268,10 +285,10 @@
distanceY = touchPos.y2 - touchPos.y1;
if (touchPos.y2 - touchStartY + verticalThreshold > 0) {
- e.preventDefault();
+ e.preventDefault();
// Some android phone
- // Throttle, aviod jitter
+ // Throttle, aviod jitter
if (now - lastTime < 90) {
return;
}
@@ -297,7 +314,7 @@
return;
}
e.preventDefault();
-
+
if (touchCurrentY > basePosY - customNavTop + NUM_POS_MIN_Y) {
// Should move over the min position
doRotate();
@@ -305,7 +322,7 @@
backToStart();
}
}
-
+
/**
* backToStart
* Return to start position
@@ -313,18 +330,18 @@
function backToStart() {
var realStartPos = basePosY + NUM_POS_START_Y;
if ( isDefaultType() ) {
- $refreshMain.css('top', realStartPos + 'px');
- $refreshMain.css('-webkit-transform', 'scale(' + 0 + ')');
+ refreshMain.style.top = realStartPos + 'px';
+ refreshMain.style.webkitTransform = 'scale(' + 0 + ')';
} else {
// Distance must greater than NUM_POS_MIN_Y
- $refreshMain.css('top', customNavTop + 'px');
- /* $refreshMain.css('-webkit-transform', 'translateY(' + realStartPos + 'px)'); */
+ refreshMain.style.top = customNavTop + 'px';
+ /* refreshMain.style.webkitTransform = 'translateY(' + realStartPos + 'px)'; */
}
setTimeout(function(){
// Handle button action
if(!isShowLoading){
- $refreshMain.css('opacity', 0);
- $refreshMain.hide();
+ refreshMain.style.opacity = 0;
+ refreshMain.style.display = 'none';
}
}, 300);
}
@@ -342,15 +359,15 @@
if (isDefaultType()) {
// Small to Big
- $refreshMain.css('-webkit-transform', 'scale(' + scalePer + ')');
+ refreshMain.style.webkitTransform = 'scale(' + scalePer + ')';
}
- /* $refreshMain.css('-webkit-transform', 'translateY('+ y + 'px)'); */
+ /* refreshMain.style.webkitTransform = 'translateY('+ y + 'px)'; */
- $refreshMain.css('opacity', scalePer);
+ refreshMain.style.opacity = scalePer;
// Change the position
- $refreshMain.css('top', currMoveY + 'px');
- $arrowMain.css('-webkit-transform', 'rotate(' + -(y * 3) + 'deg)');
- /* $arrowMain.css('transform', 'rotate(' + -(y * 3) + 'deg)'); */
+ refreshMain.style.top = currMoveY + 'px';
+ arrowMain.style.webkitTransform = 'rotate(' + -(y * 3) + 'deg)';
+ /* arrowMain.style.transform = 'rotate(' + -(y * 3) + 'deg)'; */
}
@@ -371,24 +388,24 @@
}
// Make sure display entirely
- $refreshMain.css('opacity', 1);
+ refreshMain.style.opacity = 1;
- if (!isBtnAction) {
+ if (!isBtnAction) {
var realTargetPos = basePosY + NUM_POS_TARGET_Y - 20;
if (!isDefaultType()) {
realTargetPos = realTargetPos + NUM_NAV_TARGET_ADDY;
}
- $refreshMain.css('top', realTargetPos + 'px');
- /* $refreshMain.css('-webkit-transform', 'translateY(' + realTargetPos + 'px)'); */
+ refreshMain.style.top = realTargetPos + 'px';
+ /* refreshMain.style.webkitTransform = 'translateY(' + realTargetPos + 'px)'; */
} else {
- $refreshMain.addClass(mainAnimatClass);
- $refreshMain.css('-webkit-transform', 'scale(' + 1 + ')');
+ refreshMain.classList.add(mainAnimatClass);
+ refreshMain.style.webkitTransform = 'scale(' + 1 + ')';
}
- $arrowWrapper.hide();
+ arrowWrapper.style.display = 'none';
// Start animation
- $spinnerWrapper.show();
+ spinnerWrapper.style.display = '';
// Timeout to stop animation
stopAnimatTimeout = setTimeout(recoverRefresh, maxRotateTime);
@@ -396,24 +413,24 @@
/**
* Recover Refresh
- * Hide the circle
+ * Hide the circle
*/
function recoverRefresh(){
// For aviod resolve
isStoping = true;
- // Stop animation
- $refreshMain.addClass(noShowClass);
+ // Stop animation
+ refreshMain.classList.add(noShowClass);
- $spinnerWrapper.hide();
+ spinnerWrapper.style.display = 'none';
setTimeout(function(){
- $refreshMain.removeClass(noShowClass);
- $refreshMain.hide();
-
+ refreshMain.classList.remove(noShowClass);
+ refreshMain.style.display = 'none';
+
backToStart();
- $arrowWrapper.show();
+ arrowWrapper.style.display = '';
isShowLoading = false;
isStoping = false;
@@ -423,9 +440,9 @@
} else if (typeof onEnd === 'function') {
onEnd();
}
-
+
isBtnAction = false;
-
+
}, 500);
}
@@ -436,23 +453,22 @@
* @return {Boolen}
*/
function isDefaultType() {
- return $(refreshNav).length === 0;
+ return !refreshNav;
}
function bindEvents() {
- $scrollEl.on('touchstart', touchStart);
- $scrollEl.on('touchmove', touchMove);
- $scrollEl.on('touchend', touchEnd);
+ scrollEl.addEventListener('touchstart', touchStart);
+ scrollEl.addEventListener('touchmove', touchMove);
+ scrollEl.addEventListener('touchend', touchEnd);
}
function unbindEvents() {
- $scrollEl.off('touchstart', touchStart);
- $scrollEl.off('touchmove', touchMove);
- $scrollEl.off('touchend', touchEnd);
+ scrollEl.removeEventListener('touchstart', touchStart);
+ scrollEl.removeEventListener('touchmove', touchMove);
+ scrollEl.removeEventListener('touchend', touchEnd);
}
window.mRefresh = mRefresh;
-})(Zepto || jQuery);
-
+})();