<?xml version="1.0" encoding="UTF-8"?><rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>plainjs Archives - I Learn Javascript</title>
	<atom:link href="https://www.ilearnjavascript.com/tag/plainjs/feed/" rel="self" type="application/rss+xml" />
	<link>https://www.ilearnjavascript.com/tag/plainjs/</link>
	<description>Learn Javascript for free</description>
	<lastBuildDate>Sat, 25 Jan 2020 18:11:44 +0000</lastBuildDate>
	<language>en-US</language>
	<sy:updatePeriod>
	hourly	</sy:updatePeriod>
	<sy:updateFrequency>
	1	</sy:updateFrequency>
	<generator>https://wordpress.org/?v=6.9</generator>
	<item>
		<title>PlainJS: fade-in &#038; fade-out</title>
		<link>https://www.ilearnjavascript.com/plainjs-fadein-fadeout/</link>
		
		<dc:creator><![CDATA[ILJS]]></dc:creator>
		<pubDate>Sun, 24 Mar 2019 21:28:08 +0000</pubDate>
				<category><![CDATA[Javascript]]></category>
		<category><![CDATA[PlainJS]]></category>
		<category><![CDATA[javascript]]></category>
		<category><![CDATA[plainjs]]></category>
		<guid isPermaLink="false">https://www.ilearnjavascript.com/?p=1058</guid>

					<description><![CDATA[<p>How to build a performant and reusable fade-in and fade-out animation using plain javascript and the requestAnimationFrame method.</p>
<p>The post <a href="https://www.ilearnjavascript.com/plainjs-fadein-fadeout/">PlainJS: fade-in &#038; fade-out</a> appeared first on <a href="https://www.ilearnjavascript.com">I Learn Javascript</a>.</p>
]]></description>
										<content:encoded><![CDATA[
<style type="text/css" data-created_by="avia_inline_auto" id="style-css-av-jsm56n9k-b89ad28a2e87aea11f86249f3e974975">
.flex_column.av-jsm56n9k-b89ad28a2e87aea11f86249f3e974975{
border-radius:0px 0px 0px 0px;
padding:0px 0px 0px 0px;
}
</style>
<div  class='flex_column av-jsm56n9k-b89ad28a2e87aea11f86249f3e974975 av_one_full  avia-builder-el-0  avia-builder-el-no-sibling  blogpost first flex_column_div av-zero-column-padding  '     ><p>
<style type="text/css" data-created_by="avia_inline_auto" id="style-css-av-av_heading-4677f5c828b854f68448a0f51c6f4ecb">
#top .av-special-heading.av-av_heading-4677f5c828b854f68448a0f51c6f4ecb{
padding-bottom:10px;
}
body .av-special-heading.av-av_heading-4677f5c828b854f68448a0f51c6f4ecb .av-special-heading-tag .heading-char{
font-size:25px;
}
.av-special-heading.av-av_heading-4677f5c828b854f68448a0f51c6f4ecb .av-subheading{
font-size:14px;
}
</style>
<div  class='av-special-heading av-av_heading-4677f5c828b854f68448a0f51c6f4ecb av-special-heading-h1 blockquote modern-quote  avia-builder-el-1  el_before_av_textblock  avia-builder-el-first '><h1 class='av-special-heading-tag '  itemprop="headline"  >PlainJS: fade-in <span class='special_amp'>&amp;</span> fade-out</h1><div class='av-subheading av-subheading_below'><p>8min read</p>
</div><div class="special-heading-border"><div class="special-heading-inner-border"></div></div></div><br />
<section  class='av_textblock_section av-484hle-406149cc130335ef8e30129389794269 '   itemscope="itemscope" itemtype="https://schema.org/BlogPosting" itemprop="blogPost" ><div class='avia_textblock'  itemprop="text" ><p>We use fade-in and -out animations on elements to give our users a more pleasant experience when they view our website or app. We use them for elements that get <a href="https://www.ilearnjavascript.com/glossary/#toggle-id-5" target="_blank" rel="noopener">lazyloaded</a>, toggled or whenever we want to make the appearance/ disappearance of something look smooth.</p>
<p>Back in the days most developers probably used jQuery to do the job since it was part of most websites anyway and provided a very convenient way to do it (<a href="https://api.jquery.com/fadeIn/" target="_blank" rel="noopener noreferrer">fadeIn</a>/ <a href="https://api.jquery.com/fadeout/" target="_blank" rel="noopener noreferrer">fadeOut</a>). With jQuery slowly fading out from web development I want to show in this article how to make a fadeIn and fadeOut function in plain javascript.</p>
<p>In order to make an element fade-in/fade-out we essentially need to change its opacity from 0 to 1 in a timeframe that is detectable for the human eye. Please note that changing the opacity of an element can also be done purely via CSS3 and if we just need to do that it is the most preferable because most performant solution. The way how to achieve this with CSS3 would be to either use the</p>
<p><a href="https://www.w3schools.com/css/css3_transitions.asp" target="_blank" rel="noopener noreferrer">transition property:</a></p>
<ul>
<li>set the opacity of the element to either zero or 1 (depending on whether fade-in or fade-out is desired)</li>
<li>set<em> transition: [property] [time] [easing] </em>=&gt; for example <em>transition: opacity .4s ease</em></li>
<li>apply via javascript a new class .fadein/.fadeout to the element with opacity set to zero (fade-out) or 1 (fade-in)</li>
</ul>
<p>or via a</p>
<p><a href="https://css-tricks.com/snippets/css/keyframe-animation-syntax/" target="_blank" rel="noopener noreferrer">keyframe animation:</a></p>
<ul>
<li>create a new keyframe animation @keyframe fadein (or @keyframe fadeout) that goes from <em>opacity: 0</em> to <em>opacity: 1</em> (or <em>opacity: 1</em> to <em>opacity: 0</em>)</li>
<li>apply via javascript a new class .fadein/.fadeout that has all required animation properties =&gt; e.g. <em>animation: fadein .4s linear</em></li>
</ul>
<p>However, with both of these techniques an element that gets faded out still would occupy blank space. It would be invisible but not gone (similar to <em>visibility: hidden</em>)<em>. </em>Sometimes we want the element to be gone and not take any space after it is faded out. We want it to be set to<em> display: none</em>. We can achieve this easily with Javascript.</p>
<p>Please note that I am using ES6 syntax. If you are not familiar with this please see my <a href="https://www.ilearnjavascript.com/es6/" target="_blank" rel="noopener">es6 article series</a> and keep in mind that it needs to be transpiled to ES5 for older browsers via <a href="https://babeljs.io/" target="_blank" rel="noopener noreferrer">babel.io</a>.</p>
<h2>fadeIn</h2>
<p>First we assign an anonymus function to our variable fadeIn that has an element (el) as it&#8217;s first parameter, an option to make a smooth fade-in animation which defaults to true as it&#8217;s second parameter and displayStyle &#8216;block&#8217; as default for it&#8217;s third parameter. We start with setting the elements opacity to zero and apply <em>display: block</em> because we assume that it&#8217;s current value could be <em>display: none</em>. If smooth is not <em>false</em> we declare a variable with <em>let</em> <em>opacity</em>, starting from zero, and also declare another variable <em>let</em> <em>request,</em> without assigning any value yet.</p>
<p>View the code on <a href="https://gist.github.com/ilearnjavascript/8d1e97f48a8751975fe2b6973d5889cd">Gist</a>.</p>
<p>Afterwards we create another anonymus function that is bound to the variable <em>animation</em> and sets the opacity of our element equal to the result of the value from our previously declared opacity variable plus 0.04. After the first iteration the value would be 0 + 0.04 = 0.04, in the second round 0.08 and so on until it reaches the condition being higher or equal to 1.</p>
<p>I chose 0.04 as it creates a fadeIn animation in approximately 400ms. Feel free to play with the numbers to make it optimal for your case. You can use <em>console.time()</em> (in the beginning of your function run) and <em>console.timeEnd()</em> (in the end of your function run) to understand the timings.</p>
<p>Once the condition is passed we make sure that opacity is exactly one and cancel our animation frame (see next step) via the cancelAnimationFrame(fn) method.</p>
<p>View the code on <a href="https://gist.github.com/ilearnjavascript/47436e9bace99336d47b73f3417134eb">Gist</a>.</p>
<p>We use <a href="https://developer.mozilla.org/en-US/docs/Web/API/window/requestAnimationFrame" target="_blank" rel="noopener noreferrer">requestAnimationFrame</a> for creating the iteration because this way we give the control to the browser when to re-render the layout and not force it on it as we would do with either <a href="https://www.w3schools.com/jsref/met_win_settimeout.asp" target="_blank" rel="noopener noreferrer">setTimeout</a> or <a href="https://www.w3schools.com/jsref/met_win_setinterval.asp" target="_blank" rel="noopener noreferrer">setInterval</a>. The &#8220;problem&#8221; with using a recursive setTimeout or setInterval for drawing our animations is that we command the browser at a predefined time to run our animation. Since the browser is single threaded this intervention could lead to a sluggish experience as other javascript (potentially with other animations) may need to be executed too. With requestAnimationFrame the browser controls the redrawing of the layout at an eye-friendly approximate 60hz framerate and provides us with a smooth animation that is not conflicting with any other javascript tasks which may run simultaneously. To be fair it is unlikely that our fade-in or fade-out animation would cause a sluggish experience for the user because it is very fast over but it is generally good practice to use requestAnimationFrame for animations and that&#8217;s why we will go with it.</p>
<p>We assign an anonymus function to our rAf variable that assigns a recursive call to itself via the requestAnimationFrame method. In other words we let the function call itself. Please be careful when you do recursive calls and always define a condition under which it gets cancelled. Otherwise you will create an infinite loop and crash your system/ browser.</p>
<p>We assign the function call to our variable <em>request</em> which we declared earlier. The reason we declared <em>request</em> outside of the rAf function is scope. We need to be able to access it via the cancelAnimationFrame method from within the animation function. We run animation and alter the opacity of our element on each iteration.</p>
<p>View the code on <a href="https://gist.github.com/ilearnjavascript/a85145d737884abbecc370c6acb1fc8d">Gist</a>.</p>
<p>Finally we call our rAf function to get it all started. In case you wonder about the else condition which runs when <em>smooth</em> is set to false: Technically it does ruin the &#8220;fadein experience&#8221; because it would set the element&#8217;s opacity &#8220;instantly&#8221; to 1 but it makes the function more versatile and we can achieve that only with a few lines of code.</p>
<p>View the code on <a href="https://gist.github.com/ilearnjavascript/ac50beeadaf1dafc53c1a0e12154e671">Gist</a>.</p>
<h2>fadeOut</h2>
<p>The fadeOut method is basically an inverted function of our previous explained fadeIn method. I will not go through it in such detail because it is essentially the same as the fadein method just altering the opacity from 1 back to zero and applying <em>display: none</em> in the end right before the iteration gets stopped to leave no blank space behind.</p>
<p>View the code on <a href="https://gist.github.com/ilearnjavascript/f1faf3280473e7b5a3830e1c661eb846">Gist</a>.</p>
</div></section><br />

<style type="text/css" data-created_by="avia_inline_auto" id="style-css-av-jsm56dz6-c6cf5812234ac3bae2a3b34780952756">
#top .hr.hr-invisible.av-jsm56dz6-c6cf5812234ac3bae2a3b34780952756{
height:50px;
}
</style>
<div  class='hr av-jsm56dz6-c6cf5812234ac3bae2a3b34780952756 hr-invisible  avia-builder-el-3  el_after_av_textblock  el_before_av_comments_list '><span class='hr-inner '><span class="hr-inner-style"></span></span></div><br />
<div  class='av-buildercomment av-2ruuea-5d0b64f49ac6d97814b6ef45d01162b0'></div></p></div>
<p>The post <a href="https://www.ilearnjavascript.com/plainjs-fadein-fadeout/">PlainJS: fade-in &#038; fade-out</a> appeared first on <a href="https://www.ilearnjavascript.com">I Learn Javascript</a>.</p>
]]></content:encoded>
					
		
		
			</item>
		<item>
		<title>PlainJS: postMessage() and iframes</title>
		<link>https://www.ilearnjavascript.com/plainjs-postmessage-and-iframes/</link>
		
		<dc:creator><![CDATA[ILJS]]></dc:creator>
		<pubDate>Wed, 06 Mar 2019 19:43:51 +0000</pubDate>
				<category><![CDATA[Javascript]]></category>
		<category><![CDATA[PlainJS]]></category>
		<category><![CDATA[javascript]]></category>
		<category><![CDATA[plainjs]]></category>
		<guid isPermaLink="false">https://www.ilearnjavascript.com/?p=827</guid>

					<description><![CDATA[<p>How to communicate between a window and an embedded iFrame via postMessage.</p>
<p>The post <a href="https://www.ilearnjavascript.com/plainjs-postmessage-and-iframes/">PlainJS: postMessage() and iframes</a> appeared first on <a href="https://www.ilearnjavascript.com">I Learn Javascript</a>.</p>
]]></description>
										<content:encoded><![CDATA[
<style type="text/css" data-created_by="avia_inline_auto" id="style-css-av-jsm56n9k-b89ad28a2e87aea11f86249f3e974975">
.flex_column.av-jsm56n9k-b89ad28a2e87aea11f86249f3e974975{
border-radius:0px 0px 0px 0px;
padding:0px 0px 0px 0px;
}
</style>
<div  class='flex_column av-jsm56n9k-b89ad28a2e87aea11f86249f3e974975 av_one_full  avia-builder-el-0  avia-builder-el-no-sibling  blogpost first flex_column_div av-zero-column-padding  '     ><p>
<style type="text/css" data-created_by="avia_inline_auto" id="style-css-av-jzu3o4qe-b1146c47711287d85e4bc89ff46cb642">
#top .av-special-heading.av-jzu3o4qe-b1146c47711287d85e4bc89ff46cb642{
padding-bottom:10px;
}
body .av-special-heading.av-jzu3o4qe-b1146c47711287d85e4bc89ff46cb642 .av-special-heading-tag .heading-char{
font-size:25px;
}
.av-special-heading.av-jzu3o4qe-b1146c47711287d85e4bc89ff46cb642 .av-subheading{
font-size:14px;
}
</style>
<div  class='av-special-heading av-jzu3o4qe-b1146c47711287d85e4bc89ff46cb642 av-special-heading-h1 blockquote modern-quote  avia-builder-el-1  el_before_av_textblock  avia-builder-el-first '><h1 class='av-special-heading-tag '  itemprop="headline"  >PlainJS: postMessage() and iFrames</h1><div class='av-subheading av-subheading_below'><p>12min read</p>
</div><div class="special-heading-border"><div class="special-heading-inner-border"></div></div></div><br />
<section  class='av_textblock_section av-jsxpv2aj-a70af1baa44283dc0386ec397195a3ff '   itemscope="itemscope" itemtype="https://schema.org/BlogPosting" itemprop="blogPost" ><div class='avia_textblock'  itemprop="text" ><p>Many websites, especially blogs or newssites, earn money with advertising. A common way to display these ads is through <a href="https://www.ilearnjavascript.com/glossary/#toggle-id-3" target="_blank" rel="noopener noreferrer">iFrames</a>. In this article I will explain how to communicate between a <em>window</em> and an embedded iFrame.</p>
<p>In general the <a href="https://developer.mozilla.org/en-US/docs/Web/Security/Same-origin_policy">same-origin policy</a> forbids scripts on different pages to access each other unless they share the same protocol, port number and host. The <em>window.postMessage() </em>method enables cross-origin communication between a window object and an embedded iFrame and therefore provides a mechanism to circumvent this restriction. PostMessage used incorrectly could potentially make your website vulnerable for crosssite-scripting attacks. It is important to be aware of these pitfalls before we use it in production.</p>
<h2>Listening for a message</h2>
<p>First we need to setup a listener function on our <em>window</em> (we will call it outer window from now on to differentiate since each iFrame also owns its own window) which executes code when the <em>message</em> event gets fired from our iFrame via <em>postMessage()</em>. Allowing the outer window to receive messages from an embedded iframe is a potential risk for cross-site scripting attacks. It is therefore important to verify the <em>event.origin</em> of the <em>window</em> that send the message and only allow controlled <em>event.data</em> to reach our outer window. Lets go through the terminology first:</p>
<ol>
<li><em>event.origin</em> = The origin of the window that sent the message at the time <em>postMessage</em> was called. We want this to be a domain we trust.</li>
<li><em>event.data</em> = The data that gets passed through with the <em>postMessage</em> function.</li>
<li><em>event.source</em> = Reference to the window that sent the message. In our case the iFrame.</li>
<li><em>postMessage()</em> = function we call in order to pass data to another window.</li>
</ol>
<p>We will create a receiveMessage Function on our outer window, check if the <em>event.origin</em> is the domain of our iframe and if <em>event.data</em> is the message we exppect. Then we listen via the addEventListener method for the <em>message</em> event and bind the <em>receiveMessage()</em> function to it.</p>
<p>View the code on <a href="https://gist.github.com/ilearnjavascript/c9095d2d5bb1e74d176372502faac31d">Gist</a>.</p>
<p>We could generally make it even more safe by restricting <em>event.data</em> to a specific length and test for <em>typeof string</em> since we expect a string. So lets add this:</p>
<p>View the code on <a href="https://gist.github.com/ilearnjavascript/451ecda2e7c4de2bc9b95a28dac3cb02">Gist</a>.</p>
<h2>Sending a message</h2>
<p>We send a message via the postMessage function. The syntax for it is:</p>
<p>View the code on <a href="https://gist.github.com/ilearnjavascript/7b2fb314e732e054e003d1287b47dcc6">Gist</a>.</p>
<p>The targetWindow in our case could be either <em>window.parent</em> (immediate parent window) or <em>window.top</em> (the most far outer window) because they are the same in our scenario. But since it is generally possible to nest multiple Iframes it is important to be aware of the difference. In doubt pick window.top because it will definitely reach the client window and not another parent Iframe by accident. As message we will send &#8220;message we expect&#8221; and the targetOrigin is the domain of our outer window&#8217;s domain.</p>
<p>View the code on <a href="https://gist.github.com/ilearnjavascript/4105bc66799179b611321558885a2292">Gist</a>.</p>
<p>Note: Avoid using &#8220;*&#8221; for the targetOrigin and specify it properly instead with the domain of your outer window.</p>
<h3>Working Example</h3>
<p>Here is an working example. If you want to test it just</p>
<ol>
<li>copy the code from both files (I named them window.html and iframe.html) into a directory</li>
<li>setup a small local server (I use for this https://www.npmjs.com/package/http-server) for each of the files</li>
<li>run it within the directory and choose to display window.html for the server located on http://127.0.0.1:8080 and the iframe.html on http://127.0.0.1:8081</li>
<li>play with it</li>
</ol>
<h4>window.html</h4>
<p>View the code on <a href="https://gist.github.com/ilearnjavascript/0a793e2732e17788900c12fbf0b37c91">Gist</a>.</p>
<h4>Iframe.html</h4>
<p>View the code on <a href="https://gist.github.com/ilearnjavascript/8edbf5e143c962b8f3e85c1997614aac">Gist</a>.</p>
<h2>Two Way Communication</h2>
<p>So far we looked at a one way communication in which we receive a message from an iFrame. But what if we want to have a two way communication and send something back from our outer window to the iFrame? If we embed our iFrame on the <strong>same domain</strong> as the window we can use the <em>postMessage()</em> function and <em>event.source</em> for achieving exactly this. We use <em>event.source</em> to get a reference to our iframe and trigger the <em>postMessage()</em> function from it.</p>
<h3>Working Example</h3>
<p>We will trigger <em>event.source.postMessage()</em> with a one second delay from our window.html to visualize the chronology of the functions getting triggered. In order for the iframe.html to show a response we also need to setup a<em> receiveMessage()</em> function there and bind it to the iframe&#8217;s <em>window</em> via <em>window.addEventlistener(&#8216;message&#8217;, receiveMessage, false)</em>.</p>
<ol>
<li>copy the code from both files (I named them window.html and iframe.html) into a directory</li>
<li>setup a small local server (I use for this https://www.npmjs.com/package/http-server) for both of the files</li>
<li>run it within the directory and choose to display window.html for the server located on http://127.0.0.1:8080</li>
<li>play with it</li>
</ol>
<h4>window.html</h4>
<p>View the code on <a href="https://gist.github.com/ilearnjavascript/9d4855b9a189b1144d675c1cb8f52179">Gist</a>.</p>
<h4>Iframe.html</h4>
<p>View the code on <a href="https://gist.github.com/ilearnjavascript/385e3f6af6d301e140baf4c03249e08f">Gist</a>.</p>
<h2>Security concerns</h2>
<p>A listener for a <em>message</em> event should only be applied to your website if you generally expect a postMessage. Cross-site scripting attacks are a real risk. Failure to check the <em>origin, data </em>and potentially<em> source </em>properties could make your website vulnerable. Always specify an exact target origin and do not just use &#8220;*&#8221; with <em>postMessage()</em> to send data to other windows. A potential attacker could change the location of the window and intercept the data sent using <em>postMessage()</em>. Add extra levels of security by restricting the <em>event.data</em> to a type and length (if applicable).</p>
</div></section><br />

<style type="text/css" data-created_by="avia_inline_auto" id="style-css-av-jsm56dz6-c6cf5812234ac3bae2a3b34780952756">
#top .hr.hr-invisible.av-jsm56dz6-c6cf5812234ac3bae2a3b34780952756{
height:50px;
}
</style>
<div  class='hr av-jsm56dz6-c6cf5812234ac3bae2a3b34780952756 hr-invisible  avia-builder-el-3  el_after_av_textblock  el_before_av_comments_list '><span class='hr-inner '><span class="hr-inner-style"></span></span></div><br />
<div  class='av-buildercomment av-7d32r-9d486d985b57f31e9e677555abdb4223'></div></p></div>
<p>The post <a href="https://www.ilearnjavascript.com/plainjs-postmessage-and-iframes/">PlainJS: postMessage() and iframes</a> appeared first on <a href="https://www.ilearnjavascript.com">I Learn Javascript</a>.</p>
]]></content:encoded>
					
		
		
			</item>
	</channel>
</rss>
