【问题标题】:switch stylesheet flicker切换样式表闪烁
【发布时间】:2012-04-14 15:29:04
【问题描述】:

我有一个包含 2 个样式表的站点,一个用于白天阅读,一个用于夜间阅读。我有一个带有onclick 事件的图像来调用一个函数来更改样式表。问题是,对于新访问者来说,当他们第一次点击按钮时,页面会在半秒钟内完全没有样式(即没有样式表),然后新的页面就会启动。我知道发生这种情况的原因是我删除了当前工作表的rel="stylesheet",然后将其添加到新工作表。有什么办法可以改进功能,即使对于新访客也不会出现短暂的延迟?谢谢。

function changeStyleSheet() {
    var a = document.getElementById('stylesheet1');
    var b = document.getElementById('stylesheet2');
    var now1 = $(a).attr('rel');
    var now2 = $(b).attr('rel');
    if (now1 == 'stylesheet') {
        a.setAttribute('rel', 'alt-stylesheet');
        b.setAttribute('rel', 'stylesheet');
    } else {
        b.setAttribute('rel', 'alt-stylesheet');
        a.setAttribute('rel', 'stylesheet');
    }
};

【问题讨论】:

    标签: javascript html css


    【解决方案1】:

    您是否尝试过切换设置属性的顺序?就像先设置要切换到的样式表的 rel 属性,然后再设置要切换的样式表的 rel 属性?

    在 HTML 中将两个 rel 属性设置为样式表,并在页面加载时使用 javascript 将其中一个更改为备用样式表。

    【讨论】:

    • 不,我没有……让我试试。我最初没有,因为我认为我不能同时将 rel="stylesheet" 设置为两个元素。
    • 没有什么不同。 似乎浏览器正在花很短的时间来加载第二个样式表或类似的东西。因为当我换过床单后它就不再闪烁了。
    • 那么如何预加载样式表。将两个 rel 属性设置为 html 中的样式表,当页面加载时,javascript 将其中一个切换为备用样式表。
    • 最后一个建议似乎奏效了……尽管 Opera 仍然以自己愚蠢的方式行事。提出另一个答案,以便我可以检查它是否正确(当前答案不正确)。
    • 我已经编辑了答案,包括在 HTML 中设置 rel 属性,然后在加载后使用 javascript 更改它。
    【解决方案2】:

    为什么不做一个类似的东西:

    JavaScript

    function changeStyle() {
        document.getElementById('stylesheet').href = 'style2.css';
    }
    

    HTML

    <input type="button" onclick="changeStyle();"/>
    <link rel="stylesheet" href="style1.css" id="stylesheet">
    

    或尝试使用this 获取多个样式表

    切换试试这个:

    function changeStyle() {
        var a = document.getElementById('stylesheet').href;
        if (a === 'style1.css') {
            document.getElementById('stylesheet').href = 'style2.css';
        } else {
            document.getElementById('stylesheet').href = 'style1.css';        
        }
    }​
    

    【讨论】:

    • 这看起来更容易。但是你如何将它切换回来,就像在切换中一样?
    • 把它包在一个 if 函数中,给我一秒钟
    • 好的,试过了。它不工作。我还需要调用 head 标签中的两张纸吗?如果是这样,我是否将relid 放在它们上面。如果我有两个具有相同 ID(错误)并且函数正在寻找一个,我可能会看到问题。
    • 问题在于,对于多个元素,它依赖于链接中单独定义的JavaScript:changeSheets(#) 部分。我有一个按钮必须同时完成。
    【解决方案3】:

    如果您不需要维护两个单独的样式表,那么只需将id 应用于body 内的父元素可能会更容易实现您的目标。在我的演示中,为了简单起见,我使用了body 元素,但如果这不可能,您可以简单地将您的网站内容包装在div 中,然后添加id。然后,只需在 CSS 选择器前面加上相关的 id 即可应用相关样式。

    在我的演示中,我使用了以下 JavaScript:

    var sel = document.getElementById('styles'),
        b = document.getElementsByTagName('body')[0];
    sel.onchange = function() {
        b.id = this.value;
    };​
    

    还有 CSS:

    #styles1 h1 {
        margin-top: 1em;
        color: #f00;
        background-color: #000;
        text-align: center;
        font-size: 2em;
    }
    
    #styles1 div {
        width: 80%;
    }
    
    #styles2 h1 {
        margin-top: 1em;
        color: #000;
        background-color: #fff;
        text-align: right;
        font-size: 1.5em;
        font-style: italic;
    }
    
    #styles2 div {
        width: 50%;
        margin: 0 auto 1em auto;
    }
    
    /* the following is for the element holding the style-switcher select */
    #styles1 #themes,
    #styles2 #themes {
        width: auto;
        position: absolute;
        top: 0;
        left: 0;
        background-color: #fff;
    }​
    

    JS Fiddle demo.

    使用上述方法,您应该不会在样式更改时注意到任何闪烁,因为样式表已经加载。如果您的页面特别复杂,可能会出现可见的闪烁,但它应该比切换到新样式表时的闪烁要短得多。

    【讨论】:

      【解决方案4】:

      除非您的两个样式表具有非常相似的结构,否则您最终会得到一个奇怪的闪烁/渲染:

      更改顺序(您希望):

      • 工作表 1 - 已应用
      • 工作表 2 - 已应用
      • 第 1 页 - 已删除

      这意味着在短时间内,您将同时应用两个样式表(如果它们都只是设置调色板并且都在相同的元素上,这不是问题,但如果更冗长/重要则将是一个问题)。

      如果这是一个问题,您可能会考虑做一些事情来让样式表更改看起来很棒 - 例如在样式更改之前淡出页面/元素,更改样式,然后再淡入。

      如果不是问题,你应该可以使用jacktheripper提供的方法

      【讨论】:

        猜你喜欢
        • 2013-02-12
        • 2016-06-10
        • 2017-07-03
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2019-03-28
        • 2011-01-06
        • 2020-03-06
        相关资源
        最近更新 更多