This article will summarize the code for passing values between frameworks (iframe) in js, from our most commonly used method to my summary of writing a function and some of the following methods for transferring iframe cross-origin values.
Many frameworks have parent-child relationships, which are very troublesome to operate. Many people often see such sad code:
The Code is as follows: |
Copy code |
Extends extends parent.doc ument. getElementById ("main ") .ContentWindow.doc ument. getElementById ('input'). value = Document. getElementById ('myiframe ') .Content1_doc ument. getElementById ('s0'). value; |
View a self-built instance
Iframe calls include the following: (calls include html dom, js global variables, and js methods)
Call iframe on the home page;
The iframe page calls the home page;
The iframe contained in the home page calls each other;
Key knowledge points
1: document. getElementById ("ii"). After contentWindow obtains the iframe object, you can use contentWindow to obtain the window object containing the page. Then you can access the page elements normally;
2: $ ("# ii") [0]. If you use the jquery selector to obtain iframe, add a [0 ];
3: $ ("# ii") [0]. contentWindow. $ ("# dd "). val () can be used to perform page operations after obtaining the iframe window object;
4: $ ("# ii") [0]. contentWindow. hellobaby = "dsafdsafsdafsdafsdafsdafsdafsadfsadfsdafsadfdsaffdsaaaaaaaaaaa"; you can pass parameters to the iframe page in this way. In the iframe page window. hellobaby can get the value. hellobaby is a custom variable;
5: On the iframe page, you can use parent to obtain the window on the home page, and then you can normally access the elements on the parent page;
6: parent. $ ("# ii") [0]. contentWindow. ff; for calls between pages with the same level iframe, you need to get the father's window first, and then call the iframe at the same level to get the window for operation;
Source code
Main.html
The Code is as follows: |
Copy code |
? <! DOCTYPE html PUBLIC "-// W3C // dtd html 4.01 Transitional // EN" "http://www.w3.org/TR/html4/loose.dtd"> <Html> <Head> <Meta http-equiv = "Content-Type" content = "text/html; charset = UTF-8"> <Title> display charts </title> <Script src = "/jquery-1.7.1.min.js" type = "text/javascript"> </script> <Script type = "text/javascript"> Var gg = "dsafdsafdsafdsafsdaf "; Function ggMM (){ Alert ("2222222222222222222222222222222 "); } Function callIframeMethod (){ // Document. getElementById ("ii"). contentWindow. test (); $ ("# Ii") [0]. contentWindow. test (); // you need to add a [0] To Call jquery. } Function callIframeField (){ Alert ($ ("# ii") [0]. contentWindow. ff ); } Function callIframeHtml (){ Alert ($ ("# ii") [0]. contentWindow. $ ("# dd"). val ()); // Alert ($ ("# ii" 20.00000).content0000doc ument. getElementById ("dd"). value ); // Alert ($ ("# ii" 20.00000).content0000doc ument. getElementById ("dd"). value ); } Function giveParameter (){ $ ("# Ii") [0]. contentWindow. hellobaby = "dsafdsafsdafsdafsdafsdafsadfsadfsadfsdafsadfdsaffdsaaaaaaaaaaa "; } </Script> </Head> <Body> <A href = "#" onClick = "giveParameter ();"> parameter transfer </a> <A href = "#" onClick = "callIframeMethod ();"> call the sub-iframe method </a> <A href = "#" onClick = "callIframeField ();"> call the sub-iframe variable </a> <A href = "#" onClick = "callIframeHtml ();"> call the sub-iframe component </a> </br> <Iframe id = "ii" src = "frame.htm" width = "100%" frameborder = "0"> </iframe> <Iframe id = "new" src = "newFrame.htm" width = "100%" frameborder = "0"> </iframe> </Body> </Html>
|
Frame.htm
The Code is as follows: |
Copy code |
? <! DOCTYPE html PUBLIC "-// W3C // dtd html 4.01 Transitional // EN" "http://www.w3.org/TR/html4/loose.dtd"> <Html> <Head> <Meta http-equiv = "Content-Type" content = "text/html; charset = UTF-8"> <Title> display charts </title> <Script src = "scripts/jquery-1.7.1.min.js" type = "text/javascript"> </script> <Script type = "text/javascript">
Var ff = "adfdasfdsafdsafdsaf "; Function test (){ Alert ($ ("# dd"). val ()); } Function callMainField (){ Alert (parent. gg ); } Function callMainMethod (){ Parent. ggMM (); } Function callMainHtml (){ Alert (parent. $ ("# ii"). attr ("id ")); } Function getParameter (){ Alert (window. hellobaby ); } </Script> </Head> <Body> <A href = "#" onClick = "getParameter ();"> Accept parameters </a> <A href = "#" onClick = "callMainMethod ();"> call the sub-iframe method </a> <A href = "#" onClick = "callMainField ();"> call the main window variable </a> <A href = "#" onClick = "callMainHtml ();"> call the sub-iframe component </a> <Input id = "dd" type = "text" value = "1111111111"/> </Body> </Html> |
NewIframe.htm
The Code is as follows: |
Copy code |
<! DOCTYPE html PUBLIC "-// W3C // dtd html 4.01 Transitional // EN" "http://www.w3.org/TR/html4/loose.dtd"> <Html> <Head> <Meta http-equiv = "Content-Type" content = "text/html; charset = UTF-8"> <Title> display charts </title> <Script src = "/jquery-1.7.1.min.js" type = "text/javascript"> </script> <Script type = "text/javascript"> Function callLevelFrame (){ Var ff = parent. $ ("# ii") [0]. contentWindow. ff; Alert (ff ); } </Script> </Head> <Body> <A href = "#" onClick = "callLevelFrame ();"> call brother iframe </a> <Input id = "nn" type = "text" value = "sdafsdfsa"/> </Body> </Html>
|
In fact, this problem can be greatly simplified. There is a fixed window in the framework application called window. top: If we cache data to this page, all the frameworks under it can be obtained, no matter how the sub-page changes. No Cookie or HTML5 local database policy is required. You only need to reference a js file on each page. The content is as follows:
The Code is as follows: |
Copy code |
Var share = {
/** * Cross-framework data sharing interface * @ Param {String} refers to the data name stored * @ Param {Any} Any data to be stored (the queried data is returned if this item is not included) */ Data: function (name, value ){ Var top = window. top, Cache = top ['_ cache'] || {}; Top ['_ cache'] = CACHE;
Return value! = Undefined? Cache [name] = value: cache [name]; }, /** * Data Sharing and deletion Interface * @ Param {String} The Name Of The Deleted Data */ RemoveData: function (name ){ Var cache = window. top ['_ cache']; If (cache & cache [name]) delete cache [name]; } };
|
The method with a few lines can share any type of data for each frame page to read. It has nothing to do with the page name and level, even if the Framework page level is modified someday, you don't have to worry about it. It works properly.
For example, we can store shared data on page:
The Code is as follows: |
Copy code |
Share. data ('myblog', 'HTTP: // www.planeart.cn '); Share. data ('edittitle', function (val ){ Document. title = val; }); |
Then, the data of page A is retrieved from any frame page.
The Code is as follows: |
Copy code |
Alert ('My blog address is: '+ share. data ('myblog '); Var editTitle = share. data ('edittitle '); EditTitle ('I have obtained the data '); |
Instance region operations
Document. domain + iframe settings
For examples with the same primary domain and different subdomains, you can set document. domain. The specific method is to create an iframe through the.html file after creating = 'a.com', to control the contentDocument of iframe, so that the two js files can "interact. Of course, this method can only solve the problem where the primary domain is the same but the second-level domain name is different. If you set the domian of script.a.com to alibaba.com in a whimsical manner, it will obviously report an error! The Code is as follows:
A.html on www.a.com
The Code is as follows: |
Copy code |
Document. domain = 'a. com '; Var ifr = document. createElement ('iframe '); Ifr. src = 'HTTP: // script.a.com/ B .html '; Ifr. style. display = 'none '; Document. body. appendChild (ifr ); Ifr. onload = function (){ Var doc = ifr. contentDocument | ifr.content##doc ument; // Operate B .html here Alert (doc. getElementsByTagName ("h1") [0]. childNodes [0]. nodeValue ); }; |
B .html on script.a.com
Document. domain = 'a. com'; this method applies to communication between any pages in {www.kuqin.com, kuqin.com, script.kuqin.com, and css.kuqin.com.
Note: The domain of a page is equal to window. location. hostname by default. The primary domain name is a domain name without www, such as a.com. The primary domain name is usually prefixed with a second-level domain name or multi-level domain name. For example, www.a.com is actually a second-level domain name. Domain can only be set as the primary domain name. You cannot set domain to c.a.com in B .a.com.
Problem:
1. Security: When a site (B .a.com) is attacked, another site (c.a.com) will cause a security vulnerability.
2. If multiple iframe is introduced to a page, you must set the same domain to operate all iframe operations.
2. dynamically create scripts
Although cross-origin access is disabled by default, the browser does not prohibit reference JS files of other domains in the page, and can freely execute the functions (including cookie and Dom operations) in the introduced JS files ). Based on this, you can easily create a script node to implement full cross-origin communication. For specific practices, refer to the YUI Get Utility
It is quite interesting to judge whether the script node is loaded: ie can only use the readystatechange attribute of the script, and other browsers are the load events of the script. The following describes how to determine whether a script has been loaded.
The Code is as follows: |
Copy code |
Js. onload = js. onreadystatechange = function (){ If (! This. readyState | this. readyState = 'loaded' | this. readyState = 'complete '){ // Callback is executed here Js. onload = js. onreadystatechange = null; } }; |
3. Use iframe and location. hash
This method is relatively difficult, but it can solve the problem of step replacement in the case of full cross-origin. The principle is to use location. hash to transmit values. '# Helloworld' in url: http://a.com # helloword is location. changing the hash does not cause page refreshing. Therefore, you can use the hash value for data transmission. Of course, the data capacity is limited. In this case, the hash value can be used for parameter transfer. Cs2.htmlafter the request is received, the modified cs1.html hash value will be passed for data transmission (because the two pages are not in the same domain, IE and Chrome cannot modify the parent. location. hash Value, so you need to use a proxy iframe under the.com domain name; Firefox can be modified ). Add a timer to cs1.html at the same time to judge whether the location. hash Value has changed over a period of time. If there is any change, obtain the hash value. The Code is as follows:
First, the cs1.html file under a.com:
The Code is as follows: |
Copy code |
Function startRequest (){ Var ifr = document. createElement ('iframe '); Ifr. style. display = 'none '; Ifr. src = 'HTTP: // www. bKjia. c0m/lab/cscript/cs2.html # paramdo '; Document. body. appendChild (ifr ); } Function checkHash (){ Try { Var data = location. hash? Location. hash. substring (1 ):''; If (console. log ){ Console. log ('Now the data is '+ data ); } } Catch (e ){}; } SetInterval (checkHash, 2000 ); |
Cs2.html under bkjia.c0mdomain Name:
The Code is as follows: |
Copy code |
// Simulate a simple parameter processing operation Switch (location. hash ){ Case '# paramdo ': CallBack (); Break; Case '# paramset ': // Do something ...... Break; } Function callBack (){ Try { Parent. location. hash = 'somedata '; } Catch (e ){ // The Security Mechanism of ie and chrome cannot be modified by parent. location. hash, // Use the proxy iframe in an intermediate cnblogs domain Var ifrproxy = document. createElement ('iframe '); Ifrproxy. style. display = 'none '; Ifrproxy. src = 'HTTP: // a.com/test/cscript/cs3.html#somedata'; // note that the file is in the "a.com" Domain Document. body. appendChild (ifrproxy ); } } |
.Com domain name cs3.html
// Because parent. parent belongs to the same domain, you can change its location. hash Value.
Parent. parent. location. hash = self. location. hash. substring (1); of course, this method also has many disadvantages, such as direct data exposure to URLs, limited data capacity and type.