butterfly两种平滑滚动实现教程

butterfly两种平滑滚动实现教程

目前该JS对谷歌浏览器有BUG,正在紧急修复中

方法:

复制smooth-scrolling.js到ROOT\themes\butterfly\source\js

smooth-scrolling.js

(function(){var defaultOptions={frameRate:150,animationTime:400,stepSize:100,pulseAlgorithm:true,pulseScale:4,pulseNormalize:1,accelerationDelta:50,accelerationMax:3,keyboardSupport:true,arrowScroll:50,fixedBackground:true,excluded:''};var options=defaultOptions;var isExcluded=false;var isFrame=false;var direction={x:0,y:0};var initDone=false;var root=document.documentElement;var activeElement;var observer;var refreshSize;var deltaBuffer=[];var deltaBufferTimer;var isMac=/^Mac/.test(navigator.platform);var key={left:37,up:38,right:39,down:40,spacebar:32,pageup:33,pagedown:34,end:35,home:36};var arrowKeys={37:1,38:1,39:1,40:1};function initTest(){if(options.keyboardSupport){addEvent('keydown',keydown);}}
function init(){if(initDone||!document.body)return;initDone=true;var body=document.body;var html=document.documentElement;var windowHeight=window.innerHeight;var scrollHeight=body.scrollHeight;root=(document.compatMode.indexOf('CSS')>=0)?html:body;activeElement=body;initTest();if(top!=self){isFrame=true;}
else if(isOldSafari&&scrollHeight>windowHeight&&(body.offsetHeight<=windowHeight||html.offsetHeight<=windowHeight)){var fullPageElem=document.createElement('div');fullPageElem.style.cssText='position:absolute; z-index:-10000; '+
'top:0; left:0; right:0; height:'+
root.scrollHeight+'px';document.body.appendChild(fullPageElem);var pendingRefresh;refreshSize=function(){if(pendingRefresh)return;pendingRefresh=setTimeout(function(){if(isExcluded)return;fullPageElem.style.height='0';fullPageElem.style.height=root.scrollHeight+'px';pendingRefresh=null;},500);};setTimeout(refreshSize,10);addEvent('resize',refreshSize);var config={attributes:true,childList:true,characterData:false};observer=new MutationObserver(refreshSize);observer.observe(body,config);if(root.offsetHeight<=windowHeight){var clearfix=document.createElement('div');clearfix.style.clear='both';body.appendChild(clearfix);}}
if(!options.fixedBackground&&!isExcluded){body.style.backgroundAttachment='scroll';html.style.backgroundAttachment='scroll';}}
function cleanup(){observer&&observer.disconnect();removeEvent(wheelEvent,wheel);removeEvent('mousedown',mousedown);removeEvent('keydown',keydown);removeEvent('resize',refreshSize);removeEvent('load',init);}
var que=[];var pending=false;var lastScroll=Date.now();function scrollArray(elem,left,top){directionCheck(left,top);if(options.accelerationMax!=1){var now=Date.now();var elapsed=now-lastScroll;if(elapsed<options.accelerationDelta){var factor=(1+(50/elapsed))/2;if(factor>1){factor=Math.min(factor,options.accelerationMax);left*=factor;top*=factor;}}
lastScroll=Date.now();}
que.push({x:left,y:top,lastX:(left<0)?0.99:-0.99,lastY:(top<0)?0.99:-0.99,start:Date.now()});if(pending){return;}
var scrollRoot=getScrollRoot();var isWindowScroll=(elem===scrollRoot||elem===document.body);if(elem.$scrollBehavior==null&&isScrollBehaviorSmooth(elem)){elem.$scrollBehavior=elem.style.scrollBehavior;elem.style.scrollBehavior='auto';}
var step=function(time){var now=Date.now();var scrollX=0;var scrollY=0;for(var i=0;i<que.length;i++){var item=que[i];var elapsed=now-item.start;var finished=(elapsed>=options.animationTime);var position=(finished)?1:elapsed/options.animationTime;if(options.pulseAlgorithm){position=pulse(position);}
var x=(item.x*position-item.lastX)>>0;var y=(item.y*position-item.lastY)>>0;scrollX+=x;scrollY+=y;item.lastX+=x;item.lastY+=y;if(finished){que.splice(i,1);i--;}}
if(isWindowScroll){window.scrollBy(scrollX,scrollY);}
else{if(scrollX)elem.scrollLeft+=scrollX;if(scrollY)elem.scrollTop+=scrollY;}
if(!left&&!top){que=[];}
if(que.length){requestFrame(step,elem,(1000/options.frameRate+1));}else{pending=false;if(elem.$scrollBehavior!=null){elem.style.scrollBehavior=elem.$scrollBehavior;elem.$scrollBehavior=null;}}};requestFrame(step,elem,0);pending=true;}
function wheel(event){if(!initDone){init();}
var target=event.target;if(event.defaultPrevented||event.ctrlKey){return true;}
if(isNodeName(activeElement,'embed')||(isNodeName(target,'embed')&&/\.pdf/i.test(target.src))||isNodeName(activeElement,'object')||target.shadowRoot){return true;}
var deltaX=-event.wheelDeltaX||event.deltaX||0;var deltaY=-event.wheelDeltaY||event.deltaY||0;if(isMac){if(event.wheelDeltaX&&isDivisible(event.wheelDeltaX,120)){deltaX=-120*(event.wheelDeltaX/Math.abs(event.wheelDeltaX));}
if(event.wheelDeltaY&&isDivisible(event.wheelDeltaY,120)){deltaY=-120*(event.wheelDeltaY/Math.abs(event.wheelDeltaY));}}
if(!deltaX&&!deltaY){deltaY=-event.wheelDelta||0;}
if(event.deltaMode===1){deltaX*=40;deltaY*=40;}
var overflowing=overflowingAncestor(target);if(!overflowing){if(isFrame&&isChrome){Object.defineProperty(event,"target",{value:window.frameElement});return parent.wheel(event);}
return true;}
if(isTouchpad(deltaY)){return true;}
if(Math.abs(deltaX)>1.2){deltaX*=options.stepSize/120;}
if(Math.abs(deltaY)>1.2){deltaY*=options.stepSize/120;}
scrollArray(overflowing,deltaX,deltaY);event.preventDefault();scheduleClearCache();}
function keydown(event){var target=event.target;var modifier=event.ctrlKey||event.altKey||event.metaKey||(event.shiftKey&&event.keyCode!==key.spacebar);if(!document.body.contains(activeElement)){activeElement=document.activeElement;}
var inputNodeNames=/^(textarea|select|embed|object)$/i;var buttonTypes=/^(button|submit|radio|checkbox|file|color|image)$/i;if(event.defaultPrevented||inputNodeNames.test(target.nodeName)||isNodeName(target,'input')&&!buttonTypes.test(target.type)||isNodeName(activeElement,'video')||isInsideYoutubeVideo(event)||target.isContentEditable||modifier){return true;}
if((isNodeName(target,'button')||isNodeName(target,'input')&&buttonTypes.test(target.type))&&event.keyCode===key.spacebar){return true;}
if(isNodeName(target,'input')&&target.type=='radio'&&arrowKeys[event.keyCode]){return true;}
var shift,x=0,y=0;var overflowing=overflowingAncestor(activeElement);if(!overflowing){return(isFrame&&isChrome)?parent.keydown(event):true;}
var clientHeight=overflowing.clientHeight;if(overflowing==document.body){clientHeight=window.innerHeight;}
switch(event.keyCode){case key.up:y=-options.arrowScroll;break;case key.down:y=options.arrowScroll;break;case key.spacebar:shift=event.shiftKey?1:-1;y=-shift*clientHeight*0.9;break;case key.pageup:y=-clientHeight*0.9;break;case key.pagedown:y=clientHeight*0.9;break;case key.home:if(overflowing==document.body&&document.scrollingElement)
overflowing=document.scrollingElement;y=-overflowing.scrollTop;break;case key.end:var scroll=overflowing.scrollHeight-overflowing.scrollTop;var scrollRemaining=scroll-clientHeight;y=(scrollRemaining>0)?scrollRemaining+10:0;break;case key.left:x=-options.arrowScroll;break;case key.right:x=options.arrowScroll;break;default:return true;}
scrollArray(overflowing,x,y);event.preventDefault();scheduleClearCache();}
function mousedown(event){activeElement=event.target;}
var uniqueID=(function(){var i=0;return function(el){return el.uniqueID||(el.uniqueID=i++);};})();var cacheX={};var cacheY={};var clearCacheTimer;var smoothBehaviorForElement={};function scheduleClearCache(){clearTimeout(clearCacheTimer);clearCacheTimer=setInterval(function(){cacheX=cacheY=smoothBehaviorForElement={};},1*1000);}
function setCache(elems,overflowing,x){var cache=x?cacheX:cacheY;for(var i=elems.length;i--;)
cache[uniqueID(elems[i])]=overflowing;return overflowing;}
function getCache(el,x){return(x?cacheX:cacheY)[uniqueID(el)];}
function overflowingAncestor(el){var elems=[];var body=document.body;var rootScrollHeight=root.scrollHeight;do{var cached=getCache(el,false);if(cached){return setCache(elems,cached);}
elems.push(el);if(rootScrollHeight===el.scrollHeight){var topOverflowsNotHidden=overflowNotHidden(root)&&overflowNotHidden(body);var isOverflowCSS=topOverflowsNotHidden||overflowAutoOrScroll(root);if(isFrame&&isContentOverflowing(root)||!isFrame&&isOverflowCSS){return setCache(elems,getScrollRoot());}}else if(isContentOverflowing(el)&&overflowAutoOrScroll(el)){return setCache(elems,el);}}while((el=el.parentElement));}
function isContentOverflowing(el){return(el.clientHeight+10<el.scrollHeight);}
function overflowNotHidden(el){var overflow=getComputedStyle(el,'').getPropertyValue('overflow-y');return(overflow!=='hidden');}
function overflowAutoOrScroll(el){var overflow=getComputedStyle(el,'').getPropertyValue('overflow-y');return(overflow==='scroll'||overflow==='auto');}
function isScrollBehaviorSmooth(el){var id=uniqueID(el);if(smoothBehaviorForElement[id]==null){var scrollBehavior=getComputedStyle(el,'')['scroll-behavior'];smoothBehaviorForElement[id]=('smooth'==scrollBehavior);}
return smoothBehaviorForElement[id];}
function addEvent(type,fn,arg){window.addEventListener(type,fn,arg||false);}
function removeEvent(type,fn,arg){window.removeEventListener(type,fn,arg||false);}
function isNodeName(el,tag){return el&&(el.nodeName||'').toLowerCase()===tag.toLowerCase();}
function directionCheck(x,y){x=(x>0)?1:-1;y=(y>0)?1:-1;if(direction.x!==x||direction.y!==y){direction.x=x;direction.y=y;que=[];lastScroll=0;}}
if(window.localStorage&&localStorage.SS_deltaBuffer){try{deltaBuffer=localStorage.SS_deltaBuffer.split(',');}catch(e){}}
function isTouchpad(deltaY){if(!deltaY)return;if(!deltaBuffer.length){deltaBuffer=[deltaY,deltaY,deltaY];}
deltaY=Math.abs(deltaY);deltaBuffer.push(deltaY);deltaBuffer.shift();clearTimeout(deltaBufferTimer);deltaBufferTimer=setTimeout(function(){try{localStorage.SS_deltaBuffer=deltaBuffer.join(',');}catch(e){}},1000);var dpiScaledWheelDelta=deltaY>120&&allDeltasDivisableBy(deltaY);return!allDeltasDivisableBy(120)&&!allDeltasDivisableBy(100)&&!dpiScaledWheelDelta;}
function isDivisible(n,divisor){return(Math.floor(n/divisor)==n/divisor);}
function allDeltasDivisableBy(divisor){return(isDivisible(deltaBuffer[0],divisor)&&isDivisible(deltaBuffer[1],divisor)&&isDivisible(deltaBuffer[2],divisor));}
function isInsideYoutubeVideo(event){var elem=event.target;var isControl=false;if(document.URL.indexOf('www.youtube.com/watch')!=-1){do{isControl=(elem.classList&&elem.classList.contains('html5-video-controls'));if(isControl)break;}while((elem=elem.parentNode));}
return isControl;}
var requestFrame=(function(){return(window.requestAnimationFrame||window.webkitRequestAnimationFrame||window.mozRequestAnimationFrame||function(callback,element,delay){window.setTimeout(callback,delay||(1000/60));});})();var MutationObserver=(window.MutationObserver||window.WebKitMutationObserver||window.MozMutationObserver);var getScrollRoot=(function(){var SCROLL_ROOT=document.scrollingElement;return function(){if(!SCROLL_ROOT){var dummy=document.createElement('div');dummy.style.cssText='height:10000px;width:1px;';document.body.appendChild(dummy);var bodyScrollTop=document.body.scrollTop;var docElScrollTop=document.documentElement.scrollTop;window.scrollBy(0,3);if(document.body.scrollTop!=bodyScrollTop)
(SCROLL_ROOT=document.body);else
(SCROLL_ROOT=document.documentElement);window.scrollBy(0,-3);document.body.removeChild(dummy);}
return SCROLL_ROOT;};})();function pulse_(x){var val,start,expx;x=x*options.pulseScale;if(x<1){val=x-(1-Math.exp(-x));}else{start=Math.exp(-1);x-=1;expx=1-Math.exp(-x);val=start+(expx*(1-start));}
return val*options.pulseNormalize;}
function pulse(x){if(x>=1)return 1;if(x<=0)return 0;if(options.pulseNormalize==1){options.pulseNormalize/=pulse_(1);}
return pulse_(x);}
var userAgent=window.navigator.userAgent;var isEdge=/Edge/.test(userAgent);var isChrome=/chrome/i.test(userAgent)&&!isEdge;var isSafari=/safari/i.test(userAgent)&&!isEdge;var isMobile=/mobile/i.test(userAgent);var isIEWin7=/Windows NT 6.1/i.test(userAgent)&&/rv:11/i.test(userAgent);var isOldSafari=isSafari&&(/Version\/8/i.test(userAgent)||/Version\/9/i.test(userAgent));var isEnabledForBrowser=(isChrome||isSafari||isIEWin7)&&!isMobile;var supportsPassive=false;try{window.addEventListener("test",null,Object.defineProperty({},'passive',{get:function(){supportsPassive=true;}}));}catch(e){}
var wheelOpt=supportsPassive?{passive:false}:false;var wheelEvent='onwheel'in document.createElement('div')?'wheel':'mousewheel';if(wheelEvent&&isEnabledForBrowser){addEvent(wheelEvent,wheel,wheelOpt);addEvent('mousedown',mousedown);addEvent('load',init);}
function SmoothScroll(optionsToSet){for(var key in optionsToSet)
if(defaultOptions.hasOwnProperty(key))
options[key]=optionsToSet[key];}
SmoothScroll.destroy=cleanup;if(window.SmoothScrollOptions)
SmoothScroll(window.SmoothScrollOptions);if(typeof define==='function'&&define.amd)
define(function(){return SmoothScroll;});else if('object'==typeof exports)
module.exports=SmoothScroll;else
window.SmoothScroll=SmoothScroll;})();

简单模式

inject:
  head:
  bottom:
    - <script src="/js/smooth-scrolling.js"></script>

然后常规三连即可

插件开关模式

打开ROOT\themes\butterfly\layout\includes\third-party\effect.pug添加如下代码

if theme.smooth_scrolling.enable
  script(src=url_for(theme.CDN.smooth_scrolling))

在主题配置文件添加下列参数:

开关:

smooth_scrolling:
  enable: true

CDN:

CDN:
  #平滑滚动
  smooth_scrolling: https://cdn.nesxc.com/js/smooth-scrolling.js

然后常规三连即可

© 版权声明
THE END
点赞14赞赏 分享
评论 抢沙发
头像
欢迎您留下宝贵的见解!
提交
头像

昵称

取消
昵称表情代码图片

    暂无评论内容