DEV Community

Cover image for Javascript and Iframes
Supun Wimalasena
Supun Wimalasena

Posted on Originally published at groups.hyvor.com

Javascript and Iframes

From the title you know I'm going to write about Javascript and Iframes. In everyday life as a developer or a blogger, embedding an Iframe into your website is pretty straightforward.

For instance, if you need to embed a youtube video to your website, you can simply copy the code from Youtube and paste it on your website.

<iframe width="560" height="315" src="https://www.youtube.com/embed/$SOME_ID" frameborder="0" allow="accelerometer; autoplay; encrypted-media; gyroscope; picture-in-picture" allowfullscreen></iframe>
Enter fullscreen mode Exit fullscreen mode

That's what I called "straightforward".

I knew this and started developing a commenting plugin, Hyvor Talk a few months back. It was not straightforward. In this article, I'm going to explain the reason for that. I learned many things and devised some tricks while creating this plugin. I'll explain those in this article. If you ever plan to develop a plugin or anything that loads on other websites using Iframes (something like a commenting plugin) this article will help you to understand how to do certain tasks in an organized way. Also, I'll explain how to overcome the obstacles you will probably face while developing such thing.

For this tutorial, let's assume that you are creating a plugin that is loaded in an iframe on other websites (I'm calling the owner of this other website "client"). Also, your website's domain is pluginx.com and the client's web site's domain is client.com.

Iframes

First, let's look into what's an Iframe.

The HTML Inline Frame element () represents a nested browsing context, embedding another HTML page into the current one - <em>MDN</em></p> </blockquote> <p>Instead of just adding HTML code to a website, in this article, I&#39;m going to focus on how to do work with Iframes using Javascript. </p> <h1> <a name="why-do-we-really-need-javascript" href="#why-do-we-really-need-javascript" class="anchor"> </a> Why do we really need Javascript? </h1> <p>Javascript can give you more control with the Iframe. Especially, auto-resizing an iframe when the content in the iframe changes can only be done with Javascript. This requires communication between the iframe (your website) and the website (other one&#39;s website). So, the best way is not to give an <code>&lt;iframe&gt;</code> code to the client but to let them add a Javascript file.</p> <p>The client adds the code to his website. The code includes a <code>&lt;script&gt;</code> tag and a <code>&lt;div&gt;</code> tag (the iframe container).<br> </p> <div class="highlight"><pre class="highlight html"><code><span class="nt">&lt;html&gt;</span> <span class="nt">&lt;head&gt;</span> ... <span class="nt">&lt;/head&gt;</span> <span class="nt">&lt;body&gt;</span> ... <span class="nt">&lt;div</span> <span class="na">id=</span><span class="s">"pluginx-iframe-container"</span><span class="nt">&gt;&lt;/div&gt;</span> <span class="nt">&lt;script </span><span class="na">src=</span><span class="s">"https://pluginx.com/iframe-loader.js"</span><span class="nt">&gt;&lt;/script&gt;</span> <span class="nt">&lt;/body&gt;</span> </code></pre></div> <p></p> <p>Now, we can write the <strong>iframe-loader.js</strong> which loads the HTML page hosted on your domain.</p> <h2> <a name="adding-the-iframe" href="#adding-the-iframe" class="anchor"> </a> Adding the Iframe </h2> <p>This task requires simple Javascript. One thing you should remember is to <strong>keep all the variables in a <a href="https://www.w3schools.com/js/js_scope.asp">local scope</a></strong>. This can be done by wrapping the code inside a <a href="https://scriptverse.academy/tutorials/js-self-invoking-functions.html">self-invoking function</a>. This prevents the collision between your JS variables and the client&#39;s website&#39;s JS variables. If you use a bundler like <a href="https://webpack.js.org/">webpack</a>, this is not required as webpack makes all the variables local.<br> </p> <div class="highlight"><pre class="highlight javascript"><code><span class="p">(</span><span class="kd">function</span><span class="p">()</span> <span class="p">{</span> <span class="kd">var</span> <span class="nx">iframe</span> <span class="o">=</span> <span class="nb">document</span><span class="p">.</span><span class="nf">createElement</span><span class="p">(</span><span class="dl">"</span><span class="s2">iframe</span><span class="dl">"</span><span class="p">);</span> <span class="nx">iframe</span><span class="p">.</span><span class="nx">src</span> <span class="o">=</span> <span class="dl">"</span><span class="s2">https://pluginx.com/iframe</span><span class="dl">"</span><span class="p">;</span> <span class="c1">// iframe content (HTML page)</span> <span class="nx">iframe</span><span class="p">.</span><span class="nx">name</span> <span class="o">=</span> <span class="dl">"</span><span class="s2">pluginx-main-iframe</span><span class="dl">"</span><span class="p">;</span> <span class="c1">// this is important</span> <span class="p">})();</span> </code></pre></div> <p></p> <p>I&#39;ll explain the importance of the <code>name</code> attribute later. Make sure to set a unique name for that.</p> <p>I found that adding the following attribute makes your iframe well-looking in all the browsers.<br> </p> <div class="highlight"><pre class="highlight javascript"><code><span class="nx">iframe</span><span class="p">.</span><span class="nx">width</span> <span class="o">=</span> <span class="dl">"</span><span class="s2">100%</span><span class="dl">"</span><span class="p">;</span> <span class="nx">iframe</span><span class="p">.</span><span class="nx">allowTranparency</span> <span class="o">=</span> <span class="kc">true</span><span class="p">;</span> <span class="nx">iframe</span><span class="p">.</span><span class="nx">tabIndex</span> <span class="o">=</span> <span class="mi">0</span><span class="p">;</span> <span class="nx">iframe</span><span class="p">.</span><span class="nx">scrolling</span> <span class="o">=</span> <span class="dl">"</span><span class="s2">no</span><span class="dl">"</span><span class="p">;</span> <span class="nx">iframe</span><span class="p">.</span><span class="nx">frameBorder</span> <span class="o">=</span> <span class="mi">0</span><span class="p">;</span> <span class="nx">iframe</span><span class="p">.</span><span class="nx">style</span><span class="p">.</span><span class="nx">border</span> <span class="o">=</span> <span class="dl">"</span><span class="s2">none</span><span class="dl">"</span><span class="p">;</span> <span class="nx">iframe</span><span class="p">.</span><span class="nx">style</span><span class="p">.</span><span class="nx">overflow</span> <span class="o">=</span> <span class="dl">"</span><span class="s2">hidden</span><span class="dl">"</span><span class="p">;</span> <span class="nx">iframe</span><span class="p">.</span><span class="nx">style</span><span class="p">.</span><span class="nx">userSelect</span> <span class="o">=</span> <span class="dl">"</span><span class="s2">none</span><span class="dl">"</span><span class="p">;</span> <span class="nx">iframe</span><span class="p">.</span><span class="nx">style</span><span class="p">.</span><span class="nx">height</span> <span class="o">=</span> <span class="dl">"</span><span class="s2">250px</span><span class="dl">"</span><span class="p">;</span> <span class="c1">// set initial height</span> </code></pre></div> <p></p> <p>Now, we can append the <code>&lt;iframe&gt;</code>.<br> </p> <div class="highlight"><pre class="highlight javascript"><code><span class="kd">var</span> <span class="nx">container</span> <span class="o">=</span> <span class="nb">document</span><span class="p">.</span><span class="nf">getElementById</span><span class="p">(</span><span class="dl">"</span><span class="s2">pluginx-iframe-container</span><span class="dl">"</span><span class="p">);</span> <span class="nx">container</span><span class="p">.</span><span class="nf">appendChild</span><span class="p">(</span><span class="nx">iframe</span><span class="p">);</span> </code></pre></div> <p></p> <h1> <a name="the-problem-same-origin-policy" href="#the-problem-same-origin-policy" class="anchor"> </a> THE PROBLEM (Same Origin Policy) </h1> <p>If both websites were in the same domain, you can simply execute each other page&#39;s function, access variables, and so. But, according to the <a href="https://developer.mozilla.org/en-US/docs/Web/Security/Same-origin_policy">Same Origin Policy</a>, this cannot be done. The browser restricts parent websites from accessing the iframe window&#39;s functions and variables and vice versa if those two are not in the same domain. At first, I thought this is an unnecessary security implementation. But, now I understand it&#39;s one of the best ways to secure websites. Why? If your client could access your website with Javascript, They can run your functions, update content, click buttons, add likes, steal user data, and more.</p> <p>There are <a href="https://stackoverflow.com/questions/3076414/ways-to-circumvent-the-same-origin-policy">several ways</a> to circumvent the Same Origin Policy. The best method is <strong>HTML 5 Post Message API</strong>.</p> <h1> <a name="post-message-api" href="#post-message-api" class="anchor"> </a> Post Message API </h1> <p>Never think of any other best friend than the <a href="https://developer.mozilla.org/en-US/docs/Web/API/Window/postMessage">Post Message API</a> until you finish developing this application!</p> <p>The <code>window.postMessage()</code> method safely enables cross-origin communication between Window objects. Here we can use it to communicate between our plugin and the client&#39;s website. We can listen to postMessages via the <code>window.onmessage</code> event. Note that you can only send strings via this.</p> <p>While creating Hyvor Talk, I created a simple class to wrap this communication. I recommend you to use that as it simplifies the process. Here&#39;s the code. I&#39;ll explain it next.<br> </p> <div class="highlight"><pre class="highlight javascript"><code><span class="cm">/** * Creates a messenger between two windows * which have two different domains */</span> <span class="kd">class</span> <span class="nc">CrossMessenger</span> <span class="p">{</span> <span class="cm">/** * * @param {object} otherWindow - window object of the other * @param {string} targetDomain - domain of the other window * @param {object} eventHandlers - all the event names and handlers */</span> <span class="nf">constructor</span><span class="p">(</span><span class="nx">otherWindow</span><span class="p">,</span> <span class="nx">targetDomain</span><span class="p">,</span> <span class="nx">eventHandlers</span> <span class="o">=</span> <span class="p">{})</span> <span class="p">{</span> <span class="k">this</span><span class="p">.</span><span class="nx">otherWindow</span> <span class="o">=</span> <span class="nx">otherWindow</span><span class="p">;</span> <span class="k">this</span><span class="p">.</span><span class="nx">targetDomain</span> <span class="o">=</span> <span class="nx">targetDomain</span><span class="p">;</span> <span class="k">this</span><span class="p">.</span><span class="nx">eventHandlers</span> <span class="o">=</span> <span class="nx">eventHandlers</span><span class="p">;</span> <span class="nb">window</span><span class="p">.</span><span class="nf">addEventListener</span><span class="p">(</span><span class="dl">"</span><span class="s2">message</span><span class="dl">"</span><span class="p">,</span> <span class="p">(</span><span class="nx">e</span><span class="p">)</span> <span class="o">=&gt;</span> <span class="k">this</span><span class="p">.</span><span class="nx">receive</span><span class="p">.</span><span class="nf">call</span><span class="p">(</span><span class="k">this</span><span class="p">,</span> <span class="nx">e</span><span class="p">));</span> <span class="p">}</span> <span class="nf">post</span><span class="p">(</span><span class="nx">event</span><span class="p">,</span> <span class="nx">data</span><span class="p">)</span> <span class="p">{</span> <span class="k">try</span> <span class="p">{</span> <span class="c1">// data obj should have event name</span> <span class="kd">var</span> <span class="nx">json</span> <span class="o">=</span> <span class="nx">JSON</span><span class="p">.</span><span class="nf">stringify</span><span class="p">({</span> <span class="nx">event</span><span class="p">,</span> <span class="nx">data</span> <span class="p">});</span> <span class="k">this</span><span class="p">.</span><span class="nx">otherWindow</span><span class="p">.</span><span class="nf">postMessage</span><span class="p">(</span><span class="nx">json</span><span class="p">,</span> <span class="k">this</span><span class="p">.</span><span class="nx">targetDomain</span><span class="p">);</span> <span class="p">}</span> <span class="k">catch </span><span class="p">(</span><span class="nx">e</span><span class="p">)</span> <span class="p">{}</span> <span class="p">}</span> <span class="nf">receive</span><span class="p">(</span><span class="nx">e</span><span class="p">)</span> <span class="p">{</span> <span class="kd">var</span> <span class="nx">json</span><span class="p">;</span> <span class="k">try</span> <span class="p">{</span> <span class="nx">json</span> <span class="o">=</span> <span class="nx">JSON</span><span class="p">.</span><span class="nf">parse</span><span class="p">(</span><span class="nx">e</span><span class="p">.</span><span class="nx">data</span> <span class="p">?</span> <span class="nx">e</span><span class="p">.</span><span class="nx">data</span> <span class="p">:</span> <span class="dl">"</span><span class="s2">{}</span><span class="dl">"</span><span class="p">);</span> <span class="p">}</span> <span class="k">catch </span><span class="p">(</span><span class="nx">e</span><span class="p">)</span> <span class="p">{</span> <span class="k">return</span><span class="p">;</span> <span class="p">}</span> <span class="kd">var</span> <span class="nx">eventName</span> <span class="o">=</span> <span class="nx">json</span><span class="p">.</span><span class="nx">event</span><span class="p">,</span> <span class="nx">data</span> <span class="o">=</span> <span class="nx">json</span><span class="p">.</span><span class="nx">data</span><span class="p">;</span> <span class="k">if </span><span class="p">(</span><span class="nx">e</span><span class="p">.</span><span class="nx">origin</span> <span class="o">!==</span> <span class="k">this</span><span class="p">.</span><span class="nx">targetDomain</span><span class="p">)</span> <span class="k">return</span><span class="p">;</span> <span class="k">if </span><span class="p">(</span><span class="k">typeof</span> <span class="k">this</span><span class="p">.</span><span class="nx">eventHandlers</span><span class="p">[</span><span class="nx">eventName</span><span class="p">]</span> <span class="o">===</span> <span class="dl">"</span><span class="s2">function</span><span class="dl">"</span><span class="p">)</span> <span class="k">this</span><span class="p">.</span><span class="nx">eventHandlers</span><span class="p">[</span><span class="nx">eventName</span><span class="p">](</span><span class="nx">data</span><span class="p">);</span> <span class="p">}</span> <span class="p">}</span> </code></pre></div> <p></p> <p>I used ES6 to write this class. If you are not using that, you can simply convert this to browser-supported Javascript using <a href="https://babeljs.io/">Babel</a>.</p> <p>Before an explanation of the class, let&#39;s use it in our script (iframe-loader.js).<br> </p> <div class="highlight"><pre class="highlight javascript"><code> <span class="c1">// handle each event from the iframe</span> <span class="kd">var</span> <span class="nx">clientEventsHandler</span> <span class="o">=</span> <span class="p">{</span> <span class="na">resize</span><span class="p">:</span> <span class="p">(</span><span class="nx">data</span><span class="p">)</span> <span class="o">=&gt;</span> <span class="p">{</span> <span class="c1">// resize the iframe</span> <span class="p">}</span> <span class="p">};</span> <span class="nx">messenger</span> <span class="kd">var</span> <span class="nx">clientMsger</span> <span class="o">=</span> <span class="k">new</span> <span class="nc">CrossMessenger</span><span class="p">(</span><span class="nx">iframe</span><span class="p">.</span><span class="nx">contentWindow</span><span class="p">,</span> <span class="dl">"</span><span class="s2">https://pluginx.com</span><span class="dl">"</span><span class="p">,</span> <span class="nx">eventHandlers</span><span class="p">)</span> </code></pre></div> <p></p> <p>While sending messages to the iframe, we will also need to receive messages and react upon data. The <code>clientEventsHandler</code> object will contain those functions. (keys with event name). </p> <p>Let&#39;s go back to our class.</p> <p>The constructor requires three parameters. </p> <ul> <li>The first one is the iframe window on which we call the <code>postMessage()</code> function. </li> <li>Then, the target domain which is your website&#39;s domain. This allows us to verify incoming messages using <code>e.origin</code> </li> <li>Finally, the event handlers. I&#39;ll show you how to write some common event handlers like the resizing event later.</li> </ul> <p>Now, we can send a message to the iframe using <code>clientMsger.post(eventName, data)</code>. Here, data should be an object. It will be converted to JSON and sent to the iframe.</p> <h1> <a name="receiving-messages-in-iframe" href="#receiving-messages-in-iframe" class="anchor"> </a> Receiving messages in Iframe </h1> <p>For now, we worked on the Javascript file added to the client&#39;s website. Now, we will start working on the iframe&#39;s script. We will need to use the same class in the iframe to receive messages.</p> <p>Your iframe&#39;s content (HTML)<br> </p> <div class="highlight"><pre class="highlight html"><code><span class="nt">&lt;html&gt;</span> ... html stuffs <span class="nt">&lt;script </span><span class="na">src=</span><span class="s">"script.js"</span><span class="nt">&gt;&lt;/script&gt;</span> <span class="nt">&lt;/html&gt;</span> </code></pre></div> <p></p> <p><code>script.js</code><br> </p> <div class="highlight"><pre class="highlight javascript"><code><span class="kd">var</span> <span class="nx">iframeEventHandlers</span> <span class="o">=</span> <span class="p">{};</span> <span class="c1">// some event handlers as the clientEventHandlers</span> <span class="kd">var</span> <span class="nx">clientDomain</span> <span class="o">=</span> <span class="dl">""</span><span class="p">;</span> <span class="c1">// How to find this???</span> <span class="kd">var</span> <span class="nx">iframeMsger</span> <span class="o">=</span> <span class="k">new</span> <span class="nc">CrossMessenger</span><span class="p">(</span><span class="nb">window</span><span class="p">.</span><span class="nx">parent</span><span class="p">,</span> <span class="nx">clientDomain</span><span class="p">,</span> <span class="nx">iframeEventHandlers</span><span class="p">)</span> </code></pre></div> <p></p> <p>We need to find the client&#39;s domain. How I did this was to set GET params when requesting the Iframe.<br> </p> <div class="highlight"><pre class="highlight javascript"><code><span class="kd">var</span> <span class="nx">domain</span> <span class="o">=</span> <span class="nx">location</span><span class="p">.</span><span class="nx">protocol</span> <span class="o">+</span> <span class="dl">"</span><span class="s2">//</span><span class="dl">"</span> <span class="o">+</span> <span class="nx">location</span><span class="p">.</span><span class="nx">hostname</span><span class="p">;</span> <span class="nx">iframe</span><span class="p">.</span><span class="nx">src</span> <span class="o">=</span> <span class="dl">"</span><span class="s2">https://pluginx.com/iframe?domain=</span><span class="dl">"</span> <span class="o">+</span> <span class="nx">domain</span><span class="p">;</span> </code></pre></div> <p></p> <p>Then, you can receive it from your back-end language and set the <code>clientDomain</code> variable dynamically.</p> <p>Ex: For PHP<br> </p> <div class="highlight"><pre class="highlight javascript"><code><span class="kd">var</span> <span class="nx">clientDomain</span> <span class="o">=</span> <span class="dl">"</span><span class="s2">&lt;?= $_GET['domain'] ?&gt;</span><span class="dl">"</span><span class="p">;</span> <span class="c1">// make sure this is in the PHP page ;)</span> </code></pre></div> <p></p> <p>Now, both of our messengers are completed. Let&#39;s consider some events that you may need.</p> <h1> <a name="events" href="#events" class="anchor"> </a> Events </h1> <h2> <a name="1-resizing" href="#1-resizing" class="anchor"> </a> 1. Resizing </h2> <p>Iframes are not auto-resizing by default. We have to explicitly set the height of the iframe. Otherwise, a part of the iframe won&#39;t be displayed. So, resizing is a crucial part of any iframe.</p> <p>Resizing is quite complex than we think. You need to know the <code>scrollHeight</code> of the iframe document to be able to resize the iframe. This can only be canculated by the iframe.</p> <p>Here are the important moments to resize the iframe.</p> <ol> <li>When the Iframe loads</li> <li>When the client&#39;s browser is resized</li> <li>When the height of the contents of the iframe changes. (Ex: New elements added)</li> </ol> <h3> <a name="no-1-amp-2-on-load-and-resize" href="#no-1-amp-2-on-load-and-resize" class="anchor"> </a> No. 1 &amp; 2 (On load and resize) </h3> <p>We can listen to iframe&#39;s <code>onload</code> event and the browser&#39;s <code>onresize</code> event from the script on client&#39;s website (iframe-loader.js).<br> </p> <div class="highlight"><pre class="highlight javascript"><code><span class="p">(</span><span class="kd">function</span><span class="p">()</span> <span class="p">{</span> <span class="c1">// setting iframe and appending</span> <span class="nx">iframe</span><span class="p">.</span><span class="nx">onload</span> <span class="o">=</span> <span class="kd">function</span><span class="p">()</span> <span class="p">{</span> <span class="nf">requestResize</span><span class="p">();</span> <span class="c1">// do other onload tasks</span> <span class="p">}</span> <span class="nb">window</span><span class="p">.</span><span class="nf">addEventListener</span><span class="p">(</span><span class="dl">"</span><span class="s2">resize</span><span class="dl">"</span><span class="p">,</span> <span class="nx">requestHeight</span><span class="p">);</span> <span class="p">})();</span> </code></pre></div> <p></p> <p><strong>The <code>requestHeight()</code> function</strong></p> <p>This function only does one thing. Requests the <strong>height</strong> of the iframe from the iframe.<br> </p> <div class="highlight"><pre class="highlight javascript"><code><span class="nx">clientMsger</span><span class="p">.</span><span class="nf">post</span><span class="p">(</span><span class="dl">"</span><span class="s2">iframeHeightRequest</span><span class="dl">"</span><span class="p">);</span> </code></pre></div> <p></p> <p>This sends a message to the iframe with the event name &quot;iframeResizeRequest&quot; and no data.</p> <p>We have to listen to this event in the iframe. Add the event name and a handler to the <code>iframeEventHandlers</code> in the <code>script.js</code>.<br> </p> <div class="highlight"><pre class="highlight javascript"><code><span class="kd">var</span> <span class="nx">iframeEventHandlers</span> <span class="o">=</span> <span class="p">{</span> <span class="na">iframeHeightRequest</span><span class="p">:</span> <span class="p">()</span> <span class="o">=&gt;</span> <span class="p">{</span> <span class="kd">var</span> <span class="nx">docHeight</span> <span class="o">=</span> <span class="nb">document</span><span class="p">.</span><span class="nx">body</span><span class="p">.</span><span class="nx">scrollHeight</span><span class="p">;</span> <span class="nx">iframeMsger</span><span class="p">.</span><span class="nf">post</span><span class="p">(</span><span class="dl">"</span><span class="s2">resize</span><span class="dl">"</span><span class="p">,</span> <span class="p">{</span> <span class="na">height</span><span class="p">:</span> <span class="nx">docHeight</span> <span class="p">});</span> <span class="p">}</span> <span class="p">}</span> </code></pre></div> <p></p> <p>Now, we can receive the height from the client&#39;s script and resize the iframe.<br> </p> <div class="highlight"><pre class="highlight javascript"><code><span class="kd">var</span> <span class="nx">clientEventHandlers</span> <span class="o">=</span> <span class="p">{</span> <span class="na">resize</span><span class="p">:</span> <span class="p">()</span> <span class="o">=&gt;</span> <span class="p">{</span> <span class="kd">var</span> <span class="nx">height</span> <span class="o">=</span> <span class="nx">data</span><span class="p">.</span><span class="nx">height</span><span class="p">;</span> <span class="kd">var</span> <span class="nx">winScrollLeft</span> <span class="o">=</span> <span class="nb">window</span><span class="p">.</span><span class="nx">scrollX</span><span class="p">,</span> <span class="nx">windowScrollTop</span> <span class="o">=</span> <span class="nb">window</span><span class="p">.</span><span class="nx">scrollY</span><span class="p">;</span> <span class="nx">commentsIframe</span><span class="p">.</span><span class="nx">style</span><span class="p">.</span><span class="nx">visibility</span> <span class="o">=</span> <span class="dl">"</span><span class="s2">hidden</span><span class="dl">"</span><span class="p">;</span> <span class="nx">commentsIframe</span><span class="p">.</span><span class="nx">style</span><span class="p">.</span><span class="nx">height</span> <span class="o">=</span> <span class="mi">0</span><span class="p">;</span> <span class="nx">commentsIframe</span><span class="p">.</span><span class="nx">style</span><span class="p">.</span><span class="nx">visibility</span> <span class="o">=</span> <span class="dl">"</span><span class="s2">visible</span><span class="dl">"</span><span class="p">;</span> <span class="nx">commentsIframe</span><span class="p">.</span><span class="nx">height</span> <span class="o">=</span> <span class="nx">height</span> <span class="o">+</span> <span class="dl">"</span><span class="s2">px</span><span class="dl">"</span><span class="p">;</span> <span class="c1">// + 10 to add little more height if needed</span> <span class="c1">// scroll to initial position</span> <span class="nb">window</span><span class="p">.</span><span class="nf">scrollTo</span><span class="p">(</span><span class="nx">winScrollLeft</span><span class="p">,</span> <span class="nx">windowScrollTop</span><span class="p">);</span> <span class="p">}</span> <span class="p">}</span> </code></pre></div> <p></p> <p>This process can be confusing. I had the same feeling in the beginning. But, you can adapt to it quickly. If you feel like &quot;bewildered&quot; take a short break. (I did that, as I remember). After the break, look at this picture.</p> <p><img src="https://dev-to-uploads.s3.us-east-2.amazonaws.com/uploads/articles/9ggjbbt6dn07ky3k5zty.jpeg" alt="Resizing Image"/></p> <h3> <a name="no-3-iframe-height-changed" href="#no-3-iframe-height-changed" class="anchor"> </a> No 3. (Iframe height changed) </h3> <p>When you work inside the iframe, new elements can be added. This can cause to change the height of it. So, each time the height changes, we have to resize the iframe.</p> <p>We have to listen to DOM element changes in the iframe. Here&#39;s a perfect function I found from the internet for this task.<br> </p> <div class="highlight"><pre class="highlight javascript"><code><span class="kd">var</span> <span class="nx">DOMObserver</span> <span class="o">=</span> <span class="p">(</span><span class="kd">function</span><span class="p">(){</span> <span class="kd">var</span> <span class="nx">MutationObserver</span> <span class="o">=</span> <span class="nb">window</span><span class="p">.</span><span class="nx">MutationObserver</span> <span class="o">||</span> <span class="nb">window</span><span class="p">.</span><span class="nx">WebKitMutationObserver</span><span class="p">;</span> <span class="k">return</span> <span class="kd">function</span><span class="p">(</span> <span class="nx">obj</span><span class="p">,</span> <span class="nx">callback</span> <span class="p">){</span> <span class="k">if</span><span class="p">(</span> <span class="o">!</span><span class="nx">obj</span> <span class="o">||</span> <span class="o">!</span><span class="nx">obj</span><span class="p">.</span><span class="nx">nodeType</span> <span class="o">===</span> <span class="mi">1</span> <span class="p">)</span> <span class="k">return</span><span class="p">;</span> <span class="c1">// validation</span> <span class="k">if</span><span class="p">(</span> <span class="nx">MutationObserver</span> <span class="p">){</span> <span class="c1">// define a new observer</span> <span class="kd">var</span> <span class="nx">obs</span> <span class="o">=</span> <span class="k">new</span> <span class="nc">MutationObserver</span><span class="p">(</span><span class="kd">function</span><span class="p">(</span><span class="nx">mutations</span><span class="p">,</span> <span class="nx">observer</span><span class="p">){</span> <span class="nf">callback</span><span class="p">(</span><span class="nx">mutations</span><span class="p">);</span> <span class="p">})</span> <span class="c1">// have the observer observe foo for changes in children</span> <span class="nx">obs</span><span class="p">.</span><span class="nf">observe</span><span class="p">(</span> <span class="nx">obj</span><span class="p">,</span> <span class="p">{</span> <span class="na">childList</span><span class="p">:</span><span class="kc">true</span><span class="p">,</span> <span class="na">subtree</span><span class="p">:</span><span class="kc">true</span> <span class="p">});</span> <span class="p">}</span> <span class="k">else</span> <span class="k">if</span><span class="p">(</span> <span class="nb">window</span><span class="p">.</span><span class="nx">addEventListener</span> <span class="p">){</span> <span class="nx">obj</span><span class="p">.</span><span class="nf">addEventListener</span><span class="p">(</span><span class="dl">'</span><span class="s1">DOMNodeInserted</span><span class="dl">'</span><span class="p">,</span> <span class="nx">callback</span><span class="p">,</span> <span class="kc">false</span><span class="p">);</span> <span class="nx">obj</span><span class="p">.</span><span class="nf">addEventListener</span><span class="p">(</span><span class="dl">'</span><span class="s1">DOMNodeRemoved</span><span class="dl">'</span><span class="p">,</span> <span class="nx">callback</span><span class="p">,</span> <span class="kc">false</span><span class="p">);</span> <span class="p">}</span> <span class="p">}</span> <span class="p">})();</span> </code></pre></div> <p></p> <p>Add this to <code>script.js</code> and then call the function.<br> </p> <div class="highlight"><pre class="highlight javascript"><code><span class="nc">DOMObserver</span><span class="p">(</span><span class="nb">document</span><span class="p">.</span><span class="nx">body</span><span class="p">,</span> <span class="nx">iframeEventHandlers</span><span class="p">.</span><span class="nx">iframeHeightRequest</span><span class="p">);</span> </code></pre></div> <p></p> <p>Each time a node is added or removed, the <code>iframeEventHandlers.iframeHeightRequest</code> function will be called. Iframe will be resized!.</p> <p>Besides resizing, you can add any event and convey messages between the iframe and the client.</p> <p>If you are creating a plugin or anything that loads inside an iframe, here are some tips from me.</p> <ul> <li>Keep all the data in your window. Only share the needed ones with the client website. Never share sensitive data like user&#39;s data.</li> <li>Do all AJAX stuff in your iframe. </li> <li>Never use <a href="https://developer.mozilla.org/en-US/docs/Web/HTTP/CORS">CORS</a> and give access to your website from others. Always use postMessage API.</li> </ul> <p>I hope this article helped you to understand how to use Javascript with Iframes. I tried my best to explain what I learned while creating Hyvor Talk. If I missed something, I&#39;ll add it in the future. Also, If you like the article please share it and comment. </p> <p>Thank you. :)</p> <p><em>This post is originally posted in <a href="https://groups.hyvor.com/WebDevelopment/171/javascript-and-iframes">Web Developers Group</a> in Hyvor Groups</em></p>

Top comments (1)

Collapse
 
fenix profile image
Fenix

Thanks for sharing, ... Namaste ;.)