【问题标题】:Is there an easy way to reload css without reloading the page?有没有一种简单的方法可以在不重新加载页面的情况下重新加载 css?
【发布时间】:2011-01-02 17:28:06
【问题描述】:

我正在尝试制作一个具有预览功能的实时页面内 css 编辑器,该功能可以重新加载样式表并应用它,而无需重新加载页面。解决此问题的最佳方法是什么?

【问题讨论】:

  • 2014 这个问题在主页上...
  • 2019,快2020了,这个问题还在首页上蹦出来……

标签: javascript css stylesheet reload


【解决方案1】:

可能不适用于您的情况,但这是我用于重新加载外部样式表的 jQuery 函数:

/**
 * Forces a reload of all stylesheets by appending a unique query string
 * to each stylesheet URL.
 */
function reloadStylesheets() {
    var queryString = '?reload=' + new Date().getTime();
    $('link[rel="stylesheet"]').each(function () {
        this.href = this.href.replace(/\?.*|$/, queryString);
    });
}

【讨论】:

  • 您可以使用ted.mielczarek.org/code/mozilla/bookmarklet.html将其设为书签
  • 这个非 jquery 单行在 chrome 中为我工作:var links = document.getElementsByTagName("link"); for (var i = 0; i < links.length;i++) { var link = links[i]; if (link.rel === "stylesheet") {link.href += "?"; }}
  • 我不确定是不是因为我只是从磁盘打开 chrome 上的页面,但这对我不起作用。
【解决方案2】:

在“编辑”页面上,不要以正常方式包含您的 CSS(使用 <link> 标签),而是将其全部写入 <style> 标签。编辑其innerHTML 属性将自动更新页面,即使没有往返服务器。

<style type="text/css" id="styles">
    p {
        color: #f0f;
    }
</style>

<textarea id="editor"></textarea>
<button id="preview">Preview</button>

Javascript,使用 jQuery:

jQuery(function($) {
    var $ed = $('#editor')
      , $style = $('#styles')
      , $button = $('#preview')
    ;
    $ed.val($style.html());
    $button.click(function() {
        $style.html($ed.val());
        return false;
    });
});

应该就是这样!

如果你想要真正花哨,请将函数附加到 textarea 上的 keydown,尽管你可能会得到一些不需要的副作用(页面会随着你的输入不断变化)

编辑:经过测试并且可以工作(至少在 Firefox 3.5 中,但在其他浏览器上应该没问题)。在此处查看演示:http://jsbin.com/owapi

【讨论】:

  • IE barfs on innerHTML for &lt;style&gt; 元素(和 &lt;script&gt;)。
  • 如果是href'ed怎么办?
  • 顺便说一句,您可以将功能附加到 textarea 上的 keydown 但throttle it with lo-dash(例如)。
【解决方案3】:

绝对没有必要为此使用 jQuery。以下 JavaScript 函数将重新加载您的所有 CSS 文件:

function reloadCss()
{
    var links = document.getElementsByTagName("link");
    for (var cl in links)
    {
        var link = links[cl];
        if (link.rel === "stylesheet")
            link.href += "";
    }
}

【讨论】:

  • 我在控制台中使用它,所以我不需要在我的代码中添加任何其他内容
  • @Bram 花括号是可选的。代码运行良好。
  • 很好的答案,因为它不依赖 jQuery! :)
  • 只是想知道 === 的用途 - rel 属性值何时可以是“样式表”但其类型不是字符串?
【解决方案4】:

查看 Andrew Davey 的时髦 Vogue 项目 - http://aboutcode.net/vogue/

【讨论】:

  • 这正是我一直在寻找的。它会在样式表更改后立即重新加载 CSS,而无需手动刷新页面。非常感谢分享:)
  • 可以在 wamp 上本地运行 Vogue 吗?
  • 我尝试过重新加载脚本,比如 Vogue。但是在 Chrome 中是个问题,因为最旧的样式表文件保留在浏览器中并且可以正常工作。例如,在一个元素中,我将背景从红色更改为白色,并且必须禁用最后一种颜色红色。
【解决方案5】:

Vanilla JS 中的一个较短的版本:

for (var link of document.querySelectorAll("link[rel=stylesheet]")) link.href = link.href.replace(/\?.*|$/, "?" + Date.now())

或扩展:

for (var link of document.querySelectorAll("link[rel=stylesheet]")) {
  link.href = link.href.replace(/\?.*|$/, "?" + Date.now())
}

【讨论】:

    【解决方案6】:

    另一种 jQuery 解决方案

    对于 id 为“css”的单个样式表,试试这个:

    $('#css').replaceWith('<link id="css" rel="stylesheet" href="css/main.css?t=' + Date.now() + '"></link>');
    

    将其包装在具有全局范围的函数中,您可以从 Chrome 的开发者控制台或 Firefox 的 Firebug 中使用它:

    var reloadCSS = function() {
      $('#css').replaceWith('<link id="css" rel="stylesheet" href="css/main.css?t=' + Date.now() + '"></link>');
    };
    

    【讨论】:

    • 嗨,我有这个,其中一些仅适用于 :( 即使我有时间添加以使其独一无二(这是在 firefox 上): function swapStyleSheet(sheet) { var sheet = sheet+'?t=' + Date.now(); $('#pagestyle').replaceWith('<link id="css" rel="stylesheet" href="'+sheet+'">'); } $("#stylesheet1").on("click", function(event) { swapStyleSheet("<url value="site.css"></url>"); } ); $("# stylesheet2").on("click", function(event) { swapStyleSheet("<url value="site2.css"></url>"); } );
    【解决方案7】:

    基于之前的解决方案,我用 JavaScript 代码创建了书签:

    javascript: { var toAppend = "trvhpqi=" + (new Date()).getTime(); var links = document.getElementsByTagName("link"); for (var i = 0; i < links.length;i++) { var link = links[i]; if (link.rel === "stylesheet") { if (link.href.indexOf("?") === -1) { link.href += "?" + toAppend; } else { if (link.href.indexOf("trvhpqi") === -1) { link.href += "&" + toAppend; } else { link.href = link.href.replace(/trvhpqi=\d{13}/, toAppend)} }; } } }; void(0);
    

    图片来自火狐:

    它有什么作用?

    它通过添加查询字符串参数来重新加载 CSS(如上面的解决方案):

    【讨论】:

      【解决方案8】:

      我现在有了这个:

          function swapStyleSheet() {
              var old = $('#pagestyle').attr('href');
              var newCss = $('#changeCss').attr('href');
              var sheet = newCss +Math.random(0,10);
              $('#pagestyle').attr('href',sheet);
              $('#profile').attr('href',old);
              }
          $("#changeCss").on("click", function(event) { 
              swapStyleSheet();
          } );
      

      在您的页面中使用 id 为 changeCss 的任何元素添加一个 href 属性,并在其中添加新的 css url。和一个带有起始 css 的链接元素:

      <link id="pagestyle" rel="stylesheet" type="text/css" href="css1.css?t=" />
      
      <img src="click.jpg" id="changeCss" href="css2.css?t=">
      

      【讨论】:

        【解决方案9】:

        另一个答案: 有一个名为 ReCSS 的书签。我没有广泛使用它,但似乎可以工作。

        该页面上有一个书签可以拖放到您的地址栏上(这里似乎无法制作)。万一它坏了,下面是代码:

        javascript:void(function()%7Bvar%20i,a,s;a=document.getElementsByTagName('link');for(i=0;i%3Ca.length;i++)%7Bs=a[i];if(s.rel.toLowerCase().indexOf('stylesheet')%3E=0&&s.href)%20%7Bvar%20h=s.href.replace(/(&%7C%5C?)forceReload=%5Cd%20/,'');s.href=h%20(h.indexOf('?')%3E=0?'&':'?')%20'forceReload='%20(new%20Date().valueOf())%7D%7D%7D)();
        

        【讨论】:

          【解决方案10】:

          如果你使用 php 很简单 只需在 css 末尾附加当前时间,如

          <link href="css/name.css?<?php echo 
          time(); ?>" rel="stylesheet">
          

          所以现在每次你重新加载它是什么,时间都会改变,浏览器认为它是一个不同的文件,因为最后一点一直在变化......你可以对任何文件执行此操作你强制浏览器始终使用任何脚本语言刷新你想要

          【讨论】:

            【解决方案11】:

            您可以简单地使用 rel="preload" 代替 rel="stylesheet"

            <link rel="preload" href="path/to/mystylesheet.css" as="style" onload="this.rel='stylesheet'">
            

            【讨论】:

            • 您说要使用rel="reload",但示例中显示的是rel="preload"
            • 感谢@haykam 纠正我,我已经更新了。
            【解决方案12】:

            由于这个问题已在 2019 年的 stackoverflow 中显示,我想使用更现代的 JavaScript 添加我的贡献。

            具体来说,对于非内联的 CSS 样式表——因为不知何故,原始问题已经涵盖了这一点。

            首先,请注意我们仍然没有可构造样式表对象。不过,我们希望它们能尽快落地。

            同时,假设HTML内容如下:

            <!DOCTYPE html>
            <html lang="en">
              <head>
                <meta charset="utf-8" />
                <link id="theme" rel="stylesheet" type="text/css" href="./index.css" />
                <script src="./index.js"></script>
              </head>
              <body>
                <p>Hello World</p>
                <button onclick="reload('theme')">Reload</button>
              </body>
            </html>
            
            

            我们可以在index.js:

            // Utility function to generate a promise that is 
            // resolved when the `target` resource is loaded,
            // and rejected if it fails to load.
            //
            const load = target =>
              new Promise((rs, rj) => {
                target.addEventListener("load", rs, { once: true });
                target.addEventListener(
                  "error",
                  rj.bind(null, `Can't load ${target.href}`),
                  { once: true }
                );
              });
            
            
            // Here the reload function called by the button.
            // It takes an `id` of the stylesheet that needs to be reloaded
            async function reload(id) {
              const link = document.getElementById(id);
            
              if (!link || !link.href) {
                throw new Error(`Can't reload '${id}', element or href attribute missing.`);
              }
            
              // Here the relevant part.
              // We're fetching the stylesheet from the server, specifying `reload`
              // as cache setting, since that is our intention.
              // With `reload`, the browser fetches the resource *without* first looking
              // in the cache, but then will update the cache with the downloaded resource.
              // So any other pages that request the same file and hit the cache first,
              // will use the updated version instead of the old ones.
              let response = await fetch(link.href, { cache: "reload" });
            
              // Once we fetched the stylesheet and replaced in the cache,
              // We want also to replace it in the document, so we're
              // creating a URL from the response's blob:
              let url = await URL.createObjectURL(await response.blob());
            
              // Then, we create another `<link>` element to display the updated style,
              // linked to the original one; but only if we didn't create previously:
              let updated = document.querySelector(`[data-link-id=${id}]`);
            
              if (!updated) {
                updated = document.createElement("link");
                updated.rel = "stylesheet";
                updated.type = "text/css";
                updated.dataset.linkId = id;
                link.parentElement.insertBefore(updated, link);
            
                // At this point we disable the original stylesheet,
                // so it won't be applied to the document anymore.
                link.disabled = true;
              }
            
              // We set the new <link> href...
              updated.href = url;
            
              // ...Waiting that is loaded...
              await load(updated);
            
              // ...and finally tell to the browser that we don't need
              // the blob's URL anymore, so it can be released.
              URL.revokeObjectURL(url);
            }
            

            【讨论】:

              【解决方案13】:

              是的,重新加载 css 标签。并记住使新 url 唯一(通常通过附加随机查询参数)。我有代码可以做到这一点,但现在没有。稍后会编辑...

              编辑:太晚了... harto 和 nickf 打败了我 ;-)

              【讨论】:

                猜你喜欢
                • 1970-01-01
                • 1970-01-01
                • 1970-01-01
                • 2011-11-09
                • 1970-01-01
                • 1970-01-01
                • 1970-01-01
                • 1970-01-01
                • 2011-11-02
                相关资源
                最近更新 更多