diff --git a/build/js/material-refresh.js b/build/js/material-refresh.js index 7ea6c9b..3e8f1e3 100644 --- a/build/js/material-refresh.js +++ b/build/js/material-refresh.js @@ -1,8 +1,7 @@ (function() { "use strict"; - (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'; @@ -31,12 +30,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 = '
\
\ @@ -65,7 +64,7 @@ y2: 0 } - // Default options + // Default options /* var opts = { */ /* scrollEl: '', //String */ /* nav: '', //String */ @@ -78,78 +77,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(); @@ -171,7 +188,7 @@ // Destory refresh mRefresh.destroy = function(){ unbindEvents(); - $refreshMain.remove(); + refreshMain.parentNode.removeChild(refreshMain); } @@ -190,16 +207,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); } } @@ -223,7 +240,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; } @@ -233,8 +250,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; @@ -259,10 +276,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; } @@ -288,7 +305,7 @@ return; } e.preventDefault(); - + if (touchCurrentY > basePosY - customNavTop + NUM_POS_MIN_Y) { // Should move over the min position doRotate(); @@ -296,7 +313,7 @@ backToStart(); } } - + /** * backToStart * Return to start position @@ -304,18 +321,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); } @@ -333,15 +350,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)'; */ } @@ -362,24 +379,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); @@ -387,24 +404,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; @@ -414,9 +431,9 @@ } else if (typeof onEnd === 'function') { onEnd(); } - + isBtnAction = false; - + }, 500); } @@ -427,23 +444,23 @@ * @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); + })(); }).call(this); \ No newline at end of file diff --git a/build/js/material-refresh.min.js b/build/js/material-refresh.min.js index 55c88b1..a7bef5e 100644 --- a/build/js/material-refresh.min.js +++ b/build/js/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(!(v0||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/material-refresh.js b/material-refresh.js index ed5546c..3e8f1e3 100644 --- a/material-refresh.js +++ b/material-refresh.js @@ -1,458 +1,466 @@ -/** - * 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. - * 3. Button action refresh - * - */ - -;(function($){ - var $scrollEl = $(document.body); - 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 = $.os.ios; - - var tmpl = '
\ -
\ -
\ -
\ -
\ -