Mam prostą stronę, która ma kilka sekcji iframe (do wyświetlania linków RSS). Jak mogę zastosować ten sam format CSS ze strony głównej do strony wyświetlanej w ramce iframe?
Mam prostą stronę, która ma kilka sekcji iframe (do wyświetlania linków RSS). Jak mogę zastosować ten sam format CSS ze strony głównej do strony wyświetlanej w ramce iframe?
Odpowiedzi:
Edycja: To nie działa między domenami, chyba że ustawiony jest odpowiedni nagłówek CORS .
Istnieją tutaj dwie różne rzeczy: styl bloku iframe i styl strony osadzonej w iframe. Możesz ustawić styl bloku iframe w zwykły sposób:
<iframe name="iframe1" id="iframe1" src="empty.htm"
frameborder="0" border="0" cellspacing="0"
style="border-style: none;width: 100%; height: 120px;"></iframe>
Styl strony osadzonej w elemencie iframe należy ustawić, umieszczając go na stronie podrzędnej:
<link type="text/css" rel="Stylesheet" href="Style/simple.css" />
Lub można go załadować ze strony nadrzędnej za pomocą 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
. Osadzanie css nadal nie działa dla mnie.
...document.head.appendChild(cssLink)
- Firefox i Safari.
Ten problem spotkałem w Kalendarzu Google . Chciałem nadać mu styl na ciemniejszym tle i zmienić czcionkę.
Na szczęście adres URL z kodu do osadzenia nie miał ograniczeń bezpośredniego dostępu, więc przy użyciu funkcji PHP file_get_contents
można uzyskać całą zawartość ze strony. Zamiast wywoływać adres URL Google, można wywołać plik php znajdujący się na serwerze, np. google.php
, który będzie zawierał oryginalną treść z modyfikacjami:
$content = file_get_contents('https://www.google.com/calendar/embed?src=%23contacts%40group.v.calendar.google.com&ctz=America/Montreal');
Dodawanie ścieżki do arkusza stylów:
$content = str_replace('</head>','<link rel="stylesheet" href="http://www.yourwebsiteurl.com/google.css" /></head>', $content);
(Spowoduje to umieszczenie arkusza stylów na końcu tuż przed head
tagiem końcowym).
Podaj podstawowy adres URL z oryginalnego adresu URL, jeśli css i js są nazywane względnie:
$content = str_replace('</title>','</title><base href="https://www.google.com/calendar/" />', $content);
Ostateczny google.php
plik powinien wyglądać następująco:
<?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;
Następnie zmieniasz iframe
kod do umieszczenia na:
<iframe src="http://www.yourwebsiteurl.com/google.php" style="border: 0" width="800" height="600" frameborder="0" scrolling="no"></iframe>
Powodzenia!
Jeśli zawartość iframe nie jest całkowicie pod twoją kontrolą lub chcesz uzyskać dostęp do zawartości z różnych stron w różnych stylach, możesz spróbować manipulować nią za pomocą 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);
Pamiętaj, że w zależności od używanej przeglądarki może to działać tylko na stronach obsługiwanych z tej samej domeny.
<iframe onload="this.contentDocument.body.style.overflow='hidden';" />
var $head = $("#eFormIFrame").contents().find("head");
$head.append($("<link/>", {
rel: "stylesheet",
href: url,
type: "text/css"
}));
Ramka iframe jest obsługiwana przez większość przeglądarek jak inna strona HTML. Jeśli chcesz zastosować ten sam arkusz stylów do treści ramki iframe, po prostu odwołaj się do niej na stronach tam używanych.
Oto jak zastosować kod CSS bezpośrednio, bez <link>
konieczności ładowania dodatkowego arkusza stylów.
var head = jQuery("#iframe").contents().find("head");
var css = '<style type="text/css">' +
'#banner{display:none}; ' +
'</style>';
jQuery(head).append(css);
Ukrywa to baner na stronie iframe. Dziękuję za sugestie!
iframe
?
#iframe
z #<id>
lub nawet iframe
, aby zaznaczyć wszystkie iframe
s
Jeśli kontrolujesz stronę w ramce iframe, jak to powiedziano, najłatwiejszym sposobem jest utworzenie udostępnionego pliku CSS o wspólnych stylach, a następnie po prostu link do niego ze stron HTML.
W przeciwnym razie jest mało prawdopodobne, że będziesz w stanie dynamicznie zmieniać styl strony ze strony zewnętrznej w swoim ramce iframe. Wynika to z faktu, że przeglądarki zaostrzyły zabezpieczenia skryptów między ramkami z powodu możliwego niewłaściwego użycia do fałszowania i innych włamań.
Ten samouczek może dostarczyć więcej informacji na temat skryptu iframe w ogóle. Informacje o skryptach między ramkami wyjaśniają ograniczenia bezpieczeństwa z perspektywy IE.
Powyższe z niewielką zmianą działa:
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);
Działa dobrze z ff3 i ie8 co najmniej
dynamic data
Jeśli chcesz ponownie użyć CSS i JavaScript ze strony głównej, może powinieneś rozważyć zastąpienie <IFRAME>
treści załadowanej Ajax. Jest to bardziej przyjazne SEO teraz, gdy boty wyszukiwania mogą wykonywać JavaScript.
To jest przykład jQuery, który zawiera inną stronę HTML w twoim dokumencie. Jest to o wiele bardziej przyjazne SEO niż iframe
. Aby mieć pewność, że boty nie indeksują dołączonej strony, po prostu dodaj ją, aby zabronićrobots.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>
Możesz także dołączyć jQuery bezpośrednio z Google: http://code.google.com/apis/ajaxlibs/documentation/ - oznacza to opcjonalne automatyczne dołączanie nowszych wersji i znaczny wzrost prędkości. Oznacza to również, że musisz im zaufać, że dostarczył ci tylko jQuery;)
Poniższe działało dla mnie.
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
Rozszerzenie powyższego rozwiązania jQuery, aby poradzić sobie z opóźnieniami w ładowaniu zawartości ramki.
$('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();
});
Moja wersja kompaktowa :
<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>
Czasami jednak iframe
nie jest gotowy na załadowane okno, więc konieczne jest użycie timera .
Gotowy do użycia kod (z timerem):
<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>
... i link jQuery:
<script src="https://ajax.aspnetcdn.com/ajax/jQuery/jquery-1.9.1.min.js" type="text/javascript"></script>
Inne odpowiedzi tutaj wykorzystują łącza jQuery i CSS.
Ten kod używa waniliowego JavaScript. Tworzy nowy <style>
element. Ustawia zawartość tekstową tego elementu jako ciąg znaków zawierający nowy CSS. I dołącza ten element bezpośrednio do głowy dokumentu 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);
Kiedy powiesz „doc.open ()”, oznacza to, że możesz napisać dowolny tag HTML wewnątrz iframe, więc powinieneś napisać wszystkie podstawowe tagi dla strony HTML, a jeśli chcesz mieć link CSS w głowie iframe, po prostu napisz iframe z linkiem CSS. Dam ci przykład:
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();
użyj może spróbować tego:
$('iframe').load( function() {
$('iframe').contents().find("head")
.append($("<style type='text/css'> .my-class{display:none;} </style>"));
});
W ten sposób nie będziesz mógł stylizować zawartości iframe. Moją sugestią byłoby użycie skryptów na serwerze (PHP, ASP lub skrypt Perla) lub znalezienie usługi online, która przekonwertuje kanał na kod JavaScript. Jedynym innym sposobem, aby to zrobić, jest wykonanie włączenia serwera.
Jeśli masz dostęp do strony iframe i chcesz zastosować inny CSS tylko wtedy, gdy załadujesz ją za pomocą iframe na swojej stronie, tutaj znalazłem rozwiązanie dla tego rodzaju rzeczy
działa to nawet wtedy, gdy iframe ładuje inną domenę
sprawdź o postMessage()
plan jest, wyślij css do iframe jako wiadomość typu
iframenode.postMessage('h2{color:red;}','*');
*
jest wysłanie tej wiadomości bez względu na domenę w ramce iframe
i odbierać wiadomość w ramce iframe i dodawać otrzymaną wiadomość (CSS) do tego nagłówka dokumentu.
kod do dodania na stronie iframe
window.addEventListener('message',function(e){
if(e.data == 'send_user_details')
document.head.appendChild('<style>'+e.data+'</style>');
});
Ponieważ wiele odpowiedzi jest napisanych dla tych samych domen, napiszę, jak to zrobić w wielu domenach.
Najpierw musisz znać API Post Message . Potrzebujemy komunikatora do komunikacji między dwoma oknami.
Oto posłaniec, którego stworzyłem.
/**
* 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);
}
}
Wykorzystanie tego w dwóch oknach do komunikacji może rozwiązać Twój problem.
W głównych oknach
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
})
Następnie otrzymaj zdarzenie z iframe.
W ramce iframe:
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);
}
})
Aby uzyskać więcej informacji, zobacz Kompletny samouczek Javascript i iframes .
Znalazłem inne rozwiązanie, aby umieścić styl w głównym html w ten sposób
<style id="iframestyle">
html {
color: white;
background: black;
}
</style>
<style>
html {
color: initial;
background: initial;
}
iframe {
border: none;
}
</style>
a następnie zrób to w iframe (zobacz onloads js)
<iframe onload="iframe.document.head.appendChild(ifstyle)" name="log" src="/upgrading.log"></iframe>
i w js
<script>
ifstyle = document.getElementById('iframestyle')
iframe = top.frames["log"];
</script>
To może nie być najlepsze rozwiązanie i na pewno można je ulepszyć, ale jest to kolejna opcja, jeśli chcesz zachować znacznik „style” w oknie nadrzędnym
W domenie są dwie rzeczy
Więc chcesz stylizować te dwie sekcje w następujący sposób,
1. Styl sekcji iFrame
Może stylizować za pomocą CSS o tym szacunku id
lub class
nazwie. Możesz po prostu stylizować go również w nadrzędnych arkuszach stylów.
<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. Styl strony ładowanej w ramce iFrame
Te style można załadować ze strony nadrzędnej za pomocą Javascript
var cssFile = document.createElement("link")
cssFile.rel = "stylesheet";
cssFile.type = "text/css";
cssFile.href = "iFramePage.css";
następnie ustaw ten plik CSS na odpowiednią sekcję iFrame
//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);
Tutaj możesz edytować Główną część strony wewnątrz iFrame, również w ten sposób
var $iFrameHead = $("#my_iFrame").contents().find("head");
$iFrameHead.append(
$("<link/>",{
rel: "stylesheet",
href: urlPath,
type: "text/css" }
));
Możemy wstawić znacznik stylu do iframe. Wysłano również tutaj ...
<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
tu jest ?
Myślę, że najprościej jest dodać kolejny div, w tym samym miejscu co iframe
uczyń go z-index
większym niż kontener iframe, abyś mógł łatwo zaprojektować własny div. Jeśli chcesz go kliknąć, po prostu użyjpointer-events:none
własnego diva, aby iframe działał na wypadek, gdybyś musiał go kliknąć;)
Mam nadzieję, że to komuś pomoże;)
Jest wspaniały skrypt, który zastępuje węzeł samą wersją iframe. CodePen Demo
Przykłady użycia:
// 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">'
});
Alternatywnie możesz użyć technologii CSS-in-JS, jak poniżej lib:
https://github.com/cssobj/cssobj
Może dynamicznie wstrzykiwać obiekt JS jako CSS do iframe
To tylko koncepcja, ale nie wdrażaj jej bez kontroli bezpieczeństwa i filtrowania! W przeciwnym razie skrypt może włamać się do Twojej witryny!
Odpowiedź: jeśli kontrolujesz witrynę docelową, możesz skonfigurować skrypt odbiorcy w następujący sposób:
1) ustaw link iframe za pomocą style
parametru, na przykład:
http://your_site.com/target.php?color=red
(ostatnia fraza jest a{color:red}
kodowana przez urlencode
funkcję.
2) ustaw stronę odbiorcy w target.php
następujący sposób:
<head>
..........
$col = FILTER_VAR(SANITIZE_STRING, $_GET['color']);
<style>.xyz{color: <?php echo (in_array( $col, ['red','yellow','green'])? $col : "black") ;?> } </style>
..........
Cóż, wykonałem następujące kroki:
iframe
iframe
do div
.divClass { width: 500px; height: 500px; }
divClass iframe { width: 100%; height: 100%; }
Działa to w IE 6. Powinien działać w innych przeglądarkach, sprawdź!