粒子滑块徽标不会在Safari中调整大小

时间:2017-12-05 14:07:02

标签: javascript wordpress safari cross-browser

我正在使用HTML 5 Blank Child Theme从Wordpress加载前端站点。我有一个使用粒子滑块的徽标效果,当我的屏幕尺寸大于&gt; 960px时;对于屏幕尺寸<960px我有一个平面徽标图像。这一切都适用于Firefox和谷歌浏览器,但当我在Safari上的徽标之间重新调整大小时,必须手动刷新页面(即通过按 cmd + r ) PS效果再次显示。该代码源自我在此处发布的原始问题 - Original Stack Q&A

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

颗粒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上看到的效果相同的效果 - 当页面重新调整大小时,徽标会从粒子切换到静态。粒子徽标重新出现完美。

所有其他相关代码都与原始问题相关联,因为没有任何更改。我没有在控制台中看到任何东西来说明它为什么不起作用。

2 个答案:

答案 0 :(得分:2)

resize事件可以多次触发,在该事件中,您在setTimeout中放入的任何内容都将在当前代码块执行后被调用。如果没有分开ParticleSlider,很难肯定地说,但我认为全局变量(nextFrameCalledoldWidth)的混合以及触发预期订单的回调是原因。

我认为目的是去抖强制重启 - 你想要调用ParticleSlider.nextFrame()但是如果它已被调用你想要先等待100ms。

查看此问题的answer you've adapted似乎是canvas元素无法在requestAnimationFrame上显示的解决方法 - 可能在100分钟后或{ {1}}已被多次调用以试图触发它。

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

所以,修复:

  1. 使用canvas
  2. 去抖调整大小事件,这样你就不会多次触发
  3. 在用户停止触发调整大小事件后立即触发一次。
  4. 代码将类似于:

    ParticleSlider.init()

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

    我要补充一点,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 - 可能是为了解决这些问题(事实上它具有处理大小调整的特定功能)。由于它是一个付费的组件,我建议请他们帮忙,因为你应该得到你的钱(或切换到一个开源组件,你可以自己修复这些错误)。

答案 1 :(得分:1)

所以,我终于通过使用之前的Q&amp; A回溯我的步骤来解决这个问题。以前一些示例链接似乎存在问题,但现在似乎有一个 - example

我进入了页面检查器并注意到触发此示例的代码与实际答案中的代码之间存在一些差异,导致徽标像灯泡一样闪烁。这是我现在放入wordpress网站的代码 -

<script type="text/javascript">
        //wait until the DOM is ready to be queried
        (function() {//document.addEventListener('DOMContentLoaded', function() { //DOM-ready callback
            var ps, timeout;
            var img1 = new Image();
            img1.src = '<?php echo home_url(); ?>/wp-content/uploads/2017/10/havoc_logohight.png';//havoc_logo_e6os2n.png';
            var imgs = [ img1 ];
            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 (ps != undefined && typeof ps !== null) {
                        ps.init(); //refresh the particle slider since it exists
                        console.log('called init on ps');
                    } else {
                            if (window.location.search.indexOf('d=1') > -1) {
                                    debugger;
                            }
                        //otherwise create a new instance of the particle slider
                        ps = new ParticleSlider({
                            width: 1400, 
                            height: 600,
                            imgs: imgs
                        });
                    }
                }
                else {
                    //when the flat logo is displayed, get rid of the particle slider instance
                 //   delete ps;
                    ps = null;
                }
            }
        })();
    </script>

它现在可以在所有主流浏览器中正常运行 - Chrome / Safari / Firefox。它仍然感觉有点笨拙,因为它在重新调整大小时将页面的其余部分向下推,并且它比我想要的时间多了几秒钟 - 不确定是否有一个计时器选项来加速恢复?否则,一切正常。