Adakah cara mudah untuk memuat ulang css tanpa memuat ulang halaman?

90

Saya mencoba membuat editor css dalam halaman langsung dengan fungsi pratinjau yang akan memuat ulang stylesheet dan menerapkannya tanpa perlu memuat ulang halaman. Apa cara terbaik untuk melakukan ini?

Stephen Belanger
sumber
1
2014 dan pertanyaan ini ada di halaman beranda ...
Kroltan
1
2019, hampir tahun 2020, dan pertanyaan ini masih muncul di beranda…
ZER0

Jawaban:

51

Di halaman "edit", alih-alih menyertakan CSS Anda dengan cara biasa (dengan <link>tag), tulis semuanya ke <style>tag. Mengedit innerHTMLproperti yang secara otomatis akan memperbarui halaman, bahkan tanpa bolak-balik ke server.

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

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

Javascript, menggunakan jQuery:

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

Dan seharusnya begitu!

Jika Anda ingin benar-benar mewah, lampirkan fungsi ke tombol bawah pada textarea, meskipun Anda bisa mendapatkan beberapa efek samping yang tidak diinginkan (halaman akan terus berubah saat Anda mengetik)

Sunting : diuji dan berfungsi (di Firefox 3.5, setidaknya, meskipun harus baik-baik saja dengan browser lain). Lihat demo di sini: http://jsbin.com/owapi

nickf
sumber
3
IE muntah innerHTMLuntuk <style>elemen (dan <script>).
JPot
3
bagaimana jika itu adalah href'ed?
allenhwkim
Btw, Anda bisa melampirkan fungsi ke tombol bawah pada textarea tapi throttle dengan lo-dash (misalnya).
Camilo Martin
109

Mungkin tidak berlaku untuk situasi Anda, tetapi inilah fungsi jQuery yang saya gunakan untuk memuat ulang stylesheet eksternal:

/**
 * 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);
    });
}
harto
sumber
3
Anda dapat menjadikannya bookmark menggunakan ted.mielczarek.org/code/mozilla/bookmarklet.html
Luke Stanley
36
Satu baris non-jquery ini bekerja untuk saya di 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
Saya tidak yakin apakah itu karena saya baru saja membuka halaman di chrome dari disk tetapi ini tidak berfungsi untuk saya.
Joao Carlos
14

Sama sekali tidak perlu menggunakan jQuery untuk ini. Fungsi JavaScript berikut akan memuat ulang semua file CSS Anda:

function reloadCss()
{
    var links = document.getElementsByTagName("link");
    for (var cl in links)
    {
        var link = links[cl];
        if (link.rel === "stylesheet")
            link.href += "";
    }
}
Dan Bray
sumber
1
Saya menggunakan ini di konsol jadi saya tidak perlu menambahkan apa pun di kode saya
loco.loop
@ Bram penjepit keriting adalah opsional. Kode berfungsi dengan baik.
Dan Bray
1
Jawaban bagus karena tidak bergantung pada jQuery! :)
Gustavo Straube
9

Lihat proyek Vogue keren Andrew Davey - http://aboutcode.net/vogue/

mcintyre321
sumber
Inilah yang sebenarnya saya cari-cari. Ini memuat ulang CSS segera setelah stylesheet diubah, tanpa perlu menyegarkan halaman secara manual. Terima kasih banyak untuk berbagi :)
Devner
Bisakah Vogue dijalankan secara lokal di wamp?
chrisdillon
Saya mencoba melakukan reload script, seperti Vogue. Tapi di Chrome masalah, karena file stylesheet olest tetap di browser dan berfungsi. Misalnya, dalam satu elemen saya mengubah latar belakang dari merah menjadi putih, dan saya harus menonaktifkan warna merah terakhir.
Peter
7

Versi yang lebih pendek di Vanilla JS dan dalam satu baris:

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

Atau diperluas:

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

Satu lagi solusi jQuery

Untuk satu lembar gaya dengan id "css" coba ini:

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

Bungkusnya dalam fungsi yang memiliki scrope global dan Anda dapat menggunakannya dari Konsol Pengembang di Chrome atau Firebug di Firefox:

var reloadCSS = function() {
  $('#css').replaceWith('<link id="css" rel="stylesheet" href="css/main.css?t=' + Date.now() + '"></link>');
};
mattdlockyer
sumber
1
hai, saya punya ini, yang mana beberapa cara hanya berfungsi satu :( meskipun saya punya waktu tambahan untuk membuatnya unik (ini di 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

Berdasarkan solusi sebelumnya, saya telah membuat bookmark dengan kode 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);

Gambar dari Firefox:

masukkan deskripsi gambar di sini

Apa fungsinya?

Itu memuat ulang CSS dengan menambahkan parameter string kueri (seperti solusi di atas):

LukLed
sumber
0

Ya, muat ulang tag css. Dan ingat untuk membuat url baru menjadi unik (biasanya dengan menambahkan parameter kueri acak). Saya memiliki kode untuk melakukan ini tetapi tidak dengan saya sekarang. Akan diedit nanti ...

edit: terlambat ... harto dan nickf mengalahkan saya untuk itu ;-)

slebetman
sumber
0

saya sekarang punya ini:

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

buat elemen apa pun di halaman Anda dengan id changeCss dengan atribut href dengan url css baru di dalamnya. dan elemen tautan dengan css awal:

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

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

Jawaban lain: Ada bookmarklet yang disebut ReCSS . Saya belum pernah menggunakannya secara ekstensif, tetapi tampaknya berhasil.

Ada bookmarklet di halaman itu untuk menyeret dan melepaskan ke bilah alamat Anda (Sepertinya tidak dapat membuatnya di sini). Jika itu rusak, inilah kodenya:

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)();
Christopher Schneider
sumber
0

sederhana jika Anda menggunakan php Cukup tambahkan waktu saat ini di akhir css seperti

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

Jadi sekarang setiap kali Anda memuat ulang apa pun itu, waktu berubah dan browser menganggapnya sebagai file yang berbeda sejak bit terakhir terus berubah .... Anda dapat melakukan ini untuk file apa pun Anda memaksa browser untuk selalu menyegarkan menggunakan bahasa skrip apa pun yang Anda inginkan

asiimwedismas
sumber
0

Secara sederhana, Anda dapat menggunakan rel = "preload" sebagai ganti rel = "stylesheet" .

<link rel="preload" href="path/to/mystylesheet.css" as="style" onload="this.rel='stylesheet'">
Gagan
sumber
Anda mengatakan untuk menggunakan rel="reload"tetapi contoh mengatakan rel="preload".
haykam
Terima kasih @haykam telah mengoreksi saya, saya telah memperbaruinya.
Gagan
0

Karena pertanyaan ini ditampilkan di stackoverflow pada tahun 2019, saya ingin menambahkan kontribusi saya menggunakan JavaScript yang lebih modern.

Secara khusus, untuk CSS Stylesheet yang tidak sebaris - karena itu sudah tercakup dari pertanyaan asli, entah bagaimana.

Pertama-tama, perhatikan bahwa kami masih belum memiliki Objek Lembar Gaya yang Dapat Dikonstruksi. Namun, kami berharap mereka segera mendarat.

Sementara itu, anggap konten HTML berikut:

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

Kami dapat memiliki, di 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);
}
ZER0
sumber