JavaScript - 必须刷新页面才能显示粒子滑块徽标效果

Posted

技术标签:

【中文标题】JavaScript - 必须刷新页面才能显示粒子滑块徽标效果【英文标题】:JavaScript - page has to be refreshed to show particle-slider logo effect 【发布时间】:2018-04-06 14:25:02 【问题描述】:

我正在使用 html 5 Blank Child Theme 从 Wordpress 加载前端站点。当我的屏幕尺寸大于 960 像素时,我使用粒子滑块产生徽标效果;对于 cmd+r),然后 PS 效果再次显示。我该如何纠正这个问题,以便在重新调整大小后自动显示效果?

这是我的代码 -

粒子滑块.php

<?php /* Template Name: particle-slider */ ?>
<!-- particle-slider template -->

    <div id="particle-slider">
        <div class="slides">
            <div class="slide" data-src="<?php echo home_url(); ?>/wp-content/uploads/2017/10/havoc_logohight.png"></div>
        </div>
        <canvas class="draw" style="width: 100%; height: 100%;"></canvas>
     </div>
     <script type="text/javascript">
        var ps = new ParticleSlider( 'width':'1400', 'height': '600' );
     </script>
  <div id="logo"> <img src="<?php echo home_url(); ?>/wp-content/uploads/2017/10/havoc_logo.png"> </div>

  <!-- particle-slider template -->

style.css

/* RWD for logo */

@media screen and (max-width: 960px) 


    #particle-slider 
        display: none;
       




@media screen and (min-width: 960px) and (max-width: 1300px) 

    #particle-slider canvas 

                    width: 70%;
                    height: 30%;
                    position: relative;
                    top: 50px;
                    padding-bottom: 50px;


    


@media screen and (min-width: 960px) 

     #logo img 

        display: none;
     


ps.js

// ┌────────────────────────────────────────────────────────────────────┐ \\
// │ ParticleSlider                   |                     Version 0.9 │ \\
// ├────────────────────────────────────────────────────────────────────┤ \\
// │ Copyright © 2013 Tamino Martinius (http://zaku.eu)                 │ \\
// │ Copyright © 2013 Particleslider.com (http://particleslider.com)    │ \\
// ├────────────────────────────────────────────────────────────────────┤ \\
// │ Terms of usage: (http://particleslider.com/legal/license)            │ \\
// └────────────────────────────────────────────────────────────────────┘ \\
;
function ParticleSlider(a)var b=this;b.sliderId="particle-slider",b.color="#fff",b.hoverColor="#88f",b.width=0,b.height=20,b.ptlGap=0,b.ptlSize=1,b.slideDelay=10,b.arrowPadding=10,b.showArrowControls=!0,b.onNextSlide=null,b.onWidthChange=null,b.onHeightChange=null,b.onSizeChange=null,b.monochrome=!1,b.mouseForce=1e4,b.restless=!0,b.imgs=[];if(a)var c=["color","hoverColor","width","height","ptlGap","ptlSize","slideDelay","arrowPadding","sliderId","showArrowControls","onNextSlide","monochrome","mouseForce","restless","imgs","onSizeChange","onWidthChange","onHeightChange"];for(var d=0,e=c.length;d<e;d++)a[c[d]]&&(b[c[d]]=a[c[d]])b.$container=b.$("#"+b.sliderId),b.$$children=b.$container.childNodes,b.$controlsContainer=b.$(".controls"),b.$$slides=b.$(".slide",b.$(".slides").childNodes,!0),b.$controlLeft=null,b.$controlRight=null,b.$canv=b.$(".draw"),b.$srcCanv=document.createElement("canvas"),b.$srcCanv.style.display="none",b.$container.appendChild(b.$srcCanv),b.$prevCanv=document.createElement("canvas"),b.$prevCanv.style.display="none",b.$container.appendChild(b.$prevCanv),b.$nextCanv=document.createElement("canvas"),b.$nextCanv.style.display="none",b.$container.appendChild(b.$nextCanv),b.$overlay=document.createElement("p"),b.$container.appendChild(b.$overlay),b.imgControlPrev=null,b.imgControlNext=null,b.$$slides.length<=1&&(b.showArrowControls=!1),b.$controlsContainer&&b.$controlsContainer.childNodes&&b.showArrowControls==!0?(b.$controlLeft=b.$(".left",b.$controlsContainer.childNodes),b.$controlRight=b.$(".right",b.$controlsContainer.childNodes),b.imgControlPrev=new Image,b.imgControlNext=new Image,b.imgControlPrev.onload=function()b.$prevCanv.height=this.height,b.$prevCanv.width=this.width,b.loadingStep(),b.imgControlNext.onload=function()b.$nextCanv.height=this.height,b.$nextCanv.width=this.width,b.loadingStep(),b.imgControlPrev.src=b.$controlLeft.getAttribute("data-src"),b.imgControlNext.src=b.$controlRight.getAttribute("data-src")):b.showArrowControls=!1,b.width<=0&&(b.width=b.$container.clientWidth),b.height<=0&&(b.height=b.$container.clientHeight),b.mouseDownRegion=0,b.colorArr=b.parseColor(b.color),b.hoverColorArr=b.parseColor(b.hoverColor),b.mx=-1,b.my=-1,b.swipeOffset=0,b.cw=b.getCw(),b.ch=b.getCh(),b.frame=0,b.nextSlideTimer=!1,b.currImg=0,b.lastImg=0,b.imagesLoaded=0,b.pxlBuffer=first:null,b.recycleBuffer=first:null,b.ctx=b.$canv.getContext("2d"),b.srcCtx=b.$srcCanv.getContext("2d"),b.prevCtx=b.$prevCanv.getContext("2d"),b.nextCtx=b.$nextCanv.getContext("2d"),b.$canv.width=b.cw,b.$canv.height=b.ch,b.shuffle=function()var a,b;for(var c=0,d=this.length;c<d;c++)b=Math.floor(Math.random()*d),a=this[c],this[c]=this[b],this[b]=a,Array.prototype.shuffle=b.shuffle,b.$canv.onmouseout=function()b.mx=-1,b.my=-1,b.mouseDownRegion=0,b.$canv.onmousemove=function(a)function c(a)var c=0,d=0,e=typeof a=="string"?b.$(a):a;if(e)c=e.offsetLeft,d=e.offsetTop;var f=document.getElementsByTagName("body")[0];while(e.offsetParent&&e!=f)c+=e.offsetParent.offsetLeft,d+=e.offsetParent.offsetTop,e=e.offsetParentthis.x=c,this.y=dvar d=new c(b.$container);b.mx=a.clientX-d.x+document.body.scrollLeft+document.documentElement.scrollLeft,b.my=a.clientY-d.y+document.body.scrollTop+document.documentElement.scrollTop,b.$canv.onmousedown=function()if(b.imgs.length>1)var a=0;b.mx>=0&&b.mx<b.arrowPadding*2+b.$prevCanv.width?a=-1:b.mx>0&&b.mx>b.cw-(b.arrowPadding*2+b.$nextCanv.width)&&(a=1),b.mouseDownRegion=a,b.$canv.onmouseup=function()if(b.imgs.length>1)var a="";b.mx>=0&&b.mx<b.arrowPadding*2+b.$prevCanv.width?a=-1:b.mx>0&&b.mx>b.cw-(b.arrowPadding*2+b.$nextCanv.width)&&(a=1),a!=0&&b.mouseDownRegion!=0&&(a!=b.mouseDownRegion&&(a*=-1),b.nextSlideTimer&&clearTimeout(b.nextSlideTimer),b.nextSlide(a)),b.mouseDownRegion=0;if(b.imgs.length==0)for(var d=0,e=b.$$slides.length;d<e;d++)var f=new Image;b.imgs.push(f),f.src=b.$$slides[d].getAttribute("data-src")b.imgs.length>0&&(b.imgs[0].onload=function()b.loadingStep()),b.requestAnimationFrame(function()b.nextFrame())var psParticle=function(a)this.ps=a,this.ttl=null,this.color=a.colorArr,this.next=null,this.prev=null,this.gravityX=0,this.gravityY=0,this.x=Math.random()*a.cw,this.y=Math.random()*a.ch,this.velocityX=Math.random()*10-5,this.velocityY=Math.random()*10-5;psParticle.prototype.move=function()var a=this.ps,b=this;if(this.ttl!=null&&this.ttl--<=0)a.swapList(b,a.pxlBuffer,a.recycleBuffer),this.ttl=null;elsevar c=this.gravityX+a.swipeOffset-this.x,d=this.gravityY-this.y,e=Math.sqrt(Math.pow(c,2)+Math.pow(d,2)),f=Math.atan2(d,c),g=e*.01;a.restless==!0?g+=Math.random()*.1-.05:g<.01&&(this.x=this.gravityX+.25,this.y=this.gravityY+.25);var h=0,i=0;if(a.mx>=0&&a.mouseForce)var j=this.x-a.mx,k=this.y-a.my;h=Math.min(a.mouseForce/(Math.pow(j,2)+Math.pow(k,2)),a.mouseForce),i=Math.atan2(k,j),typeof this.color=="function"&&(i+=Math.PI,h*=.001+Math.random()*.1-.05)else h=0,i=0;this.velocityX+=g*Math.cos(f)+h*Math.cos(i),this.velocityY+=g*Math.sin(f)+h*Math.sin(i),this.velocityX*=.92,this.velocityY*=.92,this.x+=this.velocityX,this.y+=this.velocityY,ParticleSlider.prototype.Particle=psParticle,ParticleSlider.prototype.swapList=function(a,b,c)var d=this;a==null?a=new d.Particle(d):b.first==a?a.next!=null?(a.next.prev=null,b.first=a.next):b.first=null:a.next==null?a.prev.next=null:(a.prev.next=a.next,a.next.prev=a.prev),c.first==null?(c.first=a,a.prev=null,a.next=null):(a.next=c.first,c.first.prev=a,c.first=a,a.prev=null),ParticleSlider.prototype.parseColor=function(a)var b,a=a.replace(" ","");if(b=/^#([\da-fA-F]2)([\da-fA-F]2)([\da-fA-F]2)/.exec(a))b=[parseInt(b[1],16),parseInt(b[2],16),parseInt(b[3],16)];else if(b=/^#([\da-fA-F])([\da-fA-F])([\da-fA-F])/.exec(a))b=[parseInt(b[1],16)*17,parseInt(b[2],16)*17,parseInt(b[3],16)*17];else if(b=/^rgba\(([\d]+),([\d]+),([\d]+),([\d]+|[\d]*.[\d]+)\)/.exec(a))b=[+b[1],+b[2],+b[3],+b[4]];else if(b=/^rgb\(([\d]+),([\d]+),([\d]+)\)/.exec(a))b=[+b[1],+b[2],+b[3]];else return null;isNaN(b[3])&&(b[3]=1),b[3]*=255;return b,ParticleSlider.prototype.loadingStep=function()var a=this;a.imagesLoaded++;if(a.imagesLoaded>=3||a.showArrowControls==!1)a.resize(),a.slideDelay>0&&(a.nextSlideTimer=setTimeout(function()a.nextSlide(),1e3*a.slideDelay)),ParticleSlider.prototype.$=function(a,b,c)var d=this;if(a[0]==".")var e=a.substr(1);b||(b=d.$$children);var f=[];for(var g=0,h=b.length;g<h;g++)b[g].className&&b[g].className==e&&f.push(b[g]);return f.length==0?null:f.length==1&&!c?f[0]:freturn document.getElementById(a.substr(1)),ParticleSlider.prototype.nextFrame=function()var a=this;a.mouseDownRegion==1&&a.mx<a.cw/2||a.mouseDownRegion==-1&&a.mx>a.cw/2?a.swipeOffset=a.mx-a.cw/2:a.swipeOffset=0;var b=a.pxlBuffer.first,c=null;while(b!=null)c=b.next,b.move(),b=c;a.drawParticles();if(a.frame++%25==0&&(a.cw!=a.getCw()||a.ch!=a.getCh()))var d=a.getCh(),e=a.getCw();a.ch!=e&&typeof a.onWidthChange=="function"&&a.onWidthChange(a,e),a.ch!=d&&typeof a.onHeightChange=="function"&&a.onHeightChange(a,d),typeof a.onSizeChange=="function"&&a.onSizeChange(a,e,d),a.resize()setTimeout(function()a.requestAnimationFrame(function()a.nextFrame()),15),ParticleSlider.prototype.nextSlide=function(a)var b=this;b.nextSlideTimer!=null&&b.imgs.length>1?(b.currImg=(b.currImg+b.imgs.length+(a?a:1))%b.imgs.length,b.resize(),b.slideDelay>0&&(b.nextSlideTimer=setTimeout(function()b.nextSlide(),1e3*b.slideDelay))):b.slideDelay>0&&(b.nextSlideTimer=setTimeout(function()b.nextSlide(),1e3*b.slideDelay)),typeof b.onNextSlide=="function"&&b.onNextSlide(b.currImg),ParticleSlider.prototype.drawParticles=function()var a=this,b=a.ctx.createImageData(a.cw,a.ch),c=b.data,d,e,f,g,h,i,j=a.pxlBuffer.first;while(j!=null)e=~~j.x,f=~~j.y;for(g=e;g<e+a.ptlSize&&g>=0&&g<a.cw;g++)for(h=f;h<f+a.ptlSize&&h>=0&&h<a.ch;h++)d=(h*b.width+g)*4,i=typeof j.color=="function"?j.color():j.color,c[d+0]=i[0],c[d+1]=i[1],c[d+2]=i[2],c[d+3]=i[3];j=j.nextb.data=c,a.ctx.putImageData(b,0,0),ParticleSlider.prototype.getPixelFromImageData=function(a,b,c)var d=this,e=[];for(var f=0;f<a.width;f+=d.ptlGap+1)for(var g=0;g<a.height;g+=d.ptlGap+1)i=(g*a.width+f)*4,a.data[i+3]>0&&e.push(x:b+f,y:c+g,color:d.monochrome==!0?[d.colorArr[0],d.colorArr[1],d.colorArr[2],d.colorArr[3]]:[a.data[i],a.data[i+1],a.data[i+2],a.data[i+3]]);return e,ParticleSlider.prototype.init=function(a)var b=this;if(b.imgs.length>0)b.$srcCanv.width=b.imgs[b.currImg].width,b.$srcCanv.height=b.imgs[b.currImg].height,b.srcCtx.clearRect(0,0,b.$srcCanv.width,b.$srcCanv.height),b.srcCtx.drawImage(b.imgs[b.currImg],0,0);var c=b.getPixelFromImageData(b.srcCtx.getImageData(0,0,b.$srcCanv.width,b.$srcCanv.height),~~(b.cw/2-b.$srcCanv.width/2),~~(b.ch/2-b.$srcCanv.height/2));if(b.showArrowControls==!0)b.prevCtx.clearRect(0,0,b.$prevCanv.width,b.$prevCanv.height),b.prevCtx.drawImage(b.imgControlPrev,0,0);var d=b.getPixelFromImageData(b.prevCtx.getImageData(0,0,b.$prevCanv.width,b.$prevCanv.height),b.arrowPadding,~~(b.ch/2-b.$prevCanv.height/2));for(var e=0,f=d.length;e<f;e++)d[e].color=function()return b.mx>=0&&b.mx<b.arrowPadding*2+b.$prevCanv.width?b.hoverColorArr:b.colorArr,c.push(d[e]);b.nextCtx.clearRect(0,0,b.$nextCanv.width,b.$nextCanv.height),b.nextCtx.drawImage(b.imgControlNext,0,0);var g=b.getPixelFromImageData(b.nextCtx.getImageData(0,0,b.$nextCanv.width,b.$nextCanv.height),b.cw-b.arrowPadding-b.$nextCanv.width,~~(b.ch/2-b.$nextCanv.height/2));for(var e=0,f=g.length;e<f;e++)g[e].color=function()return b.mx>0&&b.mx>b.cw-(b.arrowPadding*2+b.$nextCanv.width)?b.hoverColorArr:b.colorArr,c.push(g[e])if(b.currImg!=b.lastImg||a==!0)c.shuffle(),b.lastImg=b.currImg;var h=b.pxlBuffer.first;for(var e=0,f=c.length;e<f;e++)var i=null;h!=null?(i=h,h=h.next):(b.swapList(b.recycleBuffer.first,b.recycleBuffer,b.pxlBuffer),i=b.pxlBuffer.first),i.gravityX=c[e].x,i.gravityY=c[e].y,i.color=c[e].colorwhile(h!=null)h.ttl=~~(Math.random()*10),h.gravityY=~~(b.ch*Math.random()),h.gravityX=~~(b.cw*Math.random()),h=h.next;b.$overlay.innerHTML=b.$$slides[b.currImg].innerHTML,ParticleSlider.prototype.getCw=function()var a=this;return Math.min(document.body.clientWidth,a.width,a.$container.clientWidth),ParticleSlider.prototype.getCh=function()var a=this;return Math.min(document.body.clientHeight,a.height,a.$container.clientHeight),ParticleSlider.prototype.resize=function()var a=this;a.cw=a.getCw(),a.ch=a.getCh(),a.$canv.width=a.cw,a.$canv.height=a.ch,a.init(!0),ParticleSlider.prototype.setColor=function(a)var b=this;b.colorArr=b.parseColor(a),ParticleSlider.prototype.setHoverColor=function(a)var b=this;b.hoverColorArr=b.parseColor(a),ParticleSlider.prototype.requestAnimationFrame=function(a)var b=this,c=window.requestAnimationFrame||window.webkitRequestAnimationFrame||window.mozRequestAnimationFrame||window.oRequestAnimationFrame||window.msRequestAnimationFrame||function(a)window.setTimeout(a,1e3/60);c(a)
;

【问题讨论】:

【参考方案1】:

更新(2017 年 10 月 30 日)

所以问题似乎是这样一个事实,因为您隐藏了 ParticleSlider 用于绘图的 div,它得到大小为 0x0 的 Canvas,这导致 drawParticles 方法内部某处出现异常由nextFrame 调用。另一个重要的事实是ParticleSlider 的设计方式是,在从构造函数发起第一次调用后,nextFrame 使用requestAnimationFrame 来调度自己。所有其他方法(例如nextSlideresize)只是更改数据但不重新启动动画序列。因此,第一次调用时的异常会停止动画并修复它,您需要显式调用nextFrame

所以基本思想是你修补nextFrame 以跟踪失败/成功,并在需要时从调整大小处理程序中调用它。这是一些代码:

var ps = new ParticleSlider( 'width': '1400', 'height': '600' );

// patch nextFrame to track failure/success
var nextFrameCalled = false;
ps.oldNextFrame = ps.nextFrame;
ps.nextFrame = function () 
    try 
        ps.oldNextFrame.apply(this, arguments);
        nextFrameCalled = true;
     catch (e) 
        console.log(e);
        nextFrameCalled = false;
    
;

var addEvent = function (object, type, callback) 
    if (object.addEventListener) 
        object.addEventListener(type, callback, false);
     else if (object.attachEvent) 
        object.attachEvent("on" + type, callback);
     else 
        object["on" + type] = callback;
    
;
var oldWidth = window.innerWidth;
addEvent(window, 'resize', function () 
    var newWidth = window.innerWidth;
    if (newWidth >= 960 && oldWidth < 960) 
        console.log("Restarting particle slider " + newWidth);
        ps.resize();
        if (!nextFrameCalled)
            ps.nextFrame();  // force restart animation
        else 
            // ensure that nextFrameCalled is not still true from previous cycle
            nextFrameCalled = false;
            setTimeout(function () 
                if (!nextFrameCalled)
                    ps.nextFrame();  // force restart animation
            , 100);
        
    
    oldWidth = newWidth;
);

您可以在this plunker 观看现场演示。在单独的窗口中打开演示。然后您将有 2 秒的时间将初始大小设置为大于或小于 960 像素,以便您可以模拟任何起始条件。 2 秒超时后,主代码开始。

原答案

看起来您缺少一段代码,当窗口大小更改为 >960 像素时,该代码会重新洗牌。我还没有尝试过,但我希望这样的东西可以帮助你(如果你使用 jQuery):

var ps = new ParticleSlider( 'width': '1400', 'height': '600' );

var oldWidth = $(window).width();
$(window).resize(function () 
    var newWidth = $(window).width();
    if (newWidth >= 960 && oldWidth < 960)
        ps.resize(); // this should call init() which in turn should re-shuffle particles
    oldWidth = newWidth;
);

显然,您可以编写不带 jQuery 的等效代码,例如 SO answer 中的建议

【讨论】:

抱歉,这没用。我是否必须对上面的代码进行一些更改?我对 jQuery 不太熟悉,所以不确定这段代码是否可以直接提升并放入我的文本文件中。 我查看了链接 - 毫无疑问,调整大小代码是前进的方向,但我没有第一个线索如何做到这一点,因为我根本不精通 javascript。 @Mike.Whitehead,我想我已经找到了失败的原因。查看我更新的答案和演示。 感谢您提供的详细信息和时间,非常感谢。它在 Chrome 上完美运行,在 Firefox 上几乎完美运行(平面徽标 >960px 似乎被压扁,好像它被向上推为空白画布腾出空间)但在 Safari 上仍然无法运行。 @Mike.Whitehead,当您说“在 Safari 上仍然无法运行”时,您是指我的 Plunker 演示还是您的真实站点?问题是 Safari 对图像/画布有更强的跨域策略,而且我不知道 run.plnkr.co 托管的任何图像,所以我不能把安全的 URL 放到这个演示中。我已经使用编码到 HTML 中的图像更新了演示。看看吧。【参考方案2】:

您可以在jquery smart resize 中使用ParticleSlider 的resize 功能。因此,您将对功能有更多的控制权。

var ps = new ParticleSlider( 'width': '1400', 'height': '600' );
$(window).on("debouncedresize", function( event ) 
    ps.resize();
);

【讨论】:

能否请您发布网址。它会帮助我找出答案 该网站未上线 - 它仍在本地主机上,您是否正在寻找特别的东西,我可以将其放在问题中。【参考方案3】:

问题如下:滑块使用 js 绘制到画布中,似乎脚本在页面加载时加载了一次......滑块应该是响应式的,正如作者在他们的网站上所说的那样,但实际上滑块是只是调整大小而不是在窗口调整大小时重播...

对我来说,这似乎是在打电话

ps.nextSlide(0);

在 $(window).resize() 上可能会有所帮助。这会重新加载当前幻灯片!

如果这也不起作用,请尝试使用 init() 函数或 loadingStep() 函数重新加载整个滑块! (遗憾的是,文档在某些时候对我来说不是那么清楚......)

即:

$(window).resize(function()
    ps.nextSlide(0);
);

您可以在此处查看可用的功能:

http://particleslider.com/documentation/reference

【讨论】:

如果你没有安装 Jquery,你可以像这样使用纯 JS:window.onresize = function(event) ... ;【参考方案4】:

tl;博士

替换此代码:

<script type="text/javascript">
    var ps = new ParticleSlider( 'width':'1400', 'height': '600' );
</script>

使用此代码:

<script type="text/javascript">
//wait until the DOM is ready to be queried
document.addEventListener('DOMContentLoaded', function()  //DOM-ready callback
    var ps, timeout;
    handlePS();
    window.addEventListener('resize', function() 
        if (timeout)  //check if the timer has been set
            clearTimeout(timeout); //clear the timer
        
        //set a timer
        timeout = setTimeout(handlePS, 250);
    );

    function handlePS() 
        if (document.body.clientWidth >= 960) 
            //check if ps is assigned as an instance of the ParticleSlider 
            if (window.ps && typeof ps !== null) 
                ps.init(); //refresh the particle slider since it exists
             else 
                //otherwise create a new instance of the particle slider
                ps = new ParticleSlider(
                    'width': '1400', 
                    'height': '600'
                );
            
        
        else 
            //when the flat logo is displayed, get rid of the particle slider instance
            ps = null;
        
    
);
</script>

说明:在调整大小时调用 init()

可以在resize 事件发生时添加回调(正如其他人所提到的),并根据窗口的当前宽度调用init() 方法。

建议移动创建粒子滑块实例的代码 到一个函数,该函数检查窗口的宽度是否大于或等于 960 像素(使用 document.body 的 .clientWidth),如果是,是否已使用在外部声明的变量 ps 创建了实例功能。如果实例已经创建,调用init方法;否则创建实例。但如果宽度小于 960 像素,则将变量 ps 设置为 null

var ps; //declare out here for use in multiple functions
function handlePS() 
    if (document.body.clientWidth > 960) 
        if (window.ps && typeof ps !== null) 
            ps.init();
         else 
            ps = new ParticleSlider('width': '1400', 'height': '600');
        
    
    else 
            ps = null;
    

然后可以在页面加载以及调整大小事件发生时调用该函数:

handlePS();
window.addEventListener('resize', handlePS);

在this sample page 中查看演示。还添加了一些其他增强功能:

它通过调用handlePS() 等待DOM 准备就绪,并在使用document.addEventListener 触发DOMContentLoaded 事件后侦听resize 事件 它将 setTimeout 用于 debounce effect,以便在滚动事件结束后 250 毫秒调用 init() 方法,而不是在滚动事件期间连续调用。

因此具有这些增强功能的代码如下所示:

//wait until the DOM is ready to be queried
document.addEventListener('DOMContentLoaded', function()  //DOM-ready callback
    var ps, timeout;
    handlePS();
    window.addEventListener('resize', function() 
        //https://davidwalsh.name/javascript-debounce-function
        if (timeout)  //check if the timer has been set
                clearTimeout(timeout); //clear the timer
        
        //set a timer
        timeout = setTimeout(handlePS, 250);
    );

    function handlePS() 
        if (document.body.clientWidth >= 960) 
            //check if ps is assigned as an instance of the ParticleSlider 
            if (window.ps && typeof ps !== null) 
                ps.init(); //refresh the particle slider since it exists
             else 
                //otherwise create a new instance of the particle slider
                ps = new ParticleSlider(
                    'width': '1400', 
                    'height': '600'
                );
            
        
        else 
            //when the flat logo is displayed, get rid of the particle slider instance
            ps = null;
        
    
);

因为你添加了jquery 标签,jQuery 可以用来简化一些事情:

而不是

window.addEventListener('resize', handlePS);

使用:

$(window).on('resize, handlePS);

并替换document.body.clientWidth 宽度$(document).width()

更新

我使用了您在updated sample page 中的评论中的the image。我还减少了the Particle Slider 演示页面上使用的代码,并在this demo page 上添加了该图像。调整大小时,它仍然会闪烁。

【讨论】:

当我实现你的代码时,实际的ps效果不是很好。当我开始重新调整页面大小时,徽标效果开始像电灯开关一样闪烁。我注意到示例页面上的徽标看起来很大。 好吧,我为平面徽标重复使用了相同的徽标图像,但我将其更新为具有更小的尺寸;您在哪个浏览器中看到闪烁? 这一切都发生在他们身上。 我想知道 PS 是否对较大的图像有问题...我尝试减少网站上的示例并使用在您的其他问题之一中找到的徽标图像 - 它仍然存在问题,即使压缩 PNG(从 285 KB 到 75 KB)并转换为 GIF(82 KB)后...samonela.scienceontheweb.net/javascript/ps.html 我可以将 ps 文件中使用的图像发送给您 - 有帮助吗?我现在不在,但我可以在几个小时内把它寄过来。【参考方案5】:

您的用例有两个主要问题:

在目标可见之前初始化粒子时,图像的大小无效 (0x0) 一旦动画开始运行并且您将分辨率调小,动画就会继续在后台运行

我尝试在以下脚本中处理这两个问题。

var ps = null

function init()
  var isVisible = window.innerWidth >= 960;
  if (!ps && isVisible) 
    // create and init
    ps = new ParticleSlider(
      ptlGap: 1,
      ptlSize: 1,
      width: 1e9,
      height: 100,
    );

    ps.init(false);
   else if (ps && !isVisible) 
    // stop and remove
    ps.requestAnimationFrame = function() ; // Stop render loop
    ps = null;
  


window.addEventListener('load', init, false)
window.onload = init;
window.addEventListener('resize', init, false);
window.onresize = init;
html, body 
  background-color: black;
  width: 100%;
  height: 100%;
  margin: 0;
  padding: 0;
  color: #fff;
  text-align: center;


.slides, & > .dg 
  display: none;


.low-res 
  display: none;


@media screen and (max-width: 959px) 
  .draw 
    display: none;
  

  .low-res 
    display: inline;
    width: 50%;
  
<html>
  <head>
    <meta name="viewport" content="width=device-width" />
    <title>ParticleSlider</title>
    <script src="https://s3-us-west-2.amazonaws.com/s.cdpn.io/23500/ps-0.9.js"></script>
  </head>
  <body id="particle-slider">
    <div class="slides">
      <div id="first-slide" class="slide" data-src="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAGkAAAAgCAMAAAAmC6asAAAAMFBMVEX19vf19vft7u/19vfp6uv19vfx8vP19vf19vf19vf19vfm5+j19vcAAAD19vfl5udu+MchAAAADnRSTlOIVcIz10StZneZEewiAMEzGswAAAF/SURBVHja7ZXZbsQwCEXjneXa/P/fFntm0uRpVGkaqVX8YAW4cMCxkq1ftW7STbpJP1sJb0lFPkJiekuq4TMkfkti+gxpe0uivRmB9LQOlHraNixnYErPONAfcYZntYfv9aDtJTmUO5OCeukGR5paqZtbGaSVzYWIlZ9DI6vVpC6shJw5TzdlZk47qZpldAkteBVToxNJrLGqoil6MPE9A1bSNorUXPYWvbLUjbg37lwRNPYW6x6eJK4ilB2hVmChJw2nWx4He3Map1exMVFvQyMVN78rlexbY7Gk0tWUm7gsHUnikQ6dwzLRLM/tRKIlGMMFoijmpthqBocLFTLWO41GnhrFXZIGTiTz5pIyA9G4uqSeSV3W4bSsqvycg0x9RTpcKHaHHybNOZBXfPa41jNjLCeqjRopzgI4kXYcsDqVZWJaZwVWHpYBTOuoACCvEpjTC3DFd6/oVV9YmPw+CWsb+H1SxVWkkgkoV5B6ijasXnMjBPIf/u436e+TvgDCaqPX6lO5yQAAAABJRU5ErkJggg==">
      </div>
    </div>
    <canvas class="draw"></canvas>
    <img src="https://s3-us-west-2.amazonaws.com/s.cdpn.io/23500/codepen-white.png" class="low-res"/>
  </body>
</html>

【讨论】:

这很好用,看起来很棒,但我认为 ps.requestAnimationFrame 函数可能会阻止画布在 Safari 中调整大小?

以上是关于JavaScript - 必须刷新页面才能显示粒子滑块徽标效果的主要内容,如果未能解决你的问题,请参考以下文章

Jquery Mobile 谷歌地图,我必须刷新页面才能显示地图

iframe怎么样才能不用手动刷新,就可以显示新的页面?急...

从页面中删除行而不刷新页面

Ajax Javascript 在不刷新页面的情况下不会改变样式

在刷新带frame的整个页面时,如何才能使frame刷新当时显示的页面内容

下一个 JS apollo 链接更改清除查询,必须刷新页面才能运行查询