Có cách nào dễ dàng để tải lại css mà không cần tải lại trang không?


90

Tôi đang cố tạo một trình chỉnh sửa css trong trang trực tiếp với chức năng xem trước sẽ tải lại biểu định kiểu và áp dụng nó mà không cần tải lại trang. Cách tốt nhất để làm điều này là gì?


1
Năm 2014 và câu hỏi này là trên trang chủ ...
Kroltan

1
Năm 2019, hầu như năm 2020, và câu hỏi này vẫn popping trên trang chủ ...
Zer0

Câu trả lời:


51

Trên trang "chỉnh sửa", thay vì bao gồm CSS của bạn theo cách thông thường (với một <link>thẻ), hãy ghi tất cả vào một <style>thẻ. Việc chỉnh sửa thuộc innerHTMLtính đó sẽ tự động cập nhật trang, ngay cả khi không có chuyến đi khứ hồi đến máy chủ.

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

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

Javascript, sử dụng jQuery:

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

Và đó sẽ là nó!

Nếu bạn muốn thực sự lạ mắt, hãy gắn chức năng này vào phím bấm trên khung văn bản, mặc dù bạn có thể nhận được một số tác dụng phụ không mong muốn (trang sẽ thay đổi liên tục khi bạn nhập)

Chỉnh sửa : đã thử nghiệm và hoạt động (ít nhất là trong Firefox 3.5, mặc dù sẽ ổn với các trình duyệt khác). Xem demo tại đây: http://jsbin.com/owapi


3
IE bật thanhfs innerHTMLcho <style>các phần tử (và <script>).
JPot

3
nếu nó là href'ed thì sao?
allenhwkim

Btw, bạn có thể đính kèm một hàm vào keydown trên textarea nhưng hãy điều chỉnh nó bằng dấu gạch ngang (ví dụ).
Camilo Martin

109

Có thể không áp dụng cho trường hợp của bạn, nhưng đây là hàm jQuery mà tôi sử dụng để tải lại các bảng định kiểu bên ngoài:

/**
 * 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);
    });
}

3
Bạn có thể làm cho nó một dấu bằng ted.mielczarek.org/code/mozilla/bookmarklet.html
Luke Stanley

36
Phi jquery này một-liner công trình đối với tôi trong 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

Tôi không chắc có phải vì tôi chỉ đang mở trang trên chrome từ đĩa nhưng điều này không hoạt động với tôi.
Joao Carlos

14

Hoàn toàn không cần sử dụng jQuery cho việc này. Hàm JavaScript sau sẽ tải lại tất cả các tệp CSS của bạn:

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

1
Tôi đang sử dụng này trong giao diện điều khiển vì vậy tôi không cần thêm bất cứ điều gì khác trong mã của tôi
loco.loop

@Bram dấu ngoặc nhọn là tùy chọn. Mã hoạt động tốt.
Dan Bray

1
Câu trả lời tuyệt vời vì nó không dựa vào jQuery! :)
Gustavo Straube

9

Xem dự án Vogue hấp dẫn của Andrew Davey - http://aboutcode.net/vogue/


Đây chính xác là những gì tôi đã tìm kiếm. Nó tải lại CSS ngay khi thay đổi biểu định kiểu mà không cần phải làm mới trang theo cách thủ công. Nhờ một tấn để chia sẻ :)
Devner

Vogue có thể chạy cục bộ trên wamp không?
chrisdillon

Tôi đã thử tải lại kịch bản, như Vogue. Nhưng trong Chrome thì có vấn đề, vì các tệp biểu định kiểu tốt nhất vẫn ở trong trình duyệt và hoạt động. Ví dụ: trong một phần tử, tôi thay đổi màu nền từ đỏ sang trắng và tôi buộc phải tắt màu cuối cùng là đỏ.
Peter

7

Một phiên bản ngắn hơn trong Vanilla JS và trong một dòng:

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

Hoặc mở rộng:

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

6

Một giải pháp jQuery khác

Đối với một biểu định kiểu duy nhất có id "css", hãy thử cách này:

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

Gói nó trong một chức năng có cuộn chung và bạn có thể sử dụng nó từ Bảng điều khiển dành cho nhà phát triển trong Chrome hoặc Firebug trong Firefox:

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

1
xin chào, tôi có cái này, mà một số cách chỉ hoạt động một số: (mặc dù tôi đã thêm thời gian để làm cho nó duy nhất (cái này trên 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 ", function (event) {swapStyleSheet (" <c: url value = 'site2.css' /> ");}); </code>
tibi

3

Dựa trên các giải pháp trước đó, tôi đã tạo dấu trang bằng mã 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);

Hình ảnh từ Firefox:

nhập mô tả hình ảnh ở đây

Nó làm gì?

Nó tải lại CSS bằng cách thêm các tham số chuỗi truy vấn (như các giải pháp ở trên):


0

Có, tải lại thẻ css. Và hãy nhớ đặt url mới là duy nhất (thường bằng cách thêm một tham số truy vấn ngẫu nhiên). Tôi có mã để làm điều này nhưng không phải với tôi ngay bây giờ. Sẽ chỉnh sửa sau ...

chỉnh sửa: quá muộn ... harto và nickf đánh bại tôi với nó ;-)


0

bây giờ tôi có cái này:

    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();
    } );

tạo bất kỳ phần tử nào trong trang của bạn bằng id changeCss với thuộc tính href với url css mới trong đó. và một phần tử liên kết với css bắt đầu:

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

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

0

Một câu trả lời khác: Có một bookmarklet được gọi là ReCSS . Tôi đã không sử dụng nó rộng rãi, nhưng có vẻ hiệu quả.

Có một bookmarklet trên trang đó để kéo và thả vào thanh địa chỉ của bạn (Có vẻ như không thể tạo một bookmarklet ở đây). Trong trường hợp bị hỏng, đây là mã:

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

đơn giản nếu bạn đang sử dụng php Chỉ cần thêm thời gian hiện tại vào cuối css như

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

Vì vậy, bây giờ mỗi khi bạn tải lại bất cứ thứ gì, thời gian thay đổi và trình duyệt nghĩ rằng tệp của nó là một tệp khác vì bit cuối cùng tiếp tục thay đổi .... Bạn có thể làm điều này cho bất kỳ tệp nào, bạn buộc trình duyệt phải luôn làm mới bằng bất kỳ ngôn ngữ kịch bản nào bạn muốn


0

Theo cách đơn giản, bạn có thể sử dụng rel = "preload" thay vì rel = "stylesheet" .

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

Bạn nói để sử dụng rel="reload"nhưng ví dụ cho biết rel="preload".
haykam

Cảm ơn @haykam đã sửa cho tôi, tôi đã cập nhật nó.
Gagan

0

Vì câu hỏi này đã được hiển thị trong stackoverflow vào năm 2019, tôi muốn thêm đóng góp của mình bằng cách sử dụng JavaScript hiện đại hơn.

Cụ thể, đối với Biểu định kiểu CSS không nội tuyến - vì bằng cách nào đó đã được đề cập trong câu hỏi ban đầu.

Trước hết, hãy lưu ý rằng chúng ta vẫn chưa có Đối tượng biểu định kiểu có thể cấu trúc. Tuy nhiên, chúng tôi hy vọng họ sẽ sớm hạ cánh.

Trong khi chờ đợi, giả sử nội dung HTML sau:

<!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>

Chúng tôi có thể có, trong 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);
}
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.