Tôi có một trang đơn giản có một số phần iframe (để hiển thị các liên kết RSS). Làm cách nào tôi có thể áp dụng định dạng CSS tương tự từ trang chính vào trang được hiển thị trong iframe?
Tôi có một trang đơn giản có một số phần iframe (để hiển thị các liên kết RSS). Làm cách nào tôi có thể áp dụng định dạng CSS tương tự từ trang chính vào trang được hiển thị trong iframe?
Câu trả lời:
Chỉnh sửa: Điều này không hoạt động tên miền chéo trừ khi tiêu đề CORS thích hợp được đặt.
Có hai điều khác nhau ở đây: kiểu của khối iframe và kiểu của trang được nhúng trong iframe. Bạn có thể đặt kiểu khối iframe theo cách thông thường:
<iframe name="iframe1" id="iframe1" src="empty.htm"
frameborder="0" border="0" cellspacing="0"
style="border-style: none;width: 100%; height: 120px;"></iframe>
Kiểu của trang được nhúng trong iframe phải được đặt bằng cách đưa nó vào trang con:
<link type="text/css" rel="Stylesheet" href="Style/simple.css" />
Hoặc nó có thể được tải từ trang mẹ bằng Javascript:
var cssLink = document.createElement("link");
cssLink.href = "style.css";
cssLink.rel = "stylesheet";
cssLink.type = "text/css";
frames['iframe1'].document.head.appendChild(cssLink);
document.getElementById("myframe").contentDocument
. Mặc dù vậy, việc nhúng css dường như vẫn không hiệu quả với tôi.
...document.head.appendChild(cssLink)
- Firefox và Safari.
Tôi đã gặp vấn đề này với Lịch Google . Tôi muốn tạo kiểu cho nó trên nền tối hơn và thay đổi phông chữ.
May mắn thay, URL từ mã nhúng không bị hạn chế truy cập trực tiếp, vì vậy bằng cách sử dụng chức năng PHP file_get_contents
, có thể lấy toàn bộ nội dung từ trang. Thay vì gọi URL Google, có thể gọi tệp php nằm trên máy chủ của bạn, ví dụ: google.php
, sẽ chứa nội dung gốc với các sửa đổi:
$content = file_get_contents('https://www.google.com/calendar/embed?src=%23contacts%40group.v.calendar.google.com&ctz=America/Montreal');
Thêm đường dẫn vào biểu định kiểu của bạn:
$content = str_replace('</head>','<link rel="stylesheet" href="http://www.yourwebsiteurl.com/google.css" /></head>', $content);
(Điều này sẽ đặt biểu định kiểu của bạn kéo dài ngay trước head
thẻ kết thúc.)
Chỉ định mẫu url cơ sở url gốc trong trường hợp css và js được gọi tương đối:
$content = str_replace('</title>','</title><base href="https://www.google.com/calendar/" />', $content);
Các google.php
tập tin cuối cùng sẽ trông như thế này:
<?php
$content = file_get_contents('https://www.google.com/calendar/embed?src=%23contacts%40group.v.calendar.google.com&ctz=America/Montreal');
$content = str_replace('</title>','</title><base href="https://www.google.com/calendar/" />', $content);
$content = str_replace('</head>','<link rel="stylesheet" href="http://www.yourwebsiteurl.com/google.css" /></head>', $content);
echo $content;
Sau đó, bạn thay đổi iframe
mã nhúng thành:
<iframe src="http://www.yourwebsiteurl.com/google.php" style="border: 0" width="800" height="600" frameborder="0" scrolling="no"></iframe>
Chúc may mắn!
Nếu nội dung của iframe không hoàn toàn nằm dưới sự kiểm soát của bạn hoặc bạn muốn truy cập nội dung từ các trang khác nhau với các kiểu khác nhau, bạn có thể thử thao tác với nó bằng JavaScript.
var frm = frames['frame'].document;
var otherhead = frm.getElementsByTagName("head")[0];
var link = frm.createElement("link");
link.setAttribute("rel", "stylesheet");
link.setAttribute("type", "text/css");
link.setAttribute("href", "style.css");
otherhead.appendChild(link);
Lưu ý rằng tùy thuộc vào trình duyệt bạn sử dụng, trình duyệt này chỉ có thể hoạt động trên các trang được phân phát từ cùng một tên miền.
<iframe onload="this.contentDocument.body.style.overflow='hidden';" />
var $head = $("#eFormIFrame").contents().find("head");
$head.append($("<link/>", {
rel: "stylesheet",
href: url,
type: "text/css"
}));
Một iframe được xử lý chung như một trang HTML khác bởi hầu hết các trình duyệt. Nếu bạn muốn áp dụng cùng một biểu định kiểu cho nội dung của iframe, chỉ cần tham chiếu nó từ các trang được sử dụng trong đó.
Dưới đây là cách áp dụng mã CSS trực tiếp mà không cần sử dụng <link>
để tải thêm biểu định kiểu.
var head = jQuery("#iframe").contents().find("head");
var css = '<style type="text/css">' +
'#banner{display:none}; ' +
'</style>';
jQuery(head).append(css);
Điều này ẩn biểu ngữ trong trang iframe. Cám ơn bạn đã đóng góp ý kiến!
iframe
không?
#iframe
với #<id>
hoặc thậm chí iframe
để chọn tất cả iframe
s
Nếu bạn kiểm soát trang trong iframe, như hangy đã nói, cách tiếp cận đơn giản nhất là tạo tệp CSS được chia sẻ với các kiểu phổ biến, sau đó chỉ cần liên kết với nó từ các trang html của bạn.
Nếu không, rất có thể bạn sẽ không thể tự động thay đổi kiểu của một trang từ một trang bên ngoài trong iframe của bạn. Điều này là do các trình duyệt đã thắt chặt bảo mật trên kịch bản dom khung chéo do có thể lạm dụng để giả mạo và các bản hack khác.
Hướng dẫn này có thể cung cấp cho bạn thêm thông tin về iframe nói chung. Giới thiệu về kịch bản khung chéo giải thích các hạn chế bảo mật từ phối cảnh IE.
Ở trên với một chút thay đổi hoạt động:
var cssLink = document.createElement("link")
cssLink.href = "pFstylesEditor.css";
cssLink.rel = "stylesheet";
cssLink.type = "text/css";
//Instead of this
//frames['frame1'].document.body.appendChild(cssLink);
//Do this
var doc=document.getElementById("edit").contentWindow.document;
//If you are doing any dynamic writing do that first
doc.open();
doc.write(myData);
doc.close();
//Then append child
doc.body.appendChild(cssLink);
Hoạt động tốt với ít nhất là ff3 và eg8
dynamic data
Nếu bạn muốn sử dụng lại CSS và JavaScript từ trang chính, có lẽ bạn nên xem xét thay thế <IFRAME>
bằng một nội dung được tải Ajax. Điều này thân thiện với SEO hơn bây giờ khi các bot tìm kiếm có thể thực thi JavaScript.
Đây là ví dụ jQuery bao gồm một trang html khác vào tài liệu của bạn. Điều này thân thiện với SEO hơn nhiều iframe
. Để chắc chắn rằng các bot không lập chỉ mục trang được bao gồm, chỉ cần thêm nó để không cho phéprobots.txt
<html>
<header>
<script src="/js/jquery.js" type="text/javascript"></script>
</header>
<body>
<div id='include-from-outside'></div>
<script type='text/javascript'>
$('#include-from-outside').load('http://example.com/included.html');
</script>
</body>
</html>
Bạn cũng có thể bao gồm jQuery trực tiếp từ Google: http://code.google.com.vn/apis/ajaxlibs/documentation/ - điều này có nghĩa là tự động đưa vào các phiên bản mới hơn và tăng tốc độ đáng kể. Ngoài ra, có nghĩa là bạn phải tin tưởng họ vì đã cung cấp cho bạn chỉ jQuery;)
Sau đây làm việc cho tôi.
var iframe = top.frames[name].document;
var css = '' +
'<style type="text/css">' +
'body{margin:0;padding:0;background:transparent}' +
'</style>';
iframe.open();
iframe.write(css);
iframe.close();
Uncaught TypeError: Cannot read property 'open' of undefined
Mở rộng trên giải pháp jQuery ở trên để đối phó với bất kỳ sự chậm trễ nào trong việc tải nội dung khung.
$('iframe').each(function(){
function injectCSS(){
$iframe.contents().find('head').append(
$('<link/>', { rel: 'stylesheet', href: 'iframe.css', type: 'text/css' })
);
}
var $iframe = $(this);
$iframe.on('load', injectCSS);
injectCSS();
});
Phiên bản nhỏ gọn của tôi :
<script type="text/javascript">
$(window).load(function () {
var frame = $('iframe').get(0);
if (frame != null) {
var frmHead = $(frame).contents().find('head');
if (frmHead != null) {
frmHead.append($('style, link[rel=stylesheet]').clone()); // clone existing css link
//frmHead.append($("<link/>", { rel: "stylesheet", href: "/styles/style.css", type: "text/css" })); // or create css link yourself
}
}
});
</script>
Tuy nhiên, đôi khi iframe
không sẵn sàng trên cửa sổ được tải, do đó cần sử dụng bộ hẹn giờ .
Mã sẵn sàng sử dụng (có bộ đếm thời gian):
<script type="text/javascript">
var frameListener;
$(window).load(function () {
frameListener = setInterval("frameLoaded()", 50);
});
function frameLoaded() {
var frame = $('iframe').get(0);
if (frame != null) {
var frmHead = $(frame).contents().find('head');
if (frmHead != null) {
clearInterval(frameListener); // stop the listener
frmHead.append($('style, link[rel=stylesheet]').clone()); // clone existing css link
//frmHead.append($("<link/>", { rel: "stylesheet", href: "/styles/style.css", type: "text/css" })); // or create css link yourself
}
}
}
</script>
... Và liên kết jQuery:
<script src="https://ajax.aspnetcdn.com/ajax/jQuery/jquery-1.9.1.min.js" type="text/javascript"></script>
Các câu trả lời khác ở đây dường như sử dụng các liên kết jQuery và CSS.
Mã này sử dụng JavaScript vanilla. Nó tạo ra một <style>
yếu tố mới . Nó đặt nội dung văn bản của phần tử đó là một chuỗi chứa CSS mới. Và nó nối phần tử đó trực tiếp vào phần đầu của tài liệu iframe.
var iframe = document.getElementById('the-iframe');
var style = document.createElement('style');
style.textContent =
'.some-class-name {' +
' some-style-name: some-value;' +
'}'
;
iframe.contentDocument.head.appendChild(style);
Khi bạn nói "doc.open ()", điều đó có nghĩa là bạn có thể viết bất kỳ thẻ HTML nào bên trong iframe, vì vậy bạn nên viết tất cả các thẻ cơ bản cho trang HTML và nếu bạn muốn có một liên kết CSS trong đầu iframe của mình, hãy viết một iframe với liên kết CSS trong đó. Tôi cho bạn một ví dụ:
doc.open();
doc.write('<!DOCTYPE html><html><head><meta charset="utf-8"/><meta http-quiv="Content-Type" content="text/html; charset=utf-8"/><title>Print Frame</title><link rel="stylesheet" type="text/css" href="https://stackoverflow.com/css/print.css"/></head><body><table id="' + gridId + 'Printable' + '" class="print" >' + out + '</table></body></html>');
doc.close();
sử dụng có thể thử điều này:
$('iframe').load( function() {
$('iframe').contents().find("head")
.append($("<style type='text/css'> .my-class{display:none;} </style>"));
});
Bạn sẽ không thể định kiểu nội dung của iframe theo cách này. Đề xuất của tôi sẽ là sử dụng tập lệnh bên máy chủ (PHP, ASP hoặc tập lệnh Perl) hoặc tìm một dịch vụ trực tuyến sẽ chuyển đổi nguồn cấp dữ liệu sang mã JavaScript. Cách duy nhất khác để làm điều đó là nếu bạn có thể thực hiện một máy chủ bao gồm.
Nếu bạn có quyền truy cập vào trang iframe và muốn một CSS khác chỉ áp dụng trên trang đó khi bạn tải nó qua iframe trên trang của mình, ở đây tôi đã tìm thấy một giải pháp cho những điều này
điều này hoạt động ngay cả khi iframe đang tải một tên miền khác
kiểm tra về postMessage()
kế hoạch là, gửi css đến iframe dưới dạng tin nhắn như
iframenode.postMessage('h2{color:red;}','*');
*
là gửi tin nhắn này bất kể tên miền đó là gì trong iframe
và nhận tin nhắn trong iframe và thêm tin nhắn nhận được (CSS) vào đầu tài liệu đó.
mã để thêm vào trang iframe
window.addEventListener('message',function(e){
if(e.data == 'send_user_details')
document.head.appendChild('<style>'+e.data+'</style>');
});
Vì nhiều câu trả lời được viết cho cùng một tên miền, tôi sẽ viết cách thực hiện điều này trong các tên miền chéo.
Trước tiên, bạn cần biết API tin nhắn bài . Chúng ta cần một người đưa tin để liên lạc giữa hai cửa sổ.
Đây là một tin nhắn tôi tạo ra.
/**
* Creates a messenger between two windows
* which have two different domains
*/
class CrossMessenger {
/**
*
* @param {object} otherWindow - window object of the other
* @param {string} targetDomain - domain of the other window
* @param {object} eventHandlers - all the event names and handlers
*/
constructor(otherWindow, targetDomain, eventHandlers = {}) {
this.otherWindow = otherWindow;
this.targetDomain = targetDomain;
this.eventHandlers = eventHandlers;
window.addEventListener("message", (e) => this.receive.call(this, e));
}
post(event, data) {
try {
// data obj should have event name
var json = JSON.stringify({
event,
data
});
this.otherWindow.postMessage(json, this.targetDomain);
} catch (e) {}
}
receive(e) {
var json;
try {
json = JSON.parse(e.data ? e.data : "{}");
} catch (e) {
return;
}
var eventName = json.event,
data = json.data;
if (e.origin !== this.targetDomain)
return;
if (typeof this.eventHandlers[eventName] === "function")
this.eventHandlers[eventName](data);
}
}
Sử dụng điều này trong hai cửa sổ để giao tiếp có thể giải quyết vấn đề của bạn.
Trong các cửa sổ chính,
var msger = new CrossMessenger(iframe.contentWindow, "https://iframe.s.domain");
var cssContent = Array.prototype.map.call(yourCSSElement.sheet.cssRules, css_text).join('\n');
msger.post("cssContent", {
css: cssContent
})
Sau đó, nhận sự kiện từ Iframe.
Trong khung nội tuyến:
var msger = new CrossMessenger(window.parent, "https://parent.window.domain", {
cssContent: (data) => {
var cssElem = document.createElement("style");
cssElem.innerHTML = data.css;
document.head.appendChild(cssElem);
}
})
Xem hướng dẫn đầy đủ Javascript và Iframes để biết thêm chi tiết.
Tôi tìm thấy một giải pháp khác để đặt phong cách trong html chính như thế này
<style id="iframestyle">
html {
color: white;
background: black;
}
</style>
<style>
html {
color: initial;
background: initial;
}
iframe {
border: none;
}
</style>
và sau đó trong iframe làm điều này (xem js onload)
<iframe onload="iframe.document.head.appendChild(ifstyle)" name="log" src="/upgrading.log"></iframe>
và trong js
<script>
ifstyle = document.getElementById('iframestyle')
iframe = top.frames["log"];
</script>
Nó có thể không phải là giải pháp tốt nhất và chắc chắn nó có thể được cải thiện, nhưng đó là một lựa chọn khác nếu bạn muốn giữ một thẻ "style" trong cửa sổ cha
Ở đây, có hai điều trong miền
Vì vậy, bạn muốn tạo kiểu cho hai phần như sau,
1. Phong cách cho Phần iFrame
Nó có thể tạo kiểu bằng cách sử dụng CSS với tên id
hoặc được tôn trọng class
. Bạn cũng có thể tạo kiểu cho nó trong bảng Kiểu cha mẹ của bạn.
<style>
#my_iFrame{
height: 300px;
width: 100%;
position:absolute;
top:0;
left:0;
border: 1px black solid;
}
</style>
<iframe name='iframe1' id="my_iFrame" src="#" cellspacing="0"></iframe>
2. Định kiểu trang được tải bên trong iFrame
Kiểu này có thể được tải từ trang mẹ với sự trợ giúp của Javascript
var cssFile = document.createElement("link")
cssFile.rel = "stylesheet";
cssFile.type = "text/css";
cssFile.href = "iFramePage.css";
sau đó đặt tệp CSS đó thành phần iFrame được tôn trọng
//to Load in the Body Part
frames['my_iFrame'].document.body.appendChild(cssFile);
//to Load in the Head Part
frames['my_iFrame'].document.head.appendChild(cssFile);
Tại đây, bạn cũng có thể chỉnh sửa Phần đầu của Trang bên trong iFrame bằng cách này
var $iFrameHead = $("#my_iFrame").contents().find("head");
$iFrameHead.append(
$("<link/>",{
rel: "stylesheet",
href: urlPath,
type: "text/css" }
));
Chúng ta có thể chèn thẻ kiểu vào iframe. Đăng cũng ở đây ...
<style type="text/css" id="cssID">
.className
{
background-color: red;
}
</style>
<iframe id="iFrameID"></iframe>
<script type="text/javascript">
$(function () {
$("#iFrameID").contents().find("head")[0].appendChild(cssID);
//Or $("#iFrameID").contents().find("head")[0].appendChild($('#cssID')[0]);
});
</script>
var link1 = document.createElement('link');
link1.type = 'text/css';
link1.rel = 'stylesheet';
link1.href = "../../assets/css/normalize.css";
window.frames['richTextField'].document.body.appendChild(link1);
richTextField
ở đây?
Tôi nghĩ cách dễ nhất là thêm một div khác, ở cùng một vị trí với iframe, sau đó
làm cho nó z-index
lớn hơn thùng chứa iframe, vì vậy bạn có thể dễ dàng tạo kiểu cho div của riêng mình. Nếu bạn cần nhấp vào nó, chỉ cần sử dụngpointer-events:none
trên div của riêng bạn, vì vậy iframe sẽ hoạt động trong trường hợp bạn cần nhấp vào nó;)
Tôi hy vọng nó sẽ giúp được ai đó;)
Có một kịch bản tuyệt vời thay thế một nút bằng phiên bản iframe của chính nó. CodePen Demo
Ví dụ sử dụng:
// Single node
var component = document.querySelector('.component');
var iframe = iframify(component);
// Collection of nodes
var components = document.querySelectorAll('.component');
var iframes = Array.prototype.map.call(components, function (component) {
return iframify(component, {});
});
// With options
var component = document.querySelector('.component');
var iframe = iframify(component, {
headExtra: '<style>.component { color: red; }</style>',
metaViewport: '<meta name="viewport" content="width=device-width">'
});
Để thay thế, bạn có thể sử dụng công nghệ CSS-in-JS, như bên dưới lib:
https://github.com/cssobj/cssobj
Nó có thể tiêm đối tượng JS dưới dạng CSS vào iframe, một cách linh hoạt
Đây chỉ là một khái niệm, nhưng đừng thực hiện điều này mà không kiểm tra và lọc bảo mật! Nếu không thì script có thể hack trang web của bạn!
Trả lời: nếu bạn kiểm soát trang đích, bạn có thể thiết lập tập lệnh người nhận như:
1) đặt liên kết iframe với style
tham số, như:
http://your_site.com/target.php?color=red
(cụm từ cuối cùng được a{color:red}
mã hóa theo urlencode
chức năng.
2) đặt trang người nhận target.php
như thế này:
<head>
..........
$col = FILTER_VAR(SANITIZE_STRING, $_GET['color']);
<style>.xyz{color: <?php echo (in_array( $col, ['red','yellow','green'])? $col : "black") ;?> } </style>
..........
Vâng, tôi đã làm theo các bước sau:
iframe
iframe
vàodiv
.divClass { width: 500px; height: 500px; }
divClass iframe { width: 100%; height: 100%; }
Điều này hoạt động trong IE 6. Nên hoạt động trong các trình duyệt khác, hãy kiểm tra!