Чи є простий спосіб перезавантажити css без перезавантаження сторінки?


90

Я намагаюся створити поточний редактор css на сторінці з функцією попереднього перегляду, який би перезавантажив таблицю стилів і застосував її без необхідності перезавантажувати сторінку. Який найкращий спосіб це зробити?


1
2014, і це питання є на домашній сторінці ...
Кролтан

1
2019, майже 2020, і це питання все ще з’являється на домашній сторінці ...
ZER0

Відповіді:


51

На сторінці "редагування", замість того, щоб включати ваш 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;
    });
});

І це повинно бути все!

Якщо ви хочете бути по-справжньому вигадливим, приєднайте цю функцію до клавіатури на текстовій області, хоча ви можете отримати небажані побічні ефекти (сторінка постійно змінюватиметься під час набору тексту)

Редагувати : перевірено та працює (принаймні у Firefox 3.5, хоча з іншими браузерами це має бути добре). Див. Демонстрацію тут: http://jsbin.com/owapi


3
IE barfs innerHTMLдля <style>елементів (і <script>).
JP,

3
що якщо це href'ed?
allenhwkim

До речі, ви можете приєднати функцію до клавіатури на текстовій області, але придушити її за допомогою тире (наприклад)
Каміло Мартін

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

3
Ви можете зробити це закладкою, використовуючи ted.mielczarek.org/code/mozilla/bookmarklet.html
Люк Стенлі

36
Цей не-jquery однокласник працює для мене в хромі:var links = document.getElementsByTagName("link"); for (var i = 0; i < links.length;i++) { var link = links[i]; if (link.rel === "stylesheet") {link.href += "?"; }}
Клод,

Я не впевнений, що це так, тому що я просто відкриваю сторінку на chrome з диска, але це не працює для мене.
Жоао Карлос

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! :)
Густаво Штраубе

9

Ознайомтеся з шикарним проектом Vogue Ендрю Дейві - http://aboutcode.net/vogue/


Це саме те, що я шукав. Він перезавантажує CSS, як тільки таблицю стилів змінюється, без необхідності оновлювати сторінку вручну. Спасибі тоні за обмін :)
Девнер,

Чи можна запустити Vogue локально на вампі?
chrisdillon

Я спробував перезавантажити сценарій, як 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

Для однієї таблиці стилів з ідентифікатором "css" спробуйте наступне:

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

Оберніть його у функцію, яка має глобальний масштаб, і ви можете використовувати її з Консолі розробника в Chrome або Firebug у Firefox:

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 value = 'site2.css' /> ");}); </code>
тибі

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

зробіть будь-який елемент на вашій сторінці з ідентифікатором changeCss з атрибутом href з новою URL-адресою css. і елемент посилання з початковим css:

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

Отже, кожен раз, коли ви перезавантажуєте, що б воно не було, час змінюється, і браузер вважає, що це інший файл, оскільки останній біт постійно змінюється .... U можете зробити це для будь-якого файлу, змусити браузер завжди оновлюватись, використовуючи будь-яку мову сценаріїв, яку ви хочете


0

Ви можете просто використовувати rel = "preload" замість rel = "таблиця стилів" .

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

Ви сказали використовувати, rel="reload"але приклад говорить rel="preload".
хайкам

Дякую @haykam за виправлення, я оновив його.
Гаган

0

Оскільки це питання було показано в stackoverflow у 2019 році, я хотів би додати свій внесок, використовуючи більш сучасний 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);
}
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.