2013-04-24 15 views
22

This link (archived version) opisuje sposób wstrzyknąć kod skryptu w iframe:wstrzyknąć funkcji javascript w iframe

function injectJS() { 
    var iFrameHead = window.frames["myiframe"].document.getElementsByTagName("head")[0]; 
    var myscript = document.createElement('script'); 
    myscript.type = 'text/javascript'; 
    myscript.src = 'myscript.js'; // replace this with your SCRIPT 
    iFrameHead.appendChild(myscript); 
} 

to jest OK, ale co, jeśli chcę wstawić obiekt funkcyjny w iframe i wykonać go w kontekście iframe? Powiedzmy, że mam:

function foo() { 
    console.log ("Look at me, executed inside an iframe!", window); 
} 

i chcę wstawić kod foo wewnątrz elementu iframe? (funkcja foo może być coś ładowane dynamicznie, nie mogę po prostu owinąć go w cudzysłowie)

ja naiwnie próbowałem:

var scriptFooString = "<script>" + foo.toString() + "</script>"

celu uzyskania kodu wewnątrz funkcji, ale

  • Nie wiem, jak wstawić go w iframe HEAD (może z jquery?)
  • Nie wiem, czy to jest właściwy sposób
  • Nie wiem co się dzieje, kiedy, jeśli funkcja ta jest o wiele bardziej skomplikowane niż
  • Nie wiem co się dzieje z podwójne i pojedyncze cudzysłowy w scriptFooString

Każda podpowiedź?

Odpowiedz

22

Przede wszystkim można to osiągnąć tylko wtedy, gdy rama i strona wyświetla to jest w tej samej domenie (Ze względu na zasady wzajemnej domen)

drugie można manipulować DOM i okien obiektów ramie bezpośrednio przez JS:

frames[0].window.foo = function(){ 
    console.log ("Look at me, executed inside an iframe!", window); 
} 

zdobycia ramkę z DOMElement obiektu można użyć:

var myFrame = document.getElementById('myFrame'); 

myFrame.contentWindow.foo = function(){ 
     console.log ("Look at me, executed inside an iframe!"); 
} 

Należy pamiętać, że zakres w foo nie ulega zmianie, więc okno nadal jest nadrzędnym oknem itp. wewnątrz foo.

Jeśli chcesz wprowadzić jakiś kod, który musi być prowadzony w ramach drugiej ramce można wstrzykiwać tag skryptu lub eval go:

frames[0].window.eval('function foo(){ console.log("Im in a frame",window); }'); 

Choć ogólny konsensus jest, aby nigdy nie używać eval , Myślę, że jest to lepsza alternatywa niż zastrzyk DOM, jeśli NAPRAWDĘ potrzebujesz tego dokonać.

więc w konkretnym przypadku można zrobić coś takiego:

frames[0].window.eval(foo.toString()); 
+0

Ok, ale jeśli wykonanie funkcji z okna nadrzędnego z 'klatek [0]. window.foo(); ', jest wykonywane w kontekście okna nadrzędnego. Włożenie go w głowę sprawiłoby, że zostałoby wykonane z kontekstem iframe, czy jestem w błędzie? (patrz http://jsfiddle.net/7rEXT/) – janesconference

+0

Problem nie jest kontekstem, ale zakresem. Kiedy tworzysz funkcję foo, robisz to w ramach obecnego zakresu, wierzę, więc okno jest rodzajem okna, a nie ramek itp. Nadal musisz użyć 'myFrame.contentWindow' lub' frames [0] .window' inside funkcja dostępu do właściwego zakresu. Jeśli chcesz wstrzyknąć znacznik skryptu, możesz dołączyć go przez DOM. – EJTH

+0

Zaktualizowałem moją odpowiedź, aby lepiej pasowało do Twojego zapytania. Chociaż muszę powiedzieć, że jeśli chcesz coś takiego zrobić, istnieje duże prawdopodobieństwo, że komplikujesz rzeczy i robisz to źle, lub robisz to mądrzej. – EJTH

1

Oto moje rozwiązanie. Używam jquery wstawić zawartość, a następnie za pomocą eval wykonać znaczniki skryptów w kontekście tego iframe:

var content = $($.parseHTML(source, document, true)); 
    $("#content").contents().find("html").html(content); 
    var cw = document.getElementById("content").contentWindow; 
    [].forEach.call(cw.document.querySelectorAll("script"), function (el, idx) { 
     cw.eval(el.textContent); 
    }); 
Powiązane problemy