JavaScript Function Population

Will anyone think to explain to me what is the difference between these scenarios below? The first one found here in Stack Overflow, the second is my own version, which I understand better, but does not work. Why doesn't it work, by the way?

one.

(function blink() { $('.blinkMe').fadeOut(500).fadeIn(500, blink); })(); 

2.

 function blink() { $('.blinkMe').fadeOut(500).fadeIn(500, blink); blink(); } blink(); 
+6
source share
6 answers

The first example is an Immediately Invoked Function ( IIFE ) expression . This is a function that immediately does its job after being created. IIFE is a common JavaScript design pattern used by most popular libraries (jQuery, Backbone.js, Modernizr, etc.) to put all the library code inside a local area.

In ES6, this can be rewritten using the Arrow function if you want .blinkMe to .blinkMe only once

 (() => $('.blinkMe').fadeOut(500).fadeIn(500))(); 

You can combine as many fadeIn and fadeOut functions as you want. If you want it to loop infinitely, I would suggest an IIFE path.

Read more about IIFE here .


About your second example. You call a function inside your own function (also called a recursive loop). In your case, this creates an infinite loop, so it does not work. Remove blink(); inside the function and it will work:

 function blink() { $('.blinkMe').fadeOut(500).fadeIn(500, blink); } blink(); 

In addition, with javascript, you can also solve this problem with CCS3 animation. CSS3 animations run in a separate thread. This is a solution without jQuery:

 (function blink() { document.getElementsByClassName('blinkMe')[0].className += ' blinkActive'; })(); // Arrow function: //(() => document.getElementsByClassName('blinkMe')[0].className += ' blinkActive')(); 
 .blinkMe { width: 80px; height: 80px; background: deepskyblue; } .blinkActive { -webkit-animation: blink 1s infinite; animation: blink 1s infinite; } @-webkit-keyframes blink { 0%, 100% { opacity: 1; } 50% { opacity: 0; } } @keyframes blink { 0%, 100% { opacity: 1; } 50% { opacity: 0; } } 
 <div class="blinkMe"></div> 

I do not know how many elements you want to blink on your page, if only one element you can use ids instead of classes. Keep in mind that the @keyframes rule @keyframes not supported in IE9 or earlier, and Opera Mini: Link .

+11
source

The first is IIFE . That is, the function is immediately called (executed) after its declaration. It is not tied to the global window object and therefore does not pollute it.

The second function is exponentially recursive. Each time it starts, it calls itself twice, once as a callback to the fadeIn jquery method, and once again in the function body.

+7
source

Line $('.blinkMe').fadeOut(500).fadeIn(500, blink); already causes blink at completion. Therefore, the blink() call resembles a double function (and even more for each call). So this call was a problem.

EDIT: But, as I just found out today, timers do not execute on another thread in JavaScript. Thus, blink() in the blink function accepts all execution frames, and the blink callback is never called, but it is still registered for the call. Since, I tested by adding the maximum number of iterations that could be called inside blink() .

 function blink() { $('.blinkMe').fadeOut(500).fadeIn(500, blink); //blink(); } blink(); 
 <script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script> <span class="blinkMe">Blinking</span> 
+6
source

A named function is created in this snippet, then immediately executed once in the Immediately-Invoked Function Expression expression . The name of the function is available only to itself, so it can be called again in closing the body of the function, in this case as a callback to the fadeIn function.

 (function blink() { $('.blinkMe').fadeOut(500).fadeIn(500, blink); })(); 


In this fragment, a named function is created and called. In addition, the function calls itself again, which creates infinite recursion, so it fails. Unlike the last fragment, blink will also be available outside the closure of the function.

 function blink() { $('.blinkMe').fadeOut(500).fadeIn(500, blink); blink(); } blink(); 

Removing the blink() call inside the function itself, as shown below, will make it almost identical, except for the difference in the blink .

 function blink() { $('.blinkMe').fadeOut(500).fadeIn(500, blink); } blink(); 
+6
source

This is a recursive function (animation).

According to jQuery docs , fadeIn() takes two arguments: duration (in ms) and complete . The second argument is a function that is called after the animation finishes. It can be itself or another function.

In the second function, you call blink() again and again ... but the second and third never call. The best way is the first.

+2
source

Your function works, but Navigator blocks it due to too much recursion. because you cause blinking () right after you fadeIn just try,

 function blink() { $('.blinkMe').fadeOut(500).fadeIn(500, blink); //remove this call which causes too many recursions //blink(); } //then call the method blink(); 
+2
source

All Articles