是否有一种简单的方法可以在不重新加载页面的情况下重新加载CSS?


90

我正在尝试使用预览功能制作活页内css编辑器,该功能将重新加载样式表并应用它,而无需重新加载页面。最好的方法是什么?


1
2014年,这个问题在首页上...
Kroltan 2014年

1
2019年,差不多2020年,这个问题仍会出现在首页上…
ZER0

Answers:


51

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

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

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

使用jQuery的Javascript:

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


3
IE barfs上innerHTML<style>元素(和<script>)。
JPot 2010年

3
如果被href了怎么办?
allenhwkim 2013年

顺便说一句,您可以将一个功能附加到textarea上的keydown上,但可以使用lo-dash进行限制(例如)。
卡米洛·马丁

109

可能不适用于您的情况,但这是我用于重新加载外部样式表的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);
    });
}


36
这种非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 += "?"; }}
克劳德(Claude)

我不确定是否是因为我只是从磁盘打开chrome上的页面,但这对我不起作用。
Joao Carlos

14

绝对不需要为此使用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 += "";
    }
}

1
我在控制台中使用此代码,因此无需在代码中添加其他任何内容
loco.loop

@Bram花括号是可选的。该代码工作正常。
丹·布雷

1
很好的答案,因为它不依赖jQuery!:)
Gustavo Straube

9

查看安德鲁·戴维(Andrew Davey)时髦的Vogue项目-http: //aboutcode.net/vogue/


这正是我一直在寻找的东西。样式表更改后,它将立即重新加载CSS,而无需手动刷新页面。多谢分享:)
Devner

Vogue可以在本地运行吗?
chrisdillon 2014年

我试过重新加载脚本,例如Vogue。但是在Chrome中是有问题的,因为最新的样式表文件保留在浏览器中并且可以正常工作。例如,在一个元素中,我将背景从红色更改为白色,并且必须禁用上一个红色。
彼得

7

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>');

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

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

1
嗨,我有这个,这是一些怎么工作的:(即使我有时间增加使其唯一(在Firefox中也是如此):<code> function swapStyleSheet(sheet){var sheet = sheet +'?t =' + Date.now(); $('#pagestyle')。replaceWith('<link id =“ css” rel =“ stylesheet” href =“'+ sheet +'”> </ link>');} $(“ #stylesheet1“)。on(” click“,function(event){swapStyleSheet(” <c:url value ='site.css'/>“);}); $(”#stylesheet2“)。on(” click ”功能(事件){swapStyleSheet( “<C:url值= 'site2.css'/>”);}); </代码>
提笔

3

基于先前的解决方案,我使用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);

来自Firefox的图片:

在此处输入图片说明

它有什么作用?

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


0

是的,重新加载css标签。并记住要使新的URL唯一(通常通过附加一个随机查询参数)。我有执行此操作的代码,但现在没有。稍后再编辑...

编辑:太晚了……harto和nickf击败了我;-)


0

我现在有这个:

    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元素:

<link id="pagestyle" rel="stylesheet" type="text/css" href="css1.css?t=" />

<img src="click.jpg" id="changeCss" href="css2.css?t=">

0

另一个答案:有一个名为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)();

0

如果您使用的是php,则很简单,只需在CSS末尾附加当前时间,例如

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

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


0

您可以通过简单的方式使用rel =“ preload”而不是rel =“ stylesheet”

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

您说要使用,rel="reload"但示例中说rel="preload"
haykam

感谢@haykam纠正我,我已经更新了它。
加根

0

由于此问题已在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);
}
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.