Zastąp styl treści dla treści w elemencie iframe

165

Jak mogę kontrolować obraz tła i kolor elementu body w elemencie iframe? Zauważ, że osadzony element body ma klasę, a iframejest strony, która jest częścią mojej witryny.

Potrzebuję tego, ponieważ moja witryna ma czarne tło przypisane do treści, a następnie białe tło przypisane do elementów div zawierających tekst. Edytor WYSIWYG używa znaku iframedo osadzania treści podczas edycji, ale nie zawiera elementu div, więc tekst jest bardzo trudny do odczytania.

Treść iframewhen w edytorze ma klasę, która nie jest używana nigdzie indziej, więc zakładam, że została tam umieszczona, aby można było rozwiązać takie problemy. Jednak kiedy stosuję style class.body, nie zastępują one stylów zastosowanych do ciała. Dziwne jest to, że style pojawiają się w Firebug, więc nie mam pojęcia, co się dzieje!

Dzięki

UPDATE - wypróbowałem rozwiązanie @ mikeq polegające na dodaniu stylu do klasy, która jest klasą ciała. To nie działa po dodaniu do arkusza stylów strony głównej, ale działa po dodaniu z Firebug. Zakładam, że dzieje się tak, ponieważ Firebug jest stosowany do wszystkich elementów na stronie, podczas gdy CSS nie jest stosowany w ramkach iframe. Czy to oznacza, że ​​dodanie css po załadowaniu okna z JavaScriptem zadziała?

jd6699
źródło
1
Możliwy duplikat Jak zastosować CSS do iframe?
2540625
Chociaż nie jest możliwe dotknięcie czegokolwiek w ramce iframe, załadowanie tego adresu URL przez Ajax do a <div>może czasami być obejściem (jeśli dany nagłówek CORS na to pozwala) ... (i „oczyszczanie” załadowanych danych za pomocą wyrażenia regularnego w Tak, wszystko hacky ...)
Frank Nocke
Możesz użyć javascript, jeśli domeny strony są zgodne, ale dlaczego nie po prostu umieścić bloku stylu w kodzie HTML swojej strony wewnętrznej, aby zastąpić kolory, które chcesz zmienić? Po prostu dodaj więcej selektorów w swoim override lub użyj ważnych! jeśli wszystko inne zawiedzie, zastąp wszelkie style kolorów, które chcesz, tylko na tej jednej stronie ...
OG Sean

Odpowiedzi:

112

Element iframe to „dziura” na stronie, w której jest wyświetlana inna strona internetowa. Zawartość elementu iframe nie ma żadnego kształtu ani nie stanowi części strony nadrzędnej.

Jak powiedzieli inni, dostępne opcje to:

  • nadaj plikowi ładowanemu do elementu iframe niezbędny kod CSS
  • jeśli plik w elemencie iframe pochodzi z tej samej domeny co Twój element nadrzędny, możesz uzyskać dostęp do DOM dokumentu w elemencie iframe z elementu nadrzędnego.
DA.
źródło
251

Poniższe działa tylko wtedy, gdy zawartość iframe pochodzi z tej samej domeny nadrzędnej.

U mnie działa następujący skrypt jquery. Przetestowano w Chrome i IE8. Wewnętrzna ramka iframe odwołuje się do strony znajdującej się w tej samej domenie co strona nadrzędna.

W tym konkretnym przypadku ukrywam element z określoną klasą w wewnętrznym iframe.

Po prostu dodajesz element „style” do „głowy” wewnętrznej ramki iframe.

$('iframe').load( function() {
    $('iframe').contents().find("head")
      .append($("<style type='text/css'>  .my-class{display:none;}  </style>"));
});
SimpleSam5
źródło
4
@ SimpleSam5 Czy możesz zapewnić alternatywę dla Javascript (bez używania Jquery)?
Kamalakannan J
1
@sincerekamal Oto kod bez potrzeby jQuery: jsfiddle.net/9g9wkpon Wystarczy wiedzieć, że dzielone właściwości CSS są zapisywane w camelCase w JavaScript, jak w moim przykładzie. :)
Dennis98,
2
jquery.js? ver = 1.12.4: 2 Uncaught DOMException: nie można odczytać właściwości „contentDocument” z „HTMLIFrameElement”: zablokowano ramce o źródle „ xxxxxxxxx.com ” dostęp do ramki pochodzącej z innych źródeł.
Alex Stanese,
2
@AlexStanese, jak twierdzi jeremy, działa to tylko wtedy, gdy strona iframe pochodzi z tego samego serwera co strona nadrzędna ... co zazwyczaj oznacza, że ​​i tak nie musisz zawracać sobie głowy javascriptem ... po prostu dodaj CSS do drugiej strony na pierwszym miejscu.
DA.
@KamalakannanJ nie musisz nawet używać Javascript. Po prostu edytuj stronę, która jest w iFrame i umieść tam CSS.
DA.
25

Nie możesz zmienić stylu strony wyświetlanej w elemencie iframe, chyba że masz bezpośredni dostęp, a zatem jesteś właścicielem źródłowych plików html i / lub css.

Ma to na celu zatrzymanie XSS (Cross Site Scripting)

Myles Gray
źródło
Co rozumiesz przez „bezpośredni dostęp”? Strona w elemencie iframe pochodzi z mojej witryny, to cała jedna domena.
jd6699
2
Cóż, będziesz musiał zmienić plik źródłowy w swojej witrynie (nie możesz modyfikować żadnej zawartości w ramce iframe) - więc jeśli ramka iframe wskazuje na mysite.com/test.html, musisz bezpośrednio zmodyfikować test.html. ,
Myles Grey
1
Nie mogę? Pod warunkiem, że OP mówi, że możesz. Na przykład jego wewnętrzny adres URL elementu iframe jest taki sam, jak jego witryna nadrzędna, więc powinien mieć dostęp do DOM ok za pomocą dowolnego kodu javascript, który lubisz ...
OG Sean
@Myles Gray Wrong. Możesz modyfikować zawartość elementu iframe z jego strony nadrzędnej, jeśli znajduje się w tej samej domenie, zarówno za pomocą JavaScript, jak i CSS.
Kevin M
8

An iframema inny zakres, więc nie możesz uzyskać do niego dostępu do stylu lub zmiany jego zawartości za pomocą javascript.

Zasadniczo jest to „inna strona”.

Jedyne, co możesz zrobić, to edytować własny CSS, ponieważ z globalnym CSS nie możesz nic zrobić.

Alessandro Vendruscolo
źródło
Tak, możesz, z javascript. Zauważ, że działa najlepiej z adresem URL elementu iframe i nadrzędnym adresem URL w tej samej domenie. Ale myślę, że masz rację wskazując, że można to zrobić za pomocą CSS na stronie wewnątrz elementu iframe.
OG Sean
8

Zastąp kod CSS innej domeny iframe

Korzystając z części odpowiedzi SimpleSam5 , osiągnąłem to dzięki kilku elementom iframe czatu Tawk (ich interfejs dostosowywania jest w porządku, ale potrzebowałem dalszych dostosowań).

W tym konkretnym elemencie iframe, który pojawia się na urządzeniach mobilnych, musiałem ukryć domyślną ikonę i umieścić jeden z moich obrazów tła. Zrobiłem co następuje:

Tawk_API.onLoad = function() {
// without a specific API, you may try a similar load function
// perhaps with a setTimeout to ensure the iframe's content is fully loaded
  $('#mtawkchat-minified-iframe-element').
    contents().find("head").append(
     $("<style type='text/css'>"+
       "#tawkchat-status-text-container {"+
         "background: url(https://example.net/img/my_mobile_bg.png) no-repeat center center blue;"+
         "background-size: 100%;"+
       "} "+
       "#tawkchat-status-icon {display:none} </style>")
   );
};

Nie posiadam żadnej domeny Tawk i to zadziałało dla mnie, więc możesz to zrobić, nawet jeśli nie pochodzi z tej samej domeny nadrzędnej (pomimo komentarza Jeremy'ego Beckera na temat odpowiedzi Sama).

CPHPython
źródło
18
Podejrzewam, że to działa tylko dlatego, że ludzie w Tawk wyraźnie na to zezwolili.
Prawnik
@CPHPython Może możesz mi pomóc. Spójrz na to: stackoverflow.com/questions/60923168/…
Success Man
7

Ten kod wykorzystuje zwykły 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 nagłówka dokumentu iframe.

var iframe = document.getElementById('the-iframe');
var style = document.createElement('style');
style.textContent =
  'body {' +
  '  background-color: some-color;' +
  '  background-image: some-image;' +
  '}' 
;
iframe.contentDocument.head.appendChild(style);
2540625
źródło
7
Blocked a frame with origin xxxxxxxxx from accessing a cross-origin frame.Obawiam się, że to nie zadziała
Mike
1

Jeśli masz kontrolę nad stroną hostującą element iframe i stroną elementu iframe, możesz przekazać parametr zapytania do elementu iframe ...

Oto przykład dodawania klasy do elementu iframe na podstawie tego, czy witryna hostingowa jest mobilna ...

Dodawanie iFrame:

var isMobile=$("mobile").length; //detect if page is mobile
var iFrameUrl ="https://myiframesite/?isMobile=" + isMobile; 

$(body).append("<div id='wrapper'><iframe src=''></iframe></div>");
$("#wrapper iframe").attr("src", iFrameUrl ); 

Wewnątrz elementu iFrame:

//add mobile class if needed
var url = new URL(window.location.href);
var isMobile = url.searchParams.get("isMobile");
if(isMobile == "1") {
    $("body").addClass("mobile");
}
Ben
źródło
Może ty możesz mi pomóc. Spójrz na to: stackoverflow.com/questions/60923168/…
Success Man
0

Prowadzę bloga i miałem wiele problemów ze znalezieniem sposobu zmiany rozmiaru osadzonej treści. Menedżer postów pozwala tylko na pisanie tekstu, umieszczanie obrazów i osadzanie kodu HTML. Układ bloga sam w sobie jest responsywny. Jest zbudowany za pomocą Wix. Jednak osadzony HTML nie jest. Dużo czytałem o tym, jak niemożliwa jest zmiana rozmiaru komponentów wewnątrz treści generowanych ramek iFrame. Oto moja sugestia:

Jeśli masz tylko jeden komponent w swoim elemencie iFrame, tj. Swoją treść, możesz zmienić rozmiar tylko sedna. Zapomnij o iFrame.

Miałem problemy z widocznym obszarem, specyficznymi układami dla różnych programów użytkownika i to rozwiązało mój problem:

<script language="javascript" type="text/javascript" src="https://gist.github.com/roliveiravictor/447f994a82238247f83919e75e391c6f.js"></script>

<script language="javascript" type="text/javascript">

function windowSize() {
  let gist = document.querySelector('#gist92442763');

  let isMobile = {
    Android: function() {
        return /Android/i.test(navigator.userAgent)
    },
    BlackBerry: function() {
        return /BlackBerry/i.test(navigator.userAgent)
    },
    iOS: function() {
        return /iPhone|iPod/i.test(navigator.userAgent)
    },
    Opera: function() {
        return /Opera Mini/i.test(navigator.userAgent)
    },
    Windows: function() {
        return /IEMobile/i.test(navigator.userAgent) || /WPDesktop/i.test(navigator.userAgent)
    },
    any: function() {
        return (isMobile.Android() || isMobile.BlackBerry() || isMobile.iOS() || isMobile.Opera() || isMobile.Windows());
    }
};

  if(isMobile.any()) {
    gist.style.width = "36%";
    gist.style.WebkitOverflowScrolling = "touch"
    gist.style.position = "absolute"
  } else {
    gist.style.width = "auto !important";
  }
}

windowSize();

window.addEventListener('onresize', function() {
    windowSize();
});

</script>

<style type="text/css">

.gist-data {
  max-height: 300px;
}

.gist-meta {
  display: none;
}

</style>

Logika polega na ustawieniu gist (lub twojego komponentu) css na podstawie agenta użytkownika. Upewnij się, że najpierw zidentyfikowałeś swój komponent, zanim zastosujesz go do selektora zapytania. Zapraszam do obejrzenia, jak działa responsywność .

Victor R. Oliveira
źródło
-3

Być może teraz się to zmieniło, ale użyłem osobnego arkusza stylów z tym elementem:

.feedEkList iframe
{
max-width: 435px!important;
width: 435px!important;
height: 320px!important;
}

aby z powodzeniem stylizować osadzone elementy iframe youtube ... zobacz posty na blogu na tej stronie .

Tim Jackson
źródło
4
Chociaż ten link może odpowiedzieć na pytanie, lepiej jest zawrzeć tutaj zasadnicze części odpowiedzi i podać link do odniesienia. Odpowiedzi zawierające tylko łącze mogą stać się nieprawidłowe, jeśli połączona strona ulegnie zmianie.
Shaiful Islam
4
Dotyczy to tylko samego elementu iFrame - pytanie dotyczy konkretnie zawartości iFrame, której obecnie nie można zmienić za pomocą samego CSS.
pwdst
@ShaifulIslam, czyli dokładnie to, co się wydarzyło. Rending Tims odpowiada bezcelowo.
Alex Foxleigh,
-24

nadaj treści swojej strony iframe identyfikator (lub klasę, jeśli chcesz)

<html>
<head></head>
<body id="myId">
</body>
</html>

następnie, również na stronie elementu iframe, przypisz mu tło w CSS

#myId {
    background-color: white;
}
mikeq
źródło
To jest dziwne. Twoje rozwiązanie działa dla mnie, gdy dodam je do strony za pomocą firebuga, ale nie działa, jeśli znajduje się w normalnym pliku css strony. Czy to może być część Twojego komentarza „zakładając, że strona w elemencie iFrame jest Twoja do edycji”? Nie rozumiem, co przez to rozumiesz. Dzięki
jd6699,
Mam na myśli to, czy strona, którą ładujesz do iFrame z Twojej witryny i jest pod Twoją kontrolą? czy też pochodzi z zewnętrznej witryny, której nie można edytować źródła w celu uwzględnienia tego identyfikatora / klasy.
mikeq
Pochodzi z mojej witryny, ale ponieważ jest to zrobione przez redaktora, nie będzie łatwo zmienić przeciągniętego znacznika.
jd6699
ps Nie chodziło mi o dodanie id = "myId" do twojej strony głównej, ale do strony wewnątrz iFrame. W ten sposób możesz skierować treść strony iFrame z innym stylem niż strona główna. Odwołujesz się również do pliku CSS na swoich stronach iFrame, też nie jesteś. Musisz traktować stronę załadowaną do iFrame jako całkowicie niezależną stronę. Jeśli załadujesz tylko tę stronę do przeglądarki internetowej, czy ma ona właściwy styl?
mikeq
Właściwie nie jestem pewien, gdzie znajduje się „strona”, ponieważ nie jest to cała strona używana przez redaktora. Dzięki za pomoc, myślę, że rozumiem, jak to wszystko działa, noe.
jd6699