J'essaie de créer un éditeur css en direct sur la page avec une fonction de prévisualisation qui rechargerait la feuille de style et l'appliquerait sans avoir besoin de recharger la page. Quelle serait la meilleure façon de procéder?
J'essaie de créer un éditeur css en direct sur la page avec une fonction de prévisualisation qui rechargerait la feuille de style et l'appliquerait sans avoir besoin de recharger la page. Quelle serait la meilleure façon de procéder?
Réponses:
Sur la page "modifier", au lieu d'inclure votre CSS de la manière habituelle (avec une <link>
balise), écrivez le tout dans une <style>
balise. La modification de la innerHTML
propriété de qui mettra automatiquement à jour la page, même sans aller-retour vers le serveur.
<style type="text/css" id="styles">
p {
color: #f0f;
}
</style>
<textarea id="editor"></textarea>
<button id="preview">Preview</button>
Le Javascript, en utilisant jQuery:
jQuery(function($) {
var $ed = $('#editor')
, $style = $('#styles')
, $button = $('#preview')
;
$ed.val($style.html());
$button.click(function() {
$style.html($ed.val());
return false;
});
});
Et ça devrait être ça!
Si vous vouliez être vraiment sophistiqué, attachez la fonction au clavier de la zone de texte, bien que vous puissiez obtenir des effets secondaires indésirables (la page changerait constamment à mesure que vous tapez)
Edit : testé et fonctionne (dans Firefox 3.5, au moins, mais devrait être bien avec d'autres navigateurs). Voir la démo ici: http://jsbin.com/owapi
innerHTML
pour les <style>
éléments (et <script>
).
Peut-être pas applicable à votre situation, mais voici la fonction jQuery que j'utilise pour recharger des feuilles de style externes:
/**
* 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 += "?"; }}
Il n'est absolument pas nécessaire d'utiliser jQuery pour cela. La fonction JavaScript suivante rechargera tous vos fichiers CSS:
function reloadCss()
{
var links = document.getElementsByTagName("link");
for (var cl in links)
{
var link = links[cl];
if (link.rel === "stylesheet")
link.href += "";
}
}
Découvrez le projet chic Vogue d'Andrew Davey - http://aboutcode.net/vogue/
Une version plus courte en Vanilla JS et en une ligne:
for (var link of document.querySelectorAll("link[rel=stylesheet]")) link.href = link.href.replace(/\?.*|$/, "?" + Date.now())
Ou élargi:
for (var link of document.querySelectorAll("link[rel=stylesheet]")) {
link.href = link.href.replace(/\?.*|$/, "?" + Date.now())
}
Encore une solution jQuery
Pour une seule feuille de style avec l'ID "css", essayez ceci:
$('#css').replaceWith('<link id="css" rel="stylesheet" href="css/main.css?t=' + Date.now() + '"></link>');
Enveloppez-le dans une fonction qui a un scrope global et vous pouvez l'utiliser à partir de la Developer Console dans Chrome ou Firebug dans Firefox:
var reloadCSS = function() {
$('#css').replaceWith('<link id="css" rel="stylesheet" href="css/main.css?t=' + Date.now() + '"></link>');
};
Sur la base de solutions précédentes, j'ai créé un signet avec du code 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);
Image de Firefox:
Qu'est ce que ça fait?
Il recharge le CSS en ajoutant des paramètres de chaîne de requête (comme solutions ci-dessus):
j'ai maintenant ceci:
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();
} );
créez n'importe quel élément de votre page avec l'id changeCss avec un attribut href contenant la nouvelle URL css. et un élément de lien avec le css de départ:
<link id="pagestyle" rel="stylesheet" type="text/css" href="css1.css?t=" />
<img src="click.jpg" id="changeCss" href="css2.css?t=">
Une autre réponse: il existe un bookmarklet appelé ReCSS . Je ne l'ai pas beaucoup utilisé, mais semble fonctionner.
Il y a un bookmarklet sur cette page à glisser-déposer sur votre barre d'adresse (je n'arrive pas à en créer un ici). En cas de panne, voici le 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)();
simple si vous utilisez php Ajoutez simplement l'heure actuelle à la fin du css comme
<link href="css/name.css?<?php echo
time(); ?>" rel="stylesheet">
Alors maintenant, à chaque fois que vous rechargez quoi que ce soit, l'heure change et le navigateur pense que c'est un fichier différent puisque le dernier bit ne cesse de changer ...
De manière simple, vous pouvez utiliser rel = "preload" au lieu de rel = "stylesheet" .
<link rel="preload" href="path/to/mystylesheet.css" as="style" onload="this.rel='stylesheet'">
rel="reload"
mais l'exemple dit rel="preload"
.
Étant donné que cette question a été affichée dans le stackoverflow en 2019, j'aimerais ajouter ma contribution en utilisant un JavaScript plus moderne.
Plus précisément, pour les feuilles de style CSS qui ne sont pas en ligne - car cela est déjà couvert par la question d'origine, d'une manière ou d'une autre.
Tout d'abord, notez que nous n'avons toujours pas d'objets de feuille de style constructibles. Cependant, nous espérons les avoir débarqués bientôt.
En attendant, en supposant le contenu HTML suivant:
<!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>
On aurait pu, en 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);
}