2012-04-08 5 views
7

Jeśli uruchomię poniższy kod, znaczniki body i head zostaną usunięte.Dlaczego jQuery usuwa znaczniki body i head przy wypełnianiu elementu iframe tagiem stylu, ale nie bez?

<iframe src='blank.htm'> 
    <html> 
    <head> 
     <style type="text/css"> 

     </style> 
    </head> 
    <body> 
     test 
    </body> 
    </html> 
</iframe> 
<script> 
    $('iframe').load(function() { 
     var contents = $('iframe').text(); 
     $('iframe').contents().find('html').html(contents); 
    }); 
</script> 

Jeśli następnie usunę znaczniki stylu, wszystko pojawi się poprawnie. Dlaczego tak jest i jak mogę go powstrzymać przed usunięciem znaczników głowy i ciała? Chcę, aby zawartość była zapełniana bez żadnych manipulacji.

+0

Dlaczego to robisz? Czy możesz rozwinąć? Szybka reakcja na kolano, która przychodzi na myśl, brzmi: "Nie rób tego", ale podejrzewam, że istnieje powód, dla którego robisz to, czego nam nie mówisz? :) Myślę, że możemy pomóc, jeśli powiesz nam, jaki jest twój cel. Powodzenia! – jmort253

+0

Tworzę piaskownicę, która pozwoli mi poprawnie wyświetlić szablon html dla użytkownika końcowego. Pomyśl o wyświetleniu podglądu wiadomości e-mail, w której musisz sprawdzić, jaki jest końcowy wynik w innym oknie internetowym. Bez piaskownicy można by narzucać inne style i formaty, które nie są częścią treści wiadomości, a także odwrotnie. Ten kod pozwala mi wypełnić element iframe, gdy pojawi się na stronie, nie wpływając na resztę kodu ani na samą stronę. – Middletone

+0

To jest okienko podglądu, więc treść nie musi znajdować się nigdzie indziej, ponieważ tak jest, dlatego nie jestem po prostu ładowanie innej strony z informacji. – Middletone

Odpowiedz

3

Oto kroki, które można wykonać, aby dowiedzieć się, jak skopiować zawartość elementu iframe do ciągu, zmodyfikować go i zastąpić w elemencie iframe. Te kroki mają być wykonane w Chrome Debuggerze i służą wyłącznie do celów edukacyjnych/demonstracyjnych. Gdy zrozumiesz proces, możesz spróbować replikować w swoim kodzie w swojej witrynie.

Run każda funkcja jeden naraz Chrome Debugger:

// test iframe I loaded in a sandbox also at http://example.com 
$('body div:first').before('<iframe src="http://example.com/company"></iframe>'); 

// retrieved the body of the iframe - I cloned it so I could perform operations 
    // on the copy without bothering the iframe content. 
iBody = $('iframe:first').contents().find('body').clone(); 

// got the head 
iHead = $('iframe:first').contents().find('head').html(); 

// if there is script in the body, it really messes things up. So in my tests, 
    // I had to remove it before adding it back to the iframe. 
iBody.find("script").remove(); 

// verify there are no script elements 
ibody.html(); 

// replace the iframe head 
$('iframe:first').contents().find('head').html(iHead); 

// replace the iframe body first with a placeholder. The body is the sensitive 
    // part. If you destroy the DOM, it can make the entire page, including 
    // the parent, turn completely white. 
$('iframe:first').contents().find('body').html('<div></div>'); 

// ** inserted something in the copy to prove we modified it!! 
iBody.append("<div style='position:absolute;z-index:5000; color:red; " + 
    "background-color:white;'>JAMES WAS HERE</div>"); 

// now replace the body 
$('iframe:first').contents().find('body').html(iBody); 

W dolnej części strony, wewnątrz iframe, widziałem moją wiadomość w kolorze czerwonym na białym tle. Mogłem też zobaczyć go w źródle:

$('iframe:first').contents().find('body').html(); 

wykonałem te czynności na anonimowej stronie internetowej, za pomocą konsoli Debugger Chrome do uruchamiania poleceń. Pierwsze polecenie tworzy element iframe na stronie głównej ze stroną firmy witryny w elemencie iframe. Pozostałe polecenia pobierają główkę i ciało tego elementu iframe, klonują ciało, dodają pewne elementy, takie jak wiadomość "JAMES BYŁ TUTAJ", do klonu ciała, a następnie zastępują ciało iframe tą kopią.

Sprawdziłem również te same wyniki, ładując http://getsatisfaction.com w przeglądarce i ładując http://getsatisfaction.com/explore/product-innovation w elemencie iframe. Powtarzając powyższe kroki, widziałem moje przesłanie "JAMES BYŁ TUTAJ".

** Najgroźniejszym problemem, jaki napotkałem, nie było pozostawienie tagów stylu JavaScript lub CSS w kopii. Rozwiązaniem stylizacji jest zmodyfikowanie wszystkich modyfikacji stylu przed dodaniem obiektu z powrotem do elementu iframe. **

Z jakiegoś powodu przeglądarka próbowała uruchomić JavaScript i wygenerowała błędy. Kontekst tych błędów spowodował, że sądzę, że JavaScript był uruchamiany w kontekście tronowym, a nie w kontekście iframe! To może być dla ciebie showstopper. Być może trzeba będzie wymyślić inny plan pokazujący podglądy w wyskakującym oknie lub w linii. Może to również zachowywać się inaczej na różnych stronach internetowych z różnymi JavaScript. Może również dziwnie zachowywać się w IE.

Podsumowując, nie widzę takiego rozwiązania, które byłoby wsparciem dla strony produkcyjnej, ponieważ JavaScript musi zostać usunięty w elemencie iframe; jednak, w zależności od twoich potrzeb, może być możliwe wykonanie tej pracy w produkcji, jeśli nie potrzebujesz elementu iframe DOM, aby używać dowolnego skryptu JavaScript.

Niemniej jednak, był to interesujący problem do odkrycia!

16

miałem ten sam problem i wyciągnięte z this SO question że w rzeczywistości jest to, że przeglądarka nie stripowaniu, jako część jego parsowania nieruchomości innerHTML, która jest co jQuery używa wewnętrznie w .html().

Problem polega raczej na tym, że jQuery używa pośredniego nowego DIV, który, moim zdaniem, nie może zawierać pewnych znaczników, co skutkuje usunięciem.

Do rozwiązania, a następnie. To tak proste, jak ustawienie właściwości elementu htmlinnerHTML bezpośrednio, tak jak poniżej:

// This forcibly removes head, body, and other tags, since it internally uses an empty DIV and its innerHTML property 
jQuery(targetElement).html(exitHtml); 

// This works fine 
h = document.getElementsByTagName('html')[0]; 
h.innerHTML = htmlString; 

dla konkretnego przypadku, po prostu kierować element htmlwewnątrziframe. Twój ostateczny kod może być:

<script> 
    $('iframe').load(function() { 
     var contents = $('iframe').text(); 
     iframeHtml = $('iframe').contents().find('html').get(0); 
     iframeHtml.innerHTML = contents; 
    }); 
</script> 
+3

Świetna odpowiedź .. Również drapałem sobie głowę tym ... – idragosalex

+3

@Middletone IMHO to powinna być akceptowana odpowiedź. –

+1

Uzgodnione. To odpowiada na problem, podczas gdy zaakceptowana odpowiedź jest technicznie interesującą podróżą, ale nie jest odpowiedzią. – toxaq

Powiązane problemy