Ich versuche, einen Live-In-Page-CSS-Editor mit einer Vorschaufunktion zu erstellen, mit der das Stylesheet neu geladen und angewendet werden kann, ohne dass die Seite neu geladen werden muss. Was wäre der beste Weg, dies zu tun?
Ich versuche, einen Live-In-Page-CSS-Editor mit einer Vorschaufunktion zu erstellen, mit der das Stylesheet neu geladen und angewendet werden kann, ohne dass die Seite neu geladen werden muss. Was wäre der beste Weg, dies zu tun?
Antworten:
<link>
Schreiben Sie auf der Seite "Bearbeiten", anstatt Ihr CSS wie gewohnt (mit einem Tag) einzuschließen, alles in ein <style>
Tag. Durch Bearbeiten der innerHTML
Eigenschaft wird die Seite automatisch aktualisiert, auch ohne einen Roundtrip zum Server.
<style type="text/css" id="styles">
p {
color: #f0f;
}
</style>
<textarea id="editor"></textarea>
<button id="preview">Preview</button>
Das Javascript mit jQuery:
jQuery(function($) {
var $ed = $('#editor')
, $style = $('#styles')
, $button = $('#preview')
;
$ed.val($style.html());
$button.click(function() {
$style.html($ed.val());
return false;
});
});
Und das sollte es sein!
Wenn Sie wirklich ausgefallen sein möchten, hängen Sie die Funktion an den Keydown im Textbereich an, obwohl Sie möglicherweise unerwünschte Nebenwirkungen haben (die Seite ändert sich während der Eingabe ständig).
Bearbeiten : getestet und funktioniert (zumindest in Firefox 3.5, sollte aber mit anderen Browsern in Ordnung sein). Siehe Demo hier: http://jsbin.com/owapi
innerHTML
für <style>
Elemente (und <script>
).
Möglicherweise nicht zutreffend für Ihre Situation, aber hier ist die jQuery-Funktion, die ich zum Neuladen externer Stylesheets verwende:
/**
* 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);
});
}
var links = document.getElementsByTagName("link"); for (var i = 0; i < links.length;i++) { var link = links[i]; if (link.rel === "stylesheet") {link.href += "?"; }}
Es ist absolut nicht erforderlich, jQuery dafür zu verwenden. Die folgende JavaScript-Funktion lädt alle Ihre CSS-Dateien neu:
function reloadCss()
{
var links = document.getElementsByTagName("link");
for (var cl in links)
{
var link = links[cl];
if (link.rel === "stylesheet")
link.href += "";
}
}
Schauen Sie sich Andrew Daveys schickes Vogue-Projekt an - http://aboutcode.net/vogue/
Eine kürzere Version in Vanilla JS und in einer Zeile:
for (var link of document.querySelectorAll("link[rel=stylesheet]")) link.href = link.href.replace(/\?.*|$/, "?" + Date.now())
Oder erweitert:
for (var link of document.querySelectorAll("link[rel=stylesheet]")) {
link.href = link.href.replace(/\?.*|$/, "?" + Date.now())
}
Noch eine jQuery-Lösung
Versuchen Sie für ein einzelnes Stylesheet mit der ID "css" Folgendes:
$('#css').replaceWith('<link id="css" rel="stylesheet" href="css/main.css?t=' + Date.now() + '"></link>');
Schließen Sie es in eine Funktion mit globalem Umfang ein, und Sie können es über die Entwicklerkonsole in Chrome oder Firebug in Firefox verwenden:
var reloadCSS = function() {
$('#css').replaceWith('<link id="css" rel="stylesheet" href="css/main.css?t=' + Date.now() + '"></link>');
};
Basierend auf früheren Lösungen habe ich ein Lesezeichen mit JavaScript-Code erstellt:
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);
Bild von Firefox:
Was tut es?
CSS wird neu geladen, indem Abfragezeichenfolgenparameter hinzugefügt werden (wie oben beschrieben):
Ja, laden Sie das CSS-Tag neu. Denken Sie auch daran, die neue URL eindeutig zu machen (normalerweise durch Anhängen eines zufälligen Abfrageparameters). Ich habe Code, um dies zu tun, aber momentan nicht bei mir. Wird später bearbeitet ...
edit: zu spät ... harto und nickf haben mich geschlagen ;-)
Ich habe jetzt das:
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();
} );
Erstellen Sie ein Element auf Ihrer Seite mit der ID changeCss mit einem href-Attribut mit der neuen CSS-URL. und ein Linkelement mit dem Start-CSS:
<link id="pagestyle" rel="stylesheet" type="text/css" href="css1.css?t=" />
<img src="click.jpg" id="changeCss" href="css2.css?t=">
Eine andere Antwort: Es gibt ein Lesezeichen namens ReCSS . Ich habe es nicht ausgiebig benutzt, scheint aber zu funktionieren.
Auf dieser Seite befindet sich ein Lesezeichen, das Sie per Drag & Drop in Ihre Adressleiste ziehen können (hier kann anscheinend kein Lesezeichen erstellt werden). Falls das kaputt ist, hier ist der Code:
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)();
einfach, wenn Sie PHP verwenden Fügen Sie einfach die aktuelle Zeit am Ende des CSS wie
<link href="css/name.css?<?php echo
time(); ?>" rel="stylesheet">
Jedes Mal, wenn Sie neu laden, was auch immer es ist, ändert sich die Zeit und der Browser denkt, dass es sich um eine andere Datei handelt, da sich das letzte Bit ständig ändert. Sie können dies für jede Datei tun und den Browser zwingen, immer mit der gewünschten Skriptsprache zu aktualisieren
Auf einfache Weise können Sie rel = "Preload" anstelle von rel = "Stylesheet" verwenden .
<link rel="preload" href="path/to/mystylesheet.css" as="style" onload="this.rel='stylesheet'">
rel="reload"
aber das Beispiel sagt rel="preload"
.
Da diese Frage 2019 im Stackoverflow angezeigt wurde, möchte ich meinen Beitrag mit einem moderneren JavaScript hinzufügen.
Speziell für CSS-Stylesheets, die nicht inline sind - da dies irgendwie bereits von der ursprünglichen Frage abgedeckt ist.
Beachten Sie zunächst, dass wir immer noch keine konstruierbaren Stylesheet-Objekte haben. Wir hoffen jedoch, dass sie bald gelandet sind.
In der Zwischenzeit wird folgender HTML-Inhalt angenommen:
<!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>
Wir könnten haben in 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);
}