From d83c6a1a1393059ec31c26d57413af7d618f19a4 Mon Sep 17 00:00:00 2001 From: Rafael Belvederese Date: Wed, 13 May 2015 18:11:22 -0300 Subject: [PATCH 1/2] no dependencies. --- build/js/material-refresh.js | 172 +++---- build/js/material-refresh.min.js | 2 +- material-refresh.js | 787 +++++++++++++++---------------- material-refresh.min.js | 2 +- src/js/main.js | 177 +++---- 5 files changed, 577 insertions(+), 563 deletions(-) diff --git a/build/js/material-refresh.js b/build/js/material-refresh.js index 7ea6c9b..c32d4fd 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,24 +77,29 @@ /* 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 */ + function parseIntPx(v) { + var m = v.match('(\d+)px'); + if (m == null) return 0; + return parseInt(m[1], 10); + } + // 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; @@ -103,53 +107,57 @@ maxRotateTime = options.maxTime || maxRotateTime; refreshNav = options.nav || refreshNav; - if ($('#muirefresh').length === 0) { + if (document.querySelectorAll('#muirefresh').length === 0) { renderTmpl(); } - $refreshMain = $('#muiRefresh'); - $spinnerWrapper = $('.mui-spinner-wrapper', $refreshMain); - $arrowWrapper = $('.mui-arrow-wrapper', $refreshMain); - $arrowMain = $('.mui-arrow-main', $refreshMain); + refreshMain = document.querySelector('#muiRefresh'); + spinnerWrapper = refreshMain.querySelector('.mui-spinner-wrapper'); + arrowWrapper = refreshMain.querySelector('.mui-arrow-wrapper'); + arrowMain = refreshMain.querySelector('.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 = parseIntPx(refreshNav.style.height) + 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 = refreshNav.style.zIndex; + refreshMain.style.zIndex = 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 +179,7 @@ // Destory refresh mRefresh.destroy = function(){ unbindEvents(); - $refreshMain.remove(); + refreshMain.parentNode.removeChild(refreshMain); } @@ -190,16 +198,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); } } @@ -233,8 +241,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 +267,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 +296,7 @@ return; } e.preventDefault(); - + if (touchCurrentY > basePosY - customNavTop + NUM_POS_MIN_Y) { // Should move over the min position doRotate(); @@ -296,7 +304,7 @@ backToStart(); } } - + /** * backToStart * Return to start position @@ -304,18 +312,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 +341,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 +370,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 +395,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 +422,9 @@ } else if (typeof onEnd === 'function') { onEnd(); } - + isBtnAction = false; - + }, 500); } @@ -427,23 +435,23 @@ * @return {Boolen} */ function isDefaultType() { - return $(refreshNav).length === 0; + return !refreshNav.length || document.querySelectorAll(refreshNav).length === 0; } 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..5a021bf 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){var t=e.match("(d+)px");return null==t?0:parseInt(t[1],10)}function t(t){if(t=t||{},w=t.scrollEl?t.scrollEl:G?w:document,C=t.onBegin,X=t.onEnd,Y=t.maxTime||Y,M=t.nav||M,0===document.querySelectorAll("#muirefresh").length&&n(),p=document.querySelector("#muiRefresh"),y=p.querySelector(".mui-spinner-wrapper"),f=p.querySelector(".mui-arrow-wrapper"),v=p.querySelector(".mui-arrow-main"),!a()){p.classList.add("mui-refresh-nav"),B=e(M.style.height)+20;var i;if(i=M.getBoundingClientRect()){{var o=i.top+document.body.scrollTop;i.left+document.body.scrollLeft}I=o,"fixed"!==M.style.position&&(B+=I),p.style.top=I+"px"}var s=M.style.zIndex;p.style.zIndex=s-1}t.index&&(p.style.zIndex=~~t.index),t.top&&(p.style.top=t.top),p.classList.add(t.theme?t.theme:T),p.classList.add(x),t.freeze||d()}function n(){document.body.insertAdjacentHTML("beforeend",J)}function i(e){K.top=G&&w==document.body?window.scrollY:w!=document?document.querySelector(w).scrollTop:(document.documentElement||document.body.parentNode||document.body).scrollTop,K.top>0||b||(h=B+q,p.style.display="",e.touches[0]&&(K.x1=e.touches[0].pageX,D=K.y1=e.touches[0].pageY))}function o(e){var t,n,i=(new Date).getTime();if(!(K.top>0||b)&&e.touches&&1===e.touches.length){if(t=e.touches[0],K.x2=t.pageX,K.y2=t.pageY,n=K.y2-K.y1,K.y2-D+R>0){if(e.preventDefault(),90>i-F)return;if(!(B-I+k>h))return void u();h+=n,r(h)}K.y1=t.pageY,F=i}}function s(e){K.top>0||b||(e.preventDefault(),h>B-I+z?u():l())}function l(){var e=B+q;a()?(p.style.top=e+"px",p.style.webkitTransform="scale(0)"):p.style.top=I+"px",setTimeout(function(){b||(p.style.opacity=0,p.style.display="none")},300)}function r(e){var t=40,n=e/t>1?1:0>e/t?0:e/t,i=B+q+e;a()&&(p.style.webkitTransform="scale("+n+")"),p.style.opacity=n,p.style.top=i+"px",v.style.webkitTransform="rotate("+-(3*e)+"deg)"}function u(){if(b=!0,E&&"function"==typeof N?N():"function"==typeof C&&C(),p.style.opacity=1,E)p.classList.add(x),p.style.webkitTransform="scale(1)";else{var e=B+S-20;a()||(e+=A),p.style.top=e+"px"}f.style.display="none",y.style.display="",H=setTimeout(c,Y)}function c(){L=!0,p.classList.add(g),y.style.display="none",setTimeout(function(){p.classList.remove(g),p.style.display="none",l(),f.style.display="",b=!1,L=!1,E&&"function"==typeof j?j():"function"==typeof X&&X(),E=!1},500)}function a(){return!M.length||0===document.querySelectorAll(M).length}function d(){w.addEventListener("touchstart",i),w.addEventListener("touchmove",o),w.addEventListener("touchend",s)}function m(){w.removeEventListener("touchstart",i),w.removeEventListener("touchmove",o),w.removeEventListener("touchend",s)}var p,y,f,v,h,w=document.body,g="mui-refresh-noshow",x="mui-refresh-main-animat",T="mui-blue-theme",b=!1,L=!1,E=!1,q=-85,S=0,k=65,z=-25,A=20,D=0,I=0,R=2,Y=6e3,B=60,C=null,N=null,X=null,j=null,H=null,M="",F=(new Date).getTime(),G=/ip(hone|ad|od)/i.test(navigator.userAgent),J='
',K={top:0,x1:0,x2:0,y1:0,y2:0};t.resolve=function(){!L&&H&&(clearTimeout(H),H=null,c())},t.destroy=function(){m(),p.parentNode.removeChild(p)},t.refresh=function(e){if(!b){var t=B+S-20;b=!0,E=!0,e=e||{},N=e.onBegin,j=e.onEnd,a()||(t+=A),p.style.display="",p.classList.remove(x),p.style.top=t+"px",p.style.webkitTransform="scale(0.01)",setTimeout(u,60)}},t.unbindEvents=function(){m()},t.bindEvents=function(){d()},window.mRefresh=t}()}).call(this); \ No newline at end of file diff --git a/material-refresh.js b/material-refresh.js index ed5546c..c32d4fd 100644 --- a/material-refresh.js +++ b/material-refresh.js @@ -1,458 +1,457 @@ -/** - * 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 = '
\ -
\ -
\ -
\ -
\ -