Andrise programmeerimisalane WIKI
IFRAME skriptimine
Siia panen kirja iframe elemendi skriptimisega seotud märkused, mida aegajalt vaja võib minna. iframe on näiteks väga hea variant võõra koodi isoleerimiseks põhilehest. Samuti on sellega realiseeritud enamus WYSIWYG rakendusi (vanemad brauserid ei toeta contentEditable omadust ja seega tuleb terve dokument toimetatavaks muuta).
Stiilid
margin
iframe margininist vabanemiseks tuleb seada atribuutide marginWidth ja marginHeight väärtuseks 0. NB! camel-case on oluline!
iframeElm.setAttribute("marginWidth","0"); iframeElm.setAttribute("marginHeight","0");
äärejoon
Äärejoonest lahtisaamiseks tuleb seada atribuudi frameBorder väärtuseks 0.
iframeElm.setAttribute("frameBorder","0");
kerimisribad
Kerimisribadele saab ligi omadusega scrolling. Väärtuseks võib olla „auto“ (vaikimisi), „yes“, „no“.
var iframeElm = document.getElementById("iframe"); iframeElm.setAttribute("scrolling", "no");
contentWindow
contentWindow on freimi kõige olulisem element ehk selle freimi window objekt. Läbi antud elemendi saab ligi kõigele freimi sisuga seonduvale, sh. näiteks location jms.
contentWindow omaduse saab DOM elemendilt kätte järgnevalt:
var iframeElm = document.getElementById("iframe"), iframeWindow = iframeElm.contentWindow
contentDocument
contentDocument omaduse saab DOM elemendilt kätte järgnevalt:
var iframeElm = document.getElementById("iframe"), doc = iframeElm.contentDocument || iframeElm.contentWindow.document
Vanemad brauserid ei toeta contentDocument omadust ja seega tuleb seda otsida contentWindow omaduse seest.
Tühja iframe tekitamine lehele ja selle sisu täitmine
Tühja iframe jaoks tuleb lehele lisada ilma src parameetrita iframe element. Kui see on olemas saab lisada freimile ise sisu, avades freimi contentDocument omaduse ning kirjutades sinna sisu käsuga write.
var iframeElm = document.createElement("iframe"), iframeDoc = iframeElm.contentDocument || iframeElm.contentWindow.document; document.body.appendChild(iframeElm); iframeDoc.open(); iframeDoc.write('<html><body><p>hello world!</p></body></html>'); iframeDoc.close();
IFRAME suunamine
Kui lehel on iframe element, saab selle location omadusele ligi läbi omaduse contentWindow. Tegu on alati ligipääsetava omadusega, ainult et võõraste domeenide puhul on see write-only, mis tähendab et uut asukohta saab määrata, aga mitte praegust asukohta lugeda.
var iframeElm = document.getElementByid("iframe"), iframeWindow = iframeElm.contentWindow; iframeWindow.location.replace("http//uus.aadress");
location.replace ei jäta brauseri ajalukku märget, seega ei sega aadressi vahetus brauseris hilisemat edasi-tagasi nuppudega navigeerimist.
Teise freimi andmete kasutamine
Teise freimi funktsioonide ja muutujate kasutamiseks (ainult juhul kui tegu on sama domeeni freimidega või kui alamdomeenide puhul on seatud sama document.domain väärtus!) on vaja ligipääsu freimi window objektile. Alamfreimil on seda lihtne teha näiteks läbi parent omaduse. Ülevalt alla aga tuleb kasutada contentWindow omadust.
Skriptid
Põhileht:
function teavitus(tekst){ alert(tekst); }
Alamfreim:
parent.teavitus("abc");
DOM
DOM elementide kopeerimiseks ühest dokumendist teise tuleb kasutada importNode meetodit (sama nagu cloneNode).
var remoteNode = iframeDocument.getElementById("element"), localNode = document.importNode(remoteNode, true); document.body.appendChild(localNode);
Cross domain
Cross-domain suhtlus pole lihtsasti teostatav (cross browser stiilis, nii et igas brauseris töötaks), küll aga saab skript ligi freimile, mis asub sama domeeni teises alamdomeenis, juhul kui mõlevad seavad document.domain väärtuseks domeenide lähima ühisosa, milleks reeglina on põhidomeen.
Põhileht (www.domeen.ee):
document.domain = "domeen.ee";
freim (alamdomeen.domeen.ee):
document.domain = "domeen.ee";
Uuemates brauserites on cross-domain suhtlus võimalik tekstilist infot ühest freimist teise kandva postMessage käsuga. Seda toetavad IE8+, FF3+, Opera 9+, Safari 4+, Chrome. Vanemate brauserite jaoks on võimalik sõnumeid saata näiteks window.location abil, kui saadetavad andmed panna URL'i sisse (kasutatavat URL'i on vaja siiski juba teada), sisestades need sümboli # järele. Näiteks www.neti.ee/#freimile+saadetavad+andmed.
postMessage
Sõnumite saamiseks tuleb seada message sündmuste kuular.
window.addEventListener("message", function(event){ alert("Saabus sõnum "+ event.data); }, false);
Saatmiseks on vaja freimi window elementi, mille pihta saab käivitada meetodi postMessage
parent.postMessage("Saadetav sõnum teksti kujul", "*");
NB! Enne postMessage kasutamist tasub tutvuda lähemalt võimalustega turvalisuse tõstmiseks kuna siin toodud näited on totaalselt ebaturvalised! MDC window.postMessage.
NB! Osade brauserite vanemad versioonid ei toeta event.origin omadust, vaid selle asemel on kasutusel event.domain. Sellisel juhul saab korrektse väärtuse tuletada näiteks nii:
var origin = event.origin || window.location.protocol+'//'+event.domain; if(origin != "http://www.neti.ee")alert("Unknown origin!");
location.hash
Saatmiseks tuleb seada saadetavad andmed freimi URL'i lõppu hash väärtusena. Kasutatav URL peab olema teada, kuna see tuleb samuti iga kord ette anda, ei saa kasutada lihtsat vormi #andmed, vaid http://...ee/#andmed. Kuna aga sama leht on niikuinii freimis juba parasjagu ees ja muutub ainult hash siis brauser uut päringut serverile tegema ei hakka.
iframeWindow.location.replace(iframeUrl + "#" + encoded_message);
Vanematel brauseritel (ehk nendel, kelle jaoks see häkk üldse vajalik on, uuematel on olemas postMessage) puudub onhashchange sündmuse tugi, seega tuleb kuidagi teisit aadressi muutumist jälgida. Näiteks taimeriga.
window.setInterval(function(){ if(String(window.location.hash).length>1){ var encoded_message = String(window.location.hash).substr(1); window.location.replace("#"); alert("incoming message: "+encoded_message); } }, 50);
Kuna IE ei luba kasutada pikemaid URL'e kui 2048 baiti ning kuna andmed peavad olema urlencode'itud, mis teeb algsed andmed veidi pikemaks, ei saa ühe korraga väga suurt mahtu edasi anda. Teistel brauseritel on URL'ide maksimaalsed pikkused megabaitides ja neid see piirang seega ei puuduta.
Üks võimalus sõnumi laekumisest teavitamiseks on kasutada näiteks window.onresize sündmust kui peale URL'i muutmist muuta ka iframe suurust. Nii saab sõnumeid saata veidi tihedamini kui taimeriga võimalik. Vastuvõtja seab window.onresize sündmuse kuulari ning kui see rakendub, kontrollib URL'i sisu.
Märkused
Juhul kui iframe ei ole mõeldud lehel nähtav olema (on näiteks faili üleslaadimise sihtfreim või mingiks cross domain suhtluse kanaliks), ei saa seda peita näiteks stiiliga display:none või width:0; height:0. Freimi element peab olema lehel nähtav ja mõistlikus suuruses (näiteks minimaalselt 50×50 px), et brauserid optimeerimise mõttes selle sisu laadimata ei jätaks. Küll aga saab kõiki elemente lihtsasti peita, kui määrata nende absoluutseks positsiooniks negatiivse numbriga arv. Nii läheb element „serva taha“ peitu, nii et lehel on see küll täiesti olemas, aga vaataja seda kuidagi ei näe.
<iframe src="skript.php" style="position: absolute; top:-1000px; left:-1000px;"/>
Käidud rada: • git_github • close_tab • funcparams • geolocation • iframe