我正在使用HTML 5空白子主题从Wordpress加载前端站点。当屏幕尺寸> 960px时,我使用粒子滑块产生徽标效果;对于屏幕尺寸小于960像素的屏幕,我有一个平面徽标图像。在Firefox和Google Chrome上都可以正常使用,但是当我在Safari上的徽标之间调整大小时,必须手动刷新页面(即通过按cmd + r),然后PS效果才会再次显示。该代码源自我在此处发布的原始问题-Original Stack Q&A

这是我现在正在使用的javascript代码-

particle-slider.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' });

        // 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;
        });
    </script>
  <div id="logo"> <img src="<?php echo home_url(); ?>/wp-content/uploads/2017/10/havoc_logo.png"> </div>

  <!-- particle-slider template -->

我需要的效果与本网站here上看到的效果相同-更改页面大小时,徽标从粒子切换为静态。粒子徽标完美地重新出现。

由于没有任何变化,所有其他相关代码都与原始问题相关联。我在控制台中看不到任何东西来提示为什么它不起作用。

最佳答案

resize事件可以触发多次,并且在该事件内,您在setTimeout中放入的任何内容都会在当前代码块执行后被调用。很难确定是否不分离ParticleSlider,但是我认为是导致全局变量(nextFrameCalledoldWidth)和回调超出预期顺序的原因。

我认为其目的是消除强制重启的反弹-您想调用ParticleSlider.nextFrame(),但是如果已经被调用,则要先等待100ms。

查看answer you've adapted这个问题似乎是canvas元素在requestAnimationFrame上不可见的一种解决方法-在100ms或多次调用ParticleSlider.nextFrame()尝试使其启动后,仍然可能不可用。

从您最初的问题和selected answer来看,我认为您需要ParticleSlider.init()来重置组件,但是您看到的闪烁是由于每次调用都需要一段时间才能运行。 ParticleSlider.nextFrame()不需要花费很长时间(并使用requestAnimationFrame避免了垃圾邮件),但不会在Safari中调整大小时创建canvas

因此,要解决:

  • 使用ParticleSlider.init()
  • 取消调整大小事件的抖动,因此无需多次触发oj​​it_rli
  • 在用户停止触发调整大小事件后短时间延迟触发一次。

  • 代码将类似于:
    var timeout = null;
    window.addEventListener('resize', function() {
        // Clear any existing debounced re-init
        clearTimeout(timeout);
    
        // Set up a re-init to fire in 1/2 a secound
        timeout = setTimeout(function() {
            ps.init();
        }, 500);
    });
    

    当组件重新初始化时,您仍然会看到闪烁和延迟,但是只有一次。

    我还要补充说ParticleSlider已被作者弃用,并替换为NextParticle-可能是为了解决这类问题(实际上,它具有处理尺寸调整的特定功能)。由于它是付费组件,因此建议您向他们寻求帮助,因为您应该物有所值(或切换到可以自行修复这些错误的开源组件)。

    10-02 17:16