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ì?
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ì?
Câu trả lời:
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 innerHTML
tí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
innerHTML
cho <style>
các phần tử (và <script>
).
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);
});
}
var links = document.getElementsByTagName("link"); for (var i = 0; i < links.length;i++) { var link = links[i]; if (link.rel === "stylesheet") {link.href += "?"; }}
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 += "";
}
}
Xem dự án Vogue hấp dẫn của Andrew Davey - http://aboutcode.net/vogue/
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())
}
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>');
};
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:
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):
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ó ;-)
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=">
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)();
đơ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
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'">
rel="reload"
nhưng ví dụ cho biết rel="preload"
.
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);
}