diff options
author | Peter Bengtsson <mail@peterbe.com> | 2020-12-08 14:41:45 -0500 |
---|---|---|
committer | Peter Bengtsson <mail@peterbe.com> | 2020-12-08 14:41:45 -0500 |
commit | 1109132f09d75da9a28b649c7677bb6ce07c40c0 (patch) | |
tree | 0dd8b084480983cf9f9680e8aedb92782a921b13 /files/es/learn/javascript/building_blocks | |
parent | 4b1a9203c547c019fc5398082ae19a3f3d4c3efe (diff) | |
download | translated-content-1109132f09d75da9a28b649c7677bb6ce07c40c0.tar.gz translated-content-1109132f09d75da9a28b649c7677bb6ce07c40c0.tar.bz2 translated-content-1109132f09d75da9a28b649c7677bb6ce07c40c0.zip |
initial commit
Diffstat (limited to 'files/es/learn/javascript/building_blocks')
8 files changed, 3314 insertions, 0 deletions
diff --git a/files/es/learn/javascript/building_blocks/bucle_codigo/index.html b/files/es/learn/javascript/building_blocks/bucle_codigo/index.html new file mode 100644 index 0000000000..e26509afc5 --- /dev/null +++ b/files/es/learn/javascript/building_blocks/bucle_codigo/index.html @@ -0,0 +1,923 @@ +--- +title: Bucles +slug: Learn/JavaScript/Building_blocks/Bucle_codigo +translation_of: Learn/JavaScript/Building_blocks/Looping_code +--- +<div>{{LearnSidebar}}</div> + +<div>{{PreviousMenuNext("Learn/JavaScript/Building_blocks/conditionals","Learn/JavaScript/Building_blocks/Functions", "Learn/JavaScript/Building_blocks")}}</div> + +<p class="summary">Los lenguajes de programación son muy útiles para completar rápidamente tareas repetitivas, desde múltimples cálculos básicos hasta cualquier otra situación en donde tengas un montón de elementos de trabajo similares que completar. Aquí vamos a ver las estructuras de bucles disponibles en JavaScript que pueden manejar tales necesidades.</p> + +<table class="learn-box standard-table"> + <tbody> + <tr> + <th scope="row">Prerequisitos:</th> + <td>Conocimientos básicos de computación, entendimiento básico de HTML y CSS, <a href="/en-US/docs/Learn/JavaScript/First_steps">JavaScript first steps</a>.</td> + </tr> + <tr> + <th scope="row">Objetivo:</th> + <td>Entender cómo usar bucles en JavaScript.</td> + </tr> + </tbody> +</table> + +<h2 id="Mantente_en_el_Bucle">Mantente en el Bucle</h2> + +<p>Bucles, bucles, bucles. Además de ser conocidos como un cereal de desayuno popular, montañas rusas y producción músical, también son un concepto muy importante en programación. Los bucles de programación están relacionados con todo lo referente a hacer una misma cosa una y otra vez — que se denomina como <strong>iteración </strong>en el idioma de programación.</p> + +<p>Consideremos el caso de un agricultor que se asegura de tener suficiente comida para alimentar a su familia durante la semana. Podría usar el siguiente bucle para lograr esto:</p> + +<p><br> + <img alt="" src="https://mdn.mozillademos.org/files/13755/loop_js-02-farm.png" style="display: block; margin: 0 auto;"></p> + +<p>Un bucle cuenta con una o más de las siguientes características:</p> + +<ul> + <li> Un <strong>contador,</strong> que se inicia con un determinado valor — este será el valor del punto inicial del bucle ("Inicio: No tengo comida",mirar arriba).</li> + <li>Una <strong>condicion de salida</strong>, que será el criterio bajo el cual, el bucle se romperá — normalmente un contador que alcanza un determinado valor. Aquí se ilustra como "¿Tengo suficiente comida?", arriba. Digamos que son necesarias 10 porciones de comida para alimentar a su familia.</li> + <li>Un <strong>iterador, </strong>que generalmente incrementa el valor del contador en una cantidad pequeña a cada paso del bucle, hasta que alcanza la condición de salida. No hemos ilustrado esto de manera explícita arriba, pero podríamos pensar que el granjero está recolectando 2 porciones de comida cada hora. Después de cada hora, la cantidad de comida recolectada se incrementa en dos, y comprueba si tiene suficiente comida. Si alcanza los 10 puntos (la condición de salida), puede parar la recolecta e irse para casa.</li> +</ul> + +<p>En {{glossary("pseudocódigo")}},esto se vería como sigue:</p> + +<pre class="notranslate">bucle(comida = 0; comidaNecesaria = 10) { + if (comida = comidaNecesaria) { + salida bucle; + // Tenemos suficiente comida; vamonos para casa + } else { + comida += 2; // Pasar una hora recogiendo 2 más de comida + // Comenzar el bucle de nuevo + } +}</pre> + +<p>Así que la cantidad necesaria de comida se establece en 10, y la cantidad incial del granjero en 0. En cada iteración del bucle comprobamos si la cantidad de comida del granjero es mayor o igual a la cantidad que necesita. Si lo es, podemos salir del bucle. Si no, el granjero se pasará una hora más recogiendo dos porciones de comida, y el bucle arrancará de nuevo.</p> + +<h3 id="¿Por_qué_molestarse">¿Por qué molestarse?</h3> + +<p><span class="tlid-translation translation" lang="es"><span title="">En este punto, probablemente entiendas los conceptos de alto nivel que hay detrás de los bucles,</span></span> pero probablemente estés pensando "OK, fantástico, pero ¿cómo me ayuda esto a escribir un mejor codigo JavaScript?". Como dijimos antes, <strong>los bucles tienen que ver con hacer lo mismo una y otra vez</strong>, lo cual es bueno para <strong>completar rápidamente tareas repetitivas</strong>.</p> + +<p>Muchas veces, el código será ligeramente diferente en cada iteracción sucesiva del bucle, lo que significa que puedes completar una carga completa de tareas que son similares, pero ligeramente diferentes — si tienes muchos calculos diferentes que hacer, quieres hacer cada uno de ellos, ¡no el mismo una y otra vez!</p> + +<p>Vamos a ver un ejemplo para ilustrar perfectamente por qué los bucles son tan útiles. Digamos que queremos dibujar 100 círculos aleatorios en un elemento {{htmlelement("canvas")}} (presiona el botón <em>Update</em> para ejecutar el ejemplo una y otra vez y ver diferentes configuraciones aleatorias):</p> + +<div class="hidden"> +<h6 id="Hidden_code">Hidden code</h6> + +<pre class="brush: html notranslate"><!DOCTYPE html> +<html> + <head> + <meta charset="utf-8"> + <title>Random canvas circles</title> + <style> + html { + width: 100%; + height: inherit; + background: #ddd; + } + + canvas { + display: block; + } + + body { + margin: 0; + } + + button { + position: absolute; + top: 5px; + left: 5px; + } + </style> + </head> + <body> + + <button>Update</button> + + <canvas></canvas> + + + <script> + var btn = document.querySelector('button'); + var canvas = document.querySelector('canvas'); + var ctx = canvas.getContext('2d'); + + var WIDTH = document.documentElement.clientWidth; + var HEIGHT = document.documentElement.clientHeight; + + canvas.width = WIDTH; + canvas.height = HEIGHT; + + function random(number) { + return Math.floor(Math.random()*number); + } + + function draw() { + ctx.clearRect(0,0,WIDTH,HEIGHT); + for (var i = 0; i < 100; i++) { + ctx.beginPath(); + ctx.fillStyle = 'rgba(255,0,0,0.5)'; + ctx.arc(random(WIDTH), random(HEIGHT), random(50), 0, 2 * Math.PI); + ctx.fill(); + } + } + + btn.addEventListener('click',draw); + + </script> + + </body> +</html></pre> +</div> + +<p>{{ EmbedLiveSample('Hidden_code', '100%', 400, "", "", "hide-codepen-jsfiddle") }}</p> + +<p>No tienes que entender todo el código por ahora, pero vamos a echar un vistazo a la parte de código que dibuja los 100 círculos:</p> + +<pre class="brush: js notranslate">for (var i = 0; i < 100; i++) { + ctx.beginPath(); + ctx.fillStyle = 'rgba(255,0,0,0.5)'; + ctx.arc(random(WIDTH), random(HEIGHT), random(50), 0, 2 * Math.PI); + ctx.fill(); +}</pre> + +<p>Debes quedarte con la idea básica. — utilizamos un bucle para ejecutar 100 iteracciones de este código, cada una de las cuales dibuja un círculo en una posición aleatoria de la página. La cantidad de código necesario sería el mismo si dibujáramos 100, 1000, o 10,000 círculos. Solo necesitamos cambiar un número.</p> + +<p>Si no usáramos un bucle aquí, tendríamos que repetir el siguiente código por cada círculo que quisiéramos dibujar:</p> + +<pre class="brush: js notranslate">ctx.beginPath(); +ctx.fillStyle = 'rgba(255,0,0,0.5)'; +ctx.arc(random(WIDTH), random(HEIGHT), random(50), 0, 2 * Math.PI); +ctx.fill();</pre> + +<p>Esto sería muy aburrido y difícil de mantener de forma rápida. Los bucles son realmente lo mejor.</p> + +<h2 id="El_bucle_estándar_for">El bucle estándar <code>for</code></h2> + +<p>Exploremos algunos constructores de bucles específicos. El primero, que usarás la mayoría de las veces, es el bucle <a href="/es/docs/Web/JavaScript/Referencia/Sentencias/for">for</a> - este tiene la siguiente sintaxis:</p> + +<pre class="notranslate">for (inicializador; condición de salida; expresión final) { + // código a ejecutar +}</pre> + +<p>Aquí tenemos:</p> + +<ol> + <li>La palabra reservada <code>for</code>, seguida por algunos paréntesis.</li> + <li>Dentro de los paréntesis tenemos tres ítems, separados por punto y coma (;): + <ol> + <li>Un <strong>inicializador</strong> - Este es usualmente una variable con un número asignado, que aumenta el número de veces que el bucle ha sijo ejecutado. También se le llama <strong>contador</strong> o <strong>variable de conteo</strong>.</li> + <li>Una <strong>condición de salida</strong> - como se mencionó previamente, ésta define cuando el bucle debería detenerse. Generalmente es una expresión que contiene un operador de comparación, una prueba para verificar ue la condición de término o salida ha sido cumplida.</li> + <li>Una <strong>expresión final</strong> - que es siempre evaluada o ejecutada cada vez que el bucle ha completado una iteración. Usualmente sirve para modificar al contador (incrementando su valor o algunas veces disminuyendolo), para aproximarse a la condición de salida.</li> + </ol> + </li> + <li>Algunos corchetes curvos que contienen un bloque de código - este código se ejecutará cada vez que se repita el bucle.</li> +</ol> + +<p>Observa un ejemplo real para poder entender esto más claramente.</p> + +<pre class="brush: js notranslate">var cats = ['Bill', 'Jeff', 'Pete', 'Biggles', 'Jasmin']; +var info = 'My cats are called '; +var para = document.querySelector('p'); + +for (var i = 0; i < cats.length; i++) { + info += cats[i] + ', '; +} + +para.textContent = info;</pre> + +<p>Esto nos da el siguiente resultado:</p> + +<div class="hidden"> +<h6 id="Hidden_code_2">Hidden code 2</h6> + +<pre class="brush: html notranslate"><!DOCTYPE html> +<html> + <head> + <meta charset="utf-8"> + <title>Basic for loop example</title> + <style> + + </style> + </head> + <body> + + <p></p> + + + <script> + var cats = ['Bill', 'Jeff', 'Pete', 'Biggles', 'Jasmin']; + var info = 'My cats are called '; + var para = document.querySelector('p'); + + for (var i = 0; i < cats.length; i++) { + info += cats[i] + ', '; + } + + para.textContent = info; + + </script> + + </body> +</html></pre> +</div> + +<p>{{ EmbedLiveSample('Hidden_code_2', '100%', 60, "", "", "hide-codepen-jsfiddle") }}</p> + +<div class="note"> +<p><strong>Nota</strong>: Puedes encontrar este <a href="https://github.com/mdn/learning-area/blob/master/javascript/building-blocks/loops/basic-for.html">ejemplo de código en GitHub</a> también (además puedes <a href="http://mdn.github.io/learning-area/javascript/building-blocks/loops/basic-for.html">verlo ejecutar en vivo</a>).</p> +</div> + +<p>Esto muestra un bucle siendo usado para iterar sobre los elementos de un arreglo (matriz), y hacer algo con cada uno de ellos - un patrón muy común en JavaScript. Aquí:</p> + +<ol> + <li>El iterador, <code>i</code>, inicia en <code>0</code> (<code>var i = 0</code>).</li> + <li>Se le ha dicho que debe ejecutarse hasta que no sea menor que la longitud del arreglo <code>cats</code>. Esto es importante - la condición de salida muestra la condicion bajo la cual el bucle seguirá iterando. Así, en este caso, mientras <code>i < cats.length</code> sea verdadero, el bucle seguirá ejecutándose.</li> + <li>Dentro del bucle, concatenamos el elemento del bucle actual (<code>cats[i]</code> es <code>cats[lo que sea i en ese momento]</code>) junto con una coma y un espacio, al final de la variable <code>info</code>. Así: + <ol> + <li>Durante la primera ejecución, <code>i = 0</code>, así <code>cats[0] + ', '</code> se concatenará con la información ("Bill, ").</li> + <li>Durante la segunda ejecución, <code>i = 1</code>, así <code>cats[1] + ', '</code> agregará el siguiente nombre ("Jeff, ").</li> + <li>Y así sucesivamente. Después de cada vez que se ejecute el bucle, se incrementará en 1 el valod de i (<code>i++</code>), entonces el proceso comenzará de nuevo.</li> + </ol> + </li> + <li>Cuando <code>i</code> sea igual a <code>cats.length</code>, el bucle se detendrá, y el navegador se moverá al siguiente segmento de código bajo el bucle.</li> +</ol> + +<div class="note"> +<p><strong>Nota</strong>: Hemos programado la condición de salidad como <code>i < cats.length</code>, y no como <code>i <= cats.length</code>, porque los computadores cuentan desde 0, no 1 - inicializamos la variable i en 0, para llegar a <code>i = 4</code> (el índice del último elemento del arreglo). <code>cats.length</code> responde 5, ya que existen 5 elementos en el arreglo, pero no queremos que i = 5, dado que respondería <code>undefined</code> para el último elemento (no existe un elemento en el arreglo con un índice 5). for the last item (there is no array item with an index of 5). Por ello, queremos llegar a 1 menos que <code>cats.length</code> (<code>i <</code>), que no es lo mismo que <code>cats.length</code> (<code>i <=</code>).</p> +</div> + +<div class="note"> +<p><strong>Nota</strong>: Un error común con la condición de salida es utilizar el comparador "igual a" (<code>===</code>) en vez de "menor o igual a" (<code><=</code>). Si queremos que nuestro bucle se ejecute hasta que <code>i = 5</code>, la condición de salida debería ser <code>i <= cats.length</code>. Si la declaramos <code>i === cats.length</code>, el bucle no debería ejecutarse , porque <code>i</code> no es igual a <code>5</code> en la primera iteración del bucle, por lo que debería detenerse inmediatamente.</p> +</div> + +<p>Un pequeño problema que se presenta es que la frase de salida final no está muy bien formada:</p> + +<blockquote> +<p>My cats are called Bill, Jeff, Pete, Biggles, Jasmin,</p> +</blockquote> + +<p>Idealmente querríamos cambiar la concatenacion al final de la última iteracion del bucle, así no tendríamos una coma en el final de la frase. Bueno, no hay problema - podemos insertar un condicional dentro de nuestro bucle para solucionar este caso especial:</p> + +<pre class="brush: js notranslate">for (var i = 0; i < cats.length; i++) { + if (i === cats.length - 1) { + info += 'and ' + cats[i] + '.'; + } else { + info += cats[i] + ', '; + } +}</pre> + +<div class="note"> +<p><strong>Note</strong>: You can find this <a href="https://github.com/mdn/learning-area/blob/master/javascript/building-blocks/loops/basic-for-improved.html">example code on GitHub</a> too (also <a href="http://mdn.github.io/learning-area/javascript/building-blocks/loops/basic-for-improved.html">see it running live</a>).</p> +</div> + +<div class="warning"> +<p><strong>Importante</strong>: Con <code>for</code> - como con todos los bucles - debes estar seguro de que el inicializador es repetido hasta que eventualemtne alcance la condición de salida. Si no, el bucle seguirá repitiéndose indefinidamente, y puede que el navegador lo fuerce a detenerse o se interrumpa. Esto se denomina <strong>bucle infinito</strong>.</p> +</div> + +<h2 id="Salir_de_un_bucle_con_break">Salir de un bucle con <code>break</code></h2> + +<p>Si deseas salir de un bucle antes de que se hayan completado todas las iteraciones, puedes usar la declaración <a href="/es/docs/Web/JavaScript/Referencia/Sentencias/break">break</a>. Ya la vimos en el artículo previo cuando revisamos la declaración <a href="/es/docs/Web/JavaScript/Referencia/Sentencias/switch">switch</a> - cuando un caso en una declaración <code>switch</code> coincide con la expresión de entrada, la declaración <code>break</code> inmediatamente sale de la declaración <code>switch</code> y avanza al código que se encuentra después.</p> + +<p>Ocurre lo mismo con los bucles - una declaración <code>break</code> saldrá inmediatamente del bucle y hará que el navegador siga con el código que sigue después.</p> + +<p>Digamos que queremos buscar a través de un arreglo de contactos y números telefónicos y retornar sólo el número que queríamos encontrar. primero, un simple HTML - un {{htmlelement("input")}} de texto que nos permita ingresar un nombre para buscar, un elemento {{htmlelement("button")}} para enviar la búsqueda, y un elemento {{htmlelement("p")}} para mostrar el resultado:</p> + +<pre class="brush: html notranslate"><label for="search">Search by contact name: </label> +<input id="search" type="text"> +<button>Search</button> + +<p></p></pre> + +<p>Ahora en el JavaScript:</p> + +<pre class="brush: js notranslate">var contacts = ['Chris:2232322', 'Sarah:3453456', 'Bill:7654322', 'Mary:9998769', 'Dianne:9384975']; +var para = document.querySelector('p'); +var input = document.querySelector('input'); +var btn = document.querySelector('button'); + +btn.addEventListener('click', function() { + var searchName = input.value; + input.value = ''; + input.focus(); + for (var i = 0; i < contacts.length; i++) { + var splitContact = contacts[i].split(':'); + if (splitContact[0] === searchName) { + para.textContent = splitContact[0] + '\'s number is ' + splitContact[1] + '.'; + break; + } else { + para.textContent = 'Contact not found.'; + } + } +});</pre> + +<div class="hidden"> +<h6 id="Hidden_code_3">Hidden code 3</h6> + +<pre class="brush: html notranslate"><!DOCTYPE html> +<html> + <head> + <meta charset="utf-8"> + <title>Simple contact search example</title> + <style> + + </style> + </head> + <body> + + <label for="search">Search by contact name: </label> + <input id="search" type="text"> + <button>Search</button> + + <p></p> + + + <script> + var contacts = ['Chris:2232322', 'Sarah:3453456', 'Bill:7654322', 'Mary:9998769', 'Dianne:9384975']; + var para = document.querySelector('p'); + var input = document.querySelector('input'); + var btn = document.querySelector('button'); + + btn.addEventListener('click', function() { + var searchName = input.value; + input.value = ''; + input.focus(); + for (var i = 0; i < contacts.length; i++) { + var splitContact = contacts[i].split(':'); + if (splitContact[0] === searchName) { + para.textContent = splitContact[0] + '\'s number is ' + splitContact[1] + '.'; + break; + } else { + para.textContent = 'Contact not found.'; + } + } + }); + </script> + + </body> +</html></pre> +</div> + +<p>{{ EmbedLiveSample('Hidden_code_3', '100%', 100, "", "", "hide-codepen-jsfiddle") }}</p> + +<ol> + <li>First of all we have some variable definitions — we have an array of contact information, with each item being a string containing a name and phone number separated by a colon.</li> + <li>Next, we attach an event listener to the button (<code>btn</code>), so that when it is pressed, some code is run to perform the search and return the results.</li> + <li>We store the value entered into the text input in a variable called <code>searchName</code>, before then emptying the text input and focusing it again, ready for the next search.</li> + <li>Now onto the interesting part, the for loop: + <ol> + <li>We start the counter at <code>0</code>, run the loop until the counter is no longer less than <code>contacts.length</code>, and increment <code>i</code> by 1 after each iteration of the loop.</li> + <li>Inside the loop we first split the current contact (<code>contacts[i]</code>) at the colon character, and store the resulting two values in an array called <code>splitContact</code>.</li> + <li>We then use a conditional statement to test whether <code>splitContact[0]</code> (the contact's name) is equal to the inputted <code>searchName</code>. If it is, we enter a string into the paragraph to report what the contact's number is, and use <code>break</code> to end the loop.</li> + </ol> + </li> + <li>If the contact name does not match the entered search, the paragraph text is set to "Contact not found.", and the loop continues iterating.</li> +</ol> + +<div class="note"> +<p>Note: You can view the <a href="https://github.com/mdn/learning-area/blob/master/javascript/building-blocks/loops/contact-search.html">full source code on GitHub</a> too (also <a href="http://mdn.github.io/learning-area/javascript/building-blocks/loops/contact-search.html">see it running live</a>).</p> +</div> + +<h2 id="Skipping_iterations_with_continue">Skipping iterations with continue</h2> + +<p>The <a href="/en-US/docs/Web/JavaScript/Reference/Statements/continue">continue</a> statement works in a similar manner to <code>break</code>, but instead of breaking out of the loop entirely, it skips to the next iteration of the loop. Let's look at another example that takes a number as an input, and returns only the numbers that are squares of integers (whole numbers).</p> + +<p>The HTML is basically the same as the last example — a simple text input, and a paragraph for output. The JavaScript is mostly the same too, although the loop itself is a bit different:</p> + +<pre class="brush: js notranslate">var num = input.value; + +for (var i = 1; i <= num; i++) { + var sqRoot = Math.sqrt(i); + if (Math.floor(sqRoot) !== sqRoot) { + continue; + } + + para.textContent += i + ' '; +}</pre> + +<p>Here's the output:</p> + +<div class="hidden"> +<h6 id="Hidden_code_4">Hidden code 4</h6> + +<pre class="brush: html notranslate"><!DOCTYPE html> +<html> + <head> + <meta charset="utf-8"> + <title>Integer squares generator</title> + <style> + + </style> + </head> + <body> + + <label for="number">Enter number: </label> + <input id="number" type="text"> + <button>Generate integer squares</button> + + <p>Output: </p> + + + <script> + var para = document.querySelector('p'); + var input = document.querySelector('input'); + var btn = document.querySelector('button'); + + btn.addEventListener('click', function() { + para.textContent = 'Output: '; + var num = input.value; + input.value = ''; + input.focus(); + for (var i = 1; i <= num; i++) { + var sqRoot = Math.sqrt(i); + if (Math.floor(sqRoot) !== sqRoot) { + continue; + } + + para.textContent += i + ' '; + } + }); + </script> + + </body> +</html></pre> +</div> + +<p>{{ EmbedLiveSample('Hidden_code_4', '100%', 100, "", "", "hide-codepen-jsfiddle") }}</p> + +<ol> + <li>In this case, the input should be a number (<code>num</code>). The <code>for</code> loop is given a counter starting at 1 (as we are not interested in 0 in this case), an exit condition that says the loop will stop when the counter becomes bigger than the input <code>num</code>, and an iterator that adds 1 to the counter each time.</li> + <li>Inside the loop, we find the square root of each number using <a href="/en-US/docs/Web/JavaScript/Reference/Global_Objects/Math/sqrt">Math.sqrt(i)</a>, then check whether the square root is an integer by testing whether it is the same as itself when it has been rounded down to the nearest integer (this is what <a href="/en-US/docs/Web/JavaScript/Reference/Global_Objects/Math/floor">Math.floor()</a> does to the number it is passed).</li> + <li>If the square root and the rounded down square root do not equal one another (<code>!==</code>), it means that the square root is not an integer, so we are not interested in it. In such a case, we use the <code>continue</code> statement to skip on to the next loop iteration without recording the number anywhere.</li> + <li>If the square root IS an integer, we skip past the if block entirely so the <code>continue</code> statement is not executed; instead, we concatenate the current <code>i</code> value plus a space on to the end of the paragraph content.</li> +</ol> + +<div class="note"> +<p><strong>Note</strong>: You can view the <a href="https://github.com/mdn/learning-area/blob/master/javascript/building-blocks/loops/integer-squares.html">full source code on GitHub</a> too (also <a href="http://mdn.github.io/learning-area/javascript/building-blocks/loops/integer-squares.html">see it running live</a>).</p> +</div> + +<h2 id="while_and_do_..._while">while and do ... while</h2> + +<p><code>for</code> is not the only type of loop available in JavaScript. There are actually many others and, while you don't need to understand all of these now, it is worth having a look at the structure of a couple of others so that you can recognize the same features at work in a slightly different way.</p> + +<p>First, let's have a look at the <a href="/en-US/docs/Web/JavaScript/Reference/Statements/while">while</a> loop. This loop's syntax looks like so:</p> + +<pre class="notranslate">initializer +while (exit-condition) { + // code to run + + final-expression +}</pre> + +<p>This works in a very similar way to the for loop, except that the initializer variable is set before the loop, and the final-expression is included inside the loop after the code to run — rather than these two items being included inside the parentheses. The exit-condition is included inside the parentheses, which are preceded by the <code>while</code> keyword rather than <code>for</code>.</p> + +<p>The same three items are still present, and they are still defined in the same order as they are in the for loop — this makes sense, as you still have to have an initializer defined before you can check whether it has reached the exit-condition; the final-condition is then run after the code inside the loop has run (an iteration has been completed), which will only happen if the exit-condition has still not been reached.</p> + +<p>Let's have a look again at our cats list example, but rewritten to use a while loop:</p> + +<pre class="brush: js notranslate">var i = 0; + +while (i < cats.length) { + if (i === cats.length - 1) { + info += 'and ' + cats[i] + '.'; + } else { + info += cats[i] + ', '; + } + + i++; +}</pre> + +<div class="note"> +<p><strong>Note</strong>: This still works just the same as expected — have a look at it <a href="http://mdn.github.io/learning-area/javascript/building-blocks/loops/while.html">running live on GitHub</a> (also view the <a href="https://github.com/mdn/learning-area/blob/master/javascript/building-blocks/loops/while.html">full source code</a>).</p> +</div> + +<p>The <a href="/en-US/docs/Web/JavaScript/Reference/Statements/do...while">do...while</a> loop is very similar, but provides a variation on the while structure:</p> + +<pre class="notranslate">initializer +do { + // code to run + + final-expression +} while (exit-condition)</pre> + +<p>In this case, the initializer again comes first, before the loop starts. The <code>do</code> keyword directly precedes the curly braces containing the code to run and the final-expression.</p> + +<p>The differentiator here is that the exit-condition comes after everything else, wrapped in parentheses and preceded by a <code>while</code> keyword. In a <code>do...while</code> loop, the code inside the curly braces is always run once before the check is made to see if it should be executed again (in while and for, the check comes first, so the code might never be executed).</p> + +<p>Let's rewrite our cat listing example again to use a <code>do...while</code> loop:</p> + +<pre class="brush: js notranslate">var i = 0; + +do { + if (i === cats.length - 1) { + info += 'and ' + cats[i] + '.'; + } else { + info += cats[i] + ', '; + } + + i++; +} while (i < cats.length);</pre> + +<div class="note"> +<p><strong>Note</strong>: Again, this works just the same as expected — have a look at it <a href="http://mdn.github.io/learning-area/javascript/building-blocks/loops/do-while.html">running live on GitHub</a> (also view the <a href="https://github.com/mdn/learning-area/blob/master/javascript/building-blocks/loops/do-while.html">full source code</a>).</p> +</div> + +<div class="warning"> +<p><strong>Important</strong>: With while and do...while — as with all loops — you must make sure that the initializer is iterated so that it eventually reaches the exit condition. If not, the loop will go on forever, and either the browser will force it to stop, or it will crash. This is called an <strong>infinite loop</strong>.</p> +</div> + +<h2 id="Active_learning_Launch_countdown!">Active learning: Launch countdown!</h2> + +<p>In this exercise, we want you to print out a simple launch countdown to the output box, from 10 down to Blast off. Specifically, we want you to:</p> + +<ul> + <li>Loop from 10 down to 0. We've provided you with an initializer — <code>var i = 10;</code>.</li> + <li>For each iteration, create a new paragraph and append it to the output <code><div></code>, which we've selected using <code>var output = document.querySelector('.output');</code>. In comments, we've provided you with three code lines that need to be used somewhere inside the loop: + <ul> + <li><code>var para = document.createElement('p');</code> — creates a new paragraph.</li> + <li><code>output.appendChild(para);</code> — appends the paragraph to the output <code><div></code>.</li> + <li><code>para.textContent =</code> — makes the text inside the paragraph equal to whatever you put on the right hand side, after the equals sign.</li> + </ul> + </li> + <li>Different iteration numbers require different text to be put in the paragraph for that iteration (you'll need a conditional statement and multiple <code>para.textContent =</code> lines): + <ul> + <li>If the number is 10, print "Countdown 10" to the paragraph.</li> + <li>If the number is 0, print "Blast off!" to the paragraph.</li> + <li>For any other number, print just the number to the paragraph.</li> + </ul> + </li> + <li>Remember to include an iterator! However, in this example we are counting down after each iteration, not up, so you <strong>don't</strong> want <code>i++</code> — how do you iterate downwards?</li> +</ul> + +<p>If you make a mistake, you can always reset the example with the "Reset" button. If you get really stuck, press "Show solution" to see a solution.</p> + +<div class="hidden"> +<h6 id="Active_learning">Active learning</h6> + +<pre class="brush: html notranslate"><h2>Live output</h2> +<div class="output" style="height: 410px;overflow: auto;"> + +</div> + +<h2>Editable code</h2> +<p class="a11y-label">Press Esc to move focus away from the code area (Tab inserts a tab character).</p> +<textarea id="code" class="playable-code" style="height: 300px;width: 95%"> +var output = document.querySelector('.output'); +output.innerHTML = ''; + +// var i = 10; + +// var para = document.createElement('p'); +// para.textContent = ; +// output.appendChild(para); +</textarea> + +<div class="playable-buttons"> + <input id="reset" type="button" value="Reset"> + <input id="solution" type="button" value="Show solution"> +</div> +</pre> + +<p class="brush: js"></p> + +<p class="brush: js"></p> + +<p class="brush: js"></p> + +<pre class="brush: css notranslate">html { + font-family: sans-serif; +} + +h2 { + font-size: 16px; +} + +.a11y-label { + margin: 0; + text-align: right; + font-size: 0.7rem; + width: 98%; +} + +body { + margin: 10px; + background: #f5f9fa; +}</pre> + +<p class="brush: js"></p> + +<p class="brush: js"></p> + +<p class="brush: js"></p> + +<p class="brush: js"></p> + +<pre class="brush: js notranslate">var textarea = document.getElementById('code'); +var reset = document.getElementById('reset'); +var solution = document.getElementById('solution'); +var code = textarea.value; +var userEntry = textarea.value; + +function updateCode() { + eval(textarea.value); +} + +reset.addEventListener('click', function() { + textarea.value = code; + userEntry = textarea.value; + solutionEntry = jsSolution; + solution.value = 'Show solution'; + updateCode(); +}); + +solution.addEventListener('click', function() { + if(solution.value === 'Show solution') { + textarea.value = solutionEntry; + solution.value = 'Hide solution'; + } else { + textarea.value = userEntry; + solution.value = 'Show solution'; + } + updateCode(); +}); + +var jsSolution = 'var output = document.querySelector(\'.output\');\noutput.innerHTML = \'\';\n\nvar i = 10;\n\nwhile(i >= 0) {\n var para = document.createElement(\'p\');\n if(i === 10) {\n para.textContent = \'Countdown \' + i;\n } else if(i === 0) {\n para.textContent = \'Blast off!\';\n } else {\n para.textContent = i;\n }\n\n output.appendChild(para);\n\n i--;\n}'; +var solutionEntry = jsSolution; + +textarea.addEventListener('input', updateCode); +window.addEventListener('load', updateCode); + +// stop tab key tabbing out of textarea and +// make it write a tab at the caret position instead + +textarea.onkeydown = function(e){ + if (e.keyCode === 9) { + e.preventDefault(); + insertAtCaret('\t'); + } + + if (e.keyCode === 27) { + textarea.blur(); + } +}; + +function insertAtCaret(text) { + var scrollPos = textarea.scrollTop; + var caretPos = textarea.selectionStart; + + var front = (textarea.value).substring(0, caretPos); + var back = (textarea.value).substring(textarea.selectionEnd, textarea.value.length); + textarea.value = front + text + back; + caretPos = caretPos + text.length; + textarea.selectionStart = caretPos; + textarea.selectionEnd = caretPos; + textarea.focus(); + textarea.scrollTop = scrollPos; +} + +// Update the saved userCode every time the user updates the text area code + +textarea.onkeyup = function(){ + // We only want to save the state when the user code is being shown, + // not the solution, so that solution is not saved over the user code + if(solution.value === 'Show solution') { + userEntry = textarea.value; + } else { + solutionEntry = textarea.value; + } + + updateCode(); +};</pre> + +<p class="brush: js"></p> +</div> + +<p>{{ EmbedLiveSample('Active_learning', '100%', 880, "", "", "hide-codepen-jsfiddle") }}</p> + +<h2 id="Active_learning_Filling_in_a_guest_list">Active learning: Filling in a guest list</h2> + +<p>In this exercise, we want you to take a list of names stored in an array, and put them into a guest list. But it's not quite that easy — we don't want to let Phil and Lola in because they are greedy and rude, and always eat all the food! We have two lists, one for guests to admit, and one for guests to refuse.</p> + +<p>Specifically, we want you to:</p> + +<ul> + <li>Write a loop that will iterate from 0 to the length of the <code>people</code> array. You'll need to start with an initializer of <code>var i = 0;</code>, but what exit condition do you need?</li> + <li>During each loop iteration, check if the current array item is equal to "Phil" or "Lola" using a conditional statement: + <ul> + <li>If it is, concatenate the array item to the end of the <code>refused</code> paragraph's <code>textContent</code>, followed by a comma and a space.</li> + <li>If it isn't, concatenate the array item to the end of the <code>admitted</code> paragraph's <code>textContent</code>, followed by a comma and a space.</li> + </ul> + </li> +</ul> + +<p>We've already provided you with:</p> + +<ul> + <li><code>var i = 0;</code> — Your initializer.</li> + <li><code>refused.textContent +=</code> — the beginnings of a line that will concatenate something on to the end of <code>refused.textContent</code>.</li> + <li><code>admitted.textContent +=</code> — the beginnings of a line that will concatenate something on to the end of <code>admitted.textContent</code>.</li> +</ul> + +<p>Extra bonus question — after completing the above tasks successfully, you will be left with two lists of names, separated by commas, but they will be untidy — there will be a comma at the end of each one. Can you work out how to write lines that slice the last comma off in each case, and add a full stop to the end? Have a look at the <a href="/en-US/docs/Learn/JavaScript/First_steps/Useful_string_methods">Useful string methods</a> article for help.</p> + +<p>If you make a mistake, you can always reset the example with the "Reset" button. If you get really stuck, press "Show solution" to see a solution.</p> + +<div class="hidden"> +<h6 id="Active_learning_2">Active learning 2</h6> + +<pre class="brush: html notranslate"><h2>Live output</h2> +<div class="output" style="height: 100px;overflow: auto;"> + <p class="admitted">Admit: </p> + <p class="refused">Refuse: </p> +</div> + +<h2>Editable code</h2> +<p class="a11y-label">Press Esc to move focus away from the code area (Tab inserts a tab character).</p> +<textarea id="code" class="playable-code" style="height: 400px;width: 95%"> +var people = ['Chris', 'Anne', 'Colin', 'Terri', 'Phil', 'Lola', 'Sam', 'Kay', 'Bruce']; + +var admitted = document.querySelector('.admitted'); +var refused = document.querySelector('.refused'); +admitted.textContent = 'Admit: '; +refused.textContent = 'Refuse: ' + +// var i = 0; + +// refused.textContent += ; +// admitted.textContent += ; + +</textarea> + +<div class="playable-buttons"> + <input id="reset" type="button" value="Reset"> + <input id="solution" type="button" value="Show solution"> +</div> +</pre> + +<pre class="brush: css notranslate">html { + font-family: sans-serif; +} + +h2 { + font-size: 16px; +} + +.a11y-label { + margin: 0; + text-align: right; + font-size: 0.7rem; + width: 98%; +} + +body { + margin: 10px; + background: #f5f9fa; +}</pre> + +<pre class="brush: js notranslate">var textarea = document.getElementById('code'); +var reset = document.getElementById('reset'); +var solution = document.getElementById('solution'); +var code = textarea.value; +var userEntry = textarea.value; + +function updateCode() { + eval(textarea.value); +} + +reset.addEventListener('click', function() { + textarea.value = code; + userEntry = textarea.value; + solutionEntry = jsSolution; + solution.value = 'Show solution'; + updateCode(); +}); + +solution.addEventListener('click', function() { + if(solution.value === 'Show solution') { + textarea.value = solutionEntry; + solution.value = 'Hide solution'; + } else { + textarea.value = userEntry; + solution.value = 'Show solution'; + } + updateCode(); +}); + +var jsSolution = 'var people = [\'Chris\', \'Anne\', \'Colin\', \'Terri\', \'Phil\', \'Lola\', \'Sam\', \'Kay\', \'Bruce\'];\n\nvar admitted = document.querySelector(\'.admitted\');\nvar refused = document.querySelector(\'.refused\');\n\nadmitted.textContent = \'Admit: \';\nrefused.textContent = \'Refuse: \'\nvar i = 0;\n\ndo {\n if(people[i] === \'Phil\' || people[i] === \'Lola\') {\n refused.textContent += people[i] + \', \';\n } else {\n admitted.textContent += people[i] + \', \';\n }\n i++;\n} while(i < people.length);\n\nrefused.textContent = refused.textContent.slice(0,refused.textContent.length-2) + \'.\';\nadmitted.textContent = admitted.textContent.slice(0,admitted.textContent.length-2) + \'.\';'; +var solutionEntry = jsSolution; + +textarea.addEventListener('input', updateCode); +window.addEventListener('load', updateCode); + +// stop tab key tabbing out of textarea and +// make it write a tab at the caret position instead + +textarea.onkeydown = function(e){ + if (e.keyCode === 9) { + e.preventDefault(); + insertAtCaret('\t'); + } + + if (e.keyCode === 27) { + textarea.blur(); + } +}; + +function insertAtCaret(text) { + var scrollPos = textarea.scrollTop; + var caretPos = textarea.selectionStart; + + var front = (textarea.value).substring(0, caretPos); + var back = (textarea.value).substring(textarea.selectionEnd, textarea.value.length); + textarea.value = front + text + back; + caretPos = caretPos + text.length; + textarea.selectionStart = caretPos; + textarea.selectionEnd = caretPos; + textarea.focus(); + textarea.scrollTop = scrollPos; +} + +// Update the saved userCode every time the user updates the text area code + +textarea.onkeyup = function(){ + // We only want to save the state when the user code is being shown, + // not the solution, so that solution is not saved over the user code + if(solution.value === 'Show solution') { + userEntry = textarea.value; + } else { + solutionEntry = textarea.value; + } + + updateCode(); +};</pre> +</div> + +<p>{{ EmbedLiveSample('Active_learning_2', '100%', 680, "", "", "hide-codepen-jsfiddle") }}</p> + +<h2 id="Which_loop_type_should_you_use">Which loop type should you use?</h2> + +<p>For basic uses, <code>for</code>, <code>while</code>, and <code>do...while</code> loops are largely interchangeable. They can all be used to solve the same problems, and which one you use will largely depend on your personal preference — which one you find easiest to remember or most intuitive. Let's have a look at them again.</p> + +<p>First <code>for</code>:</p> + +<pre class="notranslate">for (initializer; exit-condition; final-expression) { + // code to run +}</pre> + +<p><code>while</code>:</p> + +<pre class="notranslate">initializer +while (exit-condition) { + // code to run + + final-expression +}</pre> + +<p>and finally <code>do...while</code>:</p> + +<pre class="notranslate">initializer +do { + // code to run + + final-expression +} while (exit-condition)</pre> + +<p>We would recommend <code>for</code>, at least to begin with, as it is probably the easiest for remembering everything — the initializer, exit-condition, and final-expression all have to go neatly into the parentheses, so it is easy to see where they are and check that you aren't missing them.</p> + +<div class="note"> +<p><strong>Note</strong>: There are other loop types/features too, which are useful in advanced/specialized situations and beyond the scope of this article. If you want to go further with your loop learning, read our advanced <a href="/en-US/docs/Web/JavaScript/Guide/Loops_and_iteration">Loops and iteration guide</a>.</p> +</div> + +<h2 id="Conclusion">Conclusion</h2> + +<p>This article has revealed to you the basic concepts behind, and different options available when, looping code in JavaScript. You should now be clear on why loops are a good mechanism for dealing with repetitive code, and be raring to use them in your own examples!</p> + +<p>If there is anything you didn't understand, feel free to read through the article again, or <a href="/en-US/Learn#Contact_us">contact us</a> to ask for help.</p> + +<h2 id="See_also">See also</h2> + +<ul> + <li><a href="/en-US/docs/Web/JavaScript/Guide/Loops_and_iteration">Loops and iteration in detail</a></li> + <li><a href="/en-US/docs/Web/JavaScript/Reference/Statements/for">for statement reference</a></li> + <li><a href="/en-US/docs/Web/JavaScript/Reference/Statements/while">while</a> and <a href="/en-US/docs/Web/JavaScript/Reference/Statements/do...while">do...while</a> references</li> + <li><a href="/en-US/docs/Web/JavaScript/Reference/Statements/break">break</a> and <a href="/en-US/docs/Web/JavaScript/Reference/Statements/continue">continue</a> references</li> + <li> + <p class="entry-title"><a href="https://www.impressivewebs.com/javascript-for-loop/">What’s the Best Way to Write a JavaScript For Loop?</a> — some advanced loop best practices</p> + </li> +</ul> + +<p>{{PreviousMenuNext("Learn/JavaScript/Building_blocks/conditionals","Learn/JavaScript/Building_blocks/Functions", "Learn/JavaScript/Building_blocks")}}</p> + +<h2 id="In_this_module">In this module</h2> + +<ul> + <li><a href="/en-US/docs/Learn/JavaScript/Building_blocks/conditionals">Making decisions in your code — conditionals</a></li> + <li><a href="/en-US/docs/Learn/JavaScript/Building_blocks/Looping_code">Looping code</a></li> + <li><a href="/en-US/docs/Learn/JavaScript/Building_blocks/Functions">Functions — reusable blocks of code</a></li> + <li><a href="/en-US/docs/Learn/JavaScript/Building_blocks/Build_your_own_function">Build your own function</a></li> + <li><a href="/en-US/docs/Learn/JavaScript/Building_blocks/Return_values">Function return values</a></li> + <li><a href="/en-US/docs/Learn/JavaScript/Building_blocks/Events">Introduction to events</a></li> + <li><a href="/en-US/docs/Learn/JavaScript/Building_blocks/Image_gallery">Image gallery</a></li> +</ul> +<gdiv></gdiv> diff --git a/files/es/learn/javascript/building_blocks/conditionals/index.html b/files/es/learn/javascript/building_blocks/conditionals/index.html new file mode 100644 index 0000000000..7a0fdcb91d --- /dev/null +++ b/files/es/learn/javascript/building_blocks/conditionals/index.html @@ -0,0 +1,778 @@ +--- +title: Tomando decisiones en tu código — condicionales +slug: Learn/JavaScript/Building_blocks/conditionals +tags: + - Aprendizaje + - Artículo + - Codificación + - Condicionales + - JavaScript + - Principiante +translation_of: Learn/JavaScript/Building_blocks/conditionals +--- +<div> +<p>{{LearnSidebar}}</p> + +<p>{{NextMenu("Learn/JavaScript/Building_blocks/Looping_code", "Learn/JavaScript/Building_blocks")}}</p> +</div> + +<p class="summary">En cualquier lenguaje de programación, el código necesita realizar decisiones y llevar a cabo diferentes acciones acordes dependiendo de distintas entradas. Por ejemplo, en un juego, si el el numero de vidas del jugador es 0, entonces se termina el juego. En una aplicación del clima, si se observa en la mañana, se despliega una gráfica del amanecer; muestra estrellas y una luna si es de noche. En este artículo, exploraremos cómo las llamadas declaraciones condicionales funcionan en JavaScript.</p> + +<table class="learn-box standard-table"> + <tbody> + <tr> + <th scope="row">Prerequisitos:</th> + <td>Conocimientos básicos de informática, básico entendimiento de HTML y CSS, <a href="/en-US/docs/Learn/JavaScript/First_steps">JavaScript primeros pasos</a>.</td> + </tr> + <tr> + <th scope="row">Objetivo:</th> + <td>Entender como se usan las extructuras condicionales en JavaScript. </td> + </tr> + </tbody> +</table> + +<h2 id="Puedes_hacerlo_en_una_condición..!">Puedes hacerlo en una condición..!</h2> + +<p>Los seres humanos (y otros animales) toman decisiones todo el tiempo que afectan sus vidas, desde la más insignificante ("¿Debería comer una galleta o dos?") hasta la más grande (¿Debería quedarme en mi país y trabajar en la granja de mi padre, o debería mudarme a Estados Unidos y estudiar astrofísica?). </p> + +<p><img alt="" src="https://mdn.mozillademos.org/files/13703/cookie-choice-small.png" style="display: block; margin: 0 auto;"></p> + +<h2 id="Declaraciones_if_..._else">Declaraciones if ... else </h2> + +<p>Echemos un vistazo a la declaración condicional más común que usarás en JavaScript.</p> + +<p> — El humilde <code><a href="/en-US/docs/Web/JavaScript/Reference/Statements/if...else">if ... else</a></code><a href="/en-US/docs/Web/JavaScript/Reference/Statements/if...else"> statement</a>.</p> + +<h3 id="Sintaxis_if_..._else_básica.">Sintaxis if ... else básica. </h3> + +<p>Una sintaxis básica <code>if...else</code> luce así. {{glossary("pseudocode")}}:</p> + +<pre class="notranslate">if (condición) { + código a ejecutar si la condición es verdadera +} else { + ejecuta este otro código si la condición es falsa +}</pre> + +<p>Aquí tenemos:</p> + +<ol> + <li>La palabra clave <code>if</code> seguida de unos paréntesis.</li> + <li>Una condición a probar, puesta dentro de los paréntesis (típicamente "¿es este valor mayor que este otro valor?", o "¿existe este valor?"). Esta condición usará los <a href="/en-US/Learn/JavaScript/First_steps/Math#Comparison_operators">operadores de comparación</a> que hemos hablado en el módulo anterior y retorna un valor <code>true</code> o <code>false (verdadero o falso)</code>.</li> + <li>Un conjunto de llaves, en las cuales tenemos algún código — puede ser cualquier código que deseemos, código que se ejecutará sólamente si la condición retorna <code>true</code>.</li> + <li>La palabra clave <code>else</code>.</li> + <li>Otro conjunto de llaves, dentro de las cuales tendremos otro código — puede ser cualquier código que deseemos, y sólo se ejecutará si la condición no es <code>true</code>.</li> +</ol> + +<p>Este código es fácil de leer — está diciendo "<strong>si (if) </strong> la <strong>condición</strong> retorna verdadero (<code>true)</code>, entonces ejecute el código A, <strong>sino (else)</strong> ejecute el código B"</p> + +<p>Habrás notado que no tienes que incluir <code>else</code> y el segundo bloque de llaves — La siguiente declaración también es perfectmaente legal. </p> + +<pre class="notranslate">if (condición) { + ejecuta el código de al ser verdadera la condición +} + +ejecuta otro código</pre> + +<p>Sin embargo, hay que ser cuidadosos — en este caso, el segundo bloque no es controlado por una declaración condicional, así que <strong>siempre</strong> se ejecutará, sin importar si la condicional devuelve <code>true</code> o <code>false</code>. Esto no es necesariemente algo malo, pero puede ser algo que no quieras — a menudo desearás ejecutar un bloque de código u otro, no ambos.</p> + +<p>Como punto final, habrán ocaciones donde veas delcaraciones <code>if...else</code> escritas sin un conjunto de llaves, de esta manera:</p> + +<pre class="notranslate">if (condición) ejecuta código de ser verdadero (true) +else ejecuta este otro código </pre> + +<p>Este código es perfectamente valido, pero no es recomendado usarlo — es mucho más fácil leer el código y determinar qué sucede haciendo uso de las llaves para delimitar los bloques de código y usar varias líneas y sangrías.</p> + +<h3 id="Un_ejemplo_real">Un ejemplo real</h3> + +<p>Para comprender mejor la sintaxis, realicemos un ejemplo real. Imagínese a un niño a quien su madre o padre le pide ayuda con una tarea. El padre podría decir: "¡Hola, cariño! Si me ayudas yendo y haciendo las compras, te daré un subsidio adicional para que puedas pagar ese juguete que querías". En JavaScript, podríamos representar esto así:</p> + +<pre class="brush: js notranslate">let compraRealizada = false; + +if (compraRealizada === true) { + let subsidioAdicional = 10; +} else { + let subsidioAdicional = 5; +}</pre> + +<p>La variable <code>compraRealizada</code> escrita en este código dará siempre como resultado un retorno de valor <code>false</code>, lo cuál significa una desilusión para nuestro pobre hijo. Depende de nosotros proporcionar un mecanismo para que el padre cambie el valor de la variable <code>compraRealizada</code> a <code>true</code> si el niño realizó la compra.</p> + +<div class="note"> +<p><strong>Nota</strong>: Podrás ver una versión más completa de <a href="https://github.com/mdn/learning-area/blob/master/javascript/building-blocks/allowance-updater.html">este ejemplo en GitHub</a> (también podrás verlo <a href="https://mdn.github.io/learning-area/javascript/building-blocks/allowance-updater.html">corriendo en vivo.</a>)</p> +</div> + +<h3 id="else_if">else if</h3> + +<p>El último ejemplo nos proporcionó dos opciones o resultados, pero ¿qué ocurre si queremos más de dos?</p> + +<p>Hay una forma de encadenar opciones / resultados adicionales extras a <code>if...else</code> — usando <code>else if</code>. Cada opción extra requiere un bloque adicional para poner en medio de bloque <code>if() { ... }</code> y <code>else { ... }</code> — Vea el siguiente ejemplo un poco más complicado, que podría ser parte de una aplicación para un simple pronóstico del tiempo:</p> + +<pre class="brush: html notranslate"><label for="clima">Seleccione el tipo de clima de hoy: </label> +<select id="clima"> + <option value="">--Haga una elección--</option> + <option value="soleado">Soleado</option> + <option value="lluvioso">Lluvioso</option> + <option value="nevando">Nevando</option> + <option value="nublado">Nublado</option> +</select> + +<p></p></pre> + +<pre class="brush: js notranslate">let seleccionar = document.querySelector('select'); +let parrafo = document.querySelector('p'); + +seleccionar.addEventListener('change', establecerClima); + +function establecerClima() { + let eleccion = seleccionar.value; + + if (eleccion === 'soleado') { + parrafo.textContent = 'El día esta agradable y soleado hoy. ¡Use pantalones cortos! Ve a la playa o al parque y come un helado.'; + } else if (eleccion === 'lluvioso') { + parrafo.textContent = 'Está lloviendo, tome un abrigo para lluvia y un paraguas, y no se quede por fuera mucho tiempo.'; + } else if (eleccion === 'nevando') { + parrafo.textContent = 'Está nevando ─ ¡está congelando! Lo mejor es quedarse en casa con una taza caliente de chocolate, o hacer un muñeco de nieve.'; + } else if (eleccion === 'nublado') { + parrafo.textContent = 'No está lloviendo, pero el cielo está gris y nublado; podría llover en cualquier momento, así que lleve un saco solo por si acaso.'; + } else { + parrafo.textContent = ''; + } +} + +</pre> + +<p>{{ EmbedLiveSample('else_if', '100%', 100, "", "", "hide-codepen-jsfiddle") }}</p> + +<ol> + <li>Aquí tenemos un elemento HTML {{htmlelement("select")}} que nos permite realizar varias elecciones sobre el clima, y un parrafo simple.</li> + <li>En el JavaScript, estamos almacenando una referencia para ambos elementos {{htmlelement("select")}} y {{htmlelement("p")}} , y añadiendo un Event Listener o en español un Detector de Eventos al elemento <code><select></code> así cuando su valor cambie se ejecuta la función <code>establecerClima</code><code>().</code></li> + <li>Cuando la función es ejecutada, primero establecemos la variable <code>eleccion</code> con el valor obtenido del elemento <code><select>.</code> Luego usamos una declaración condicinal para mostrar distintos textos dentro del párrafo {{htmlelement("p")}} dependiendo del valor de la variable <code>eleccion</code>. Note como todas las condicinales son probadas en los bloques <code>else if() {...}</code> , a excepción del primero, el cual es probado en el primer bloque <code>if() {...}</code>.</li> + <li>La ultima elección, dentro del bloque <code>else {...}</code>, es básicamente el "último recurso" como opción— El código dentro de este bloque se ejecutará si nunguna de las condiciones es <code>true</code>. En este caso, sirve para vaciar el contenido del párrafo si nada ha sido seleccionado, por ejemplo, si el usuario decide elegir de nuevo "--Haga una elección--" mostrado al inicio.</li> +</ol> + +<div class="note"> +<p><strong>Nota</strong>: Puedes encontrar <a href="https://github.com/mdn/learning-area/blob/master/javascript/building-blocks/simple-else-if.html"> este ejemplo en GitHub</a> (También podrás verlo <a href="http://mdn.github.io/learning-area/javascript/building-blocks/simple-else-if.html">correr en vivo</a>.)</p> +</div> + +<h3 id="Una_nota_en_los_operadores_de_comparación">Una nota en los operadores de comparación </h3> + +<p>Los operadores de comparación son usados para probar las condiciones dentro de nuestra declaración condicional. Vimos estos operadores en el artículo <a href="/en-US/Learn/JavaScript/First_steps/Math#Comparison_operators">Matématica básica en JavaScript — Números y operadores</a>. Nuestras opciones son:</p> + +<ul> + <li><code>===</code> y <code>!==</code> — prueba si un valor es exactamente igual a otro, o sino es indentico a otro valor.</li> + <li><code><</code> y <code>></code> — prueba si un valor es menor o mayor que otro.</li> + <li><code><=</code> y <code>>=</code> — prueba si un valor es menor e igual o mayor e igual que otro.</li> +</ul> + +<div class="note"> +<p><strong>Nota</strong>: Revisa el material en los enlaces previos para refrescar la memoria en estos temas. </p> +</div> + +<p>Queremos hacer una mención especial al probar los valores (<code>true</code>/<code>false</code>) , y un patrón común que te encontrarás una y otra vez. Cualquier valor que no sea <code>false</code>, <code>undefined</code>, <code>null</code>, <code>0</code>, <code>NaN</code>, o una cadena vacía string (<code>''</code>) realmente retorna el valor <code>true</code> cuando es probada como una declaración condicional, por lo tanto puedes simplemente usar el nombre de una variable para probar si es <code>true</code>, o si al menos existe (i.e. no está definido.) Por ejemplo:</p> + +<pre class="brush: js notranslate">let queso = 'Cheddar'; + +if (queso) { + console.log('¡Siii! Hay queso para hacer tostadas con queso.'); +} else { + console.log('No hay tostadas con queso para ti hoy :(.'); +}</pre> + +<p>En el ejemplo anterior la variable <code>queso</code> contiene el valor 'Cheddar', y como su valor está definido o no es <code>false</code>, <code>undefined</code>, <code>null</code>, <code>0</code>, <code>NaN</code> y <code>(' ')</code> es considerado como <code>true</code> lo cual hará mostrar el mensaje dentro del primer bloque de llaves. </p> + +<p>Y, devolviéndonos al ejemplo previo del niño haciendo las compras para su padre, lo podrías haber escrito así:</p> + +<pre class="brush: js notranslate">let compraRealizada = false; + +if (compraRealizada) { //no necesitas especificar explícitamente '=== true' + let subsidioAdicional = 10; +} else { + let subsidioAdicional = 5; +}</pre> + +<h3 id="Anidando_if_..._else">Anidando if ... else</h3> + +<p>Está perfectamente permitido poner una declaración <code>if...else</code> dentro de otra declaración <code>if...else</code> — para anidarlas. Por ejemplo, podemos actualizar nuestra aplicación del clima para mostrar una serie de opciones dependiendo de cual sea la temperatura:</p> + +<pre class="brush: js notranslate">if (elección === 'soleado') { + if (temperatura < 86) { + parrafo.textContent = 'Está a ' + temperatura + ' grados afuera — agradable y soleado. Vamos a la playa, o al parque, y comer helado.'; + } else if (temperatura >= 86) { + parrafo.textContent = 'Está a ' + temperatura + ' grados afuera — ¡QUÉ CALOR! Si deseas salir, asegúrate de aplicarte bloqueador solar.'; + } +}</pre> + +<p>Aunque el código funciona en conjunto, cada declaración <code>if...else</code> funciona complentamente independiente del otro.</p> + +<h3 id="Operadores_lógicos_AND_OR_y_NOT">Operadores lógicos: AND, OR y NOT</h3> + +<p>Si quieres probar multiples condiciones sin escribir declaraciones <code>if...else </code>anidados, los <a href="/en-US/docs/Web/JavaScript/Reference/Operators/Logical_Operators">operadores lógicos</a> pueden ayudarte. Cuando se usa en condiciones, los primeros dos hacen lo siguiente:</p> + +<ul> + <li><code>&&</code> — AND; le permite encadenar dos o más expresiones para que todas ellas se tengan que evaluar individualmente <code>true</code> para que expresión entera retorne <code>true</code>.</li> + <li><code>||</code> — OR; le permite encadenar dos o más expresiones para que una o más de ellas se tengan que evaluar individualmente <code>true</code> para que expresión entera retorne <code>true</code>.</li> +</ul> + +<p>Para poner un ejemplo de AND, el anterior código puede ser reescrito de esta manera:</p> + +<pre class="brush: js notranslate">if (eleccion === 'soleado' && temperatura < 86) { + parrafo.textContent = 'Está a ' + temperatura + ' grados afuera — agradable y soleado. Vamos a la playa, o al parque, y comer helado.'; +} else if (eleccion === 'soleado' && temperatura >= 86) { + parrafo.textContent = 'Está a ' + temperatura + ' grados afuera — ¡QUÉ CALOR! Si deseas salir, asegúrate de aplicarte bloqueador solar.'; +}</pre> + +<p>Así que por ejemplo, el primer bloque solo se ejecutará si la variable <code>eleccion === 'soleado'</code> <em>y </em><code>temperatura < 86</code> devuelven un valor verdadero o <code>true</code>.</p> + +<p>Observemos un ejemplo rápido del operador OR:</p> + +<pre class="brush: js notranslate">if (carritoDeHelados || estadoDeLaCasa === 'en llamas') { + console.log('Debes salir de la casa rápidamente.'); +} else { + console.log('Es mejor que te quedes dentro de casa'); +}</pre> + +<p>El último tipo de operador lógico, NOT, es expresado con el operador <code>!</code>, puede ser usado para negar una expresión. Vamos a combinarlo con el operador OR en el siguiente ejemplo:</p> + +<pre class="brush: js notranslate">if (!(carritoDeHelados || estadoDeLaCasa === 'en llamas')) { + console.log('Es mejor que te quedes dentro de casa'); +} else { + console.log('Debes salir de la casa rápidamente.'); +}</pre> + +<p>En el anterior ejemplo, si las declaraciones del operador OR retornan un valor <code>true</code>, el operador NOT negará toda la expresión dentro de los paréntesis, por lo tanto retornará un valor <code>false</code>.</p> + +<p>Puedes combinar los operadores que quieras dentro de las sentencias, en cualquier estructura. El siguiente ejemplo ejecuta el código dentro del condicional solo si ambas sentencias OR devuelven verdadero, lo que significa que la instrucción general AND devolverá verdadero:</p> + +<pre class="brush: js notranslate">if ((x === 5 || y > 3 || z <= 10) && (logueado || nombreUsuario === 'Steve')) { + // ejecuta el código +}</pre> + +<p>Un error comun cuando se utiliza el operador OR en las declaraciones condicionales es intentar verificar el valor de la variable una sola vez, y luego darle una lista de valores que podrían retornar verdadero separados por operadores ||. Por ejemplo:</p> + +<pre class="example-bad brush: js notranslate">if (x === 5 || 7 || 10 || 20) { + // ejecuta mi código +}</pre> + +<p>En este caso la condición <code>if(...)</code> siempre evaluará a verdadero siendo que 7 (u otro valor que no sea 0) siempre será verdadero. Esta condición lo que realmente está diciendo es que "if x es igual a 5, o 7 es verdadero— lo cual siempre es". ¡Esto no es lógicamente lo que queremos! Para hacer que esto funcione, tenemos que especificar una prueba completa para cada lado del operador OR:</p> + +<pre class="brush: js notranslate">if (x === 5 || x === 7 || x === 10 ||x === 20) { + // ejecuta mi código +}</pre> + +<h2 id="Declaraciones_con_switch">Declaraciones con switch</h2> + +<p><code>El </code>condicional<code> if...else</code> hace un buen trabajo permitiéndonos realizar un buen código, pero esto viene con sus desventajas. Hay variedad de casos donde necesitarás realizar varias elecciones, y cada una requiere una cantidad razonable de código para ser ejecutado y/o sus condicionales son complejas (i.e. operadores lógicos múltiples). Para los casos en los que solo se desea establecer una variable para una determinada opción de valores o imprimir una declaración particular dependiendo de una condición, la sintaxis puede ser un poco engorrosa, especialmente si se tiene una gran cantidad de opciones.</p> + +<p>Para estos casos los <a href="/en-US/docs/Web/JavaScript/Reference/Statements/switch"><code>switch</code> statements</a> son de gran ayuda — toman una sola expresión / valor como una entrada, y luego pasan a través de una serie de opciones hasta que encuentran una que coincida con ese valor, ejecutando el código correspondiente que va junto con ella. Aquí hay un pseudocódigo más para hacerte una idea:</p> + +<pre class="notranslate">switch (expresion) { + case choice1: + ejecuta este código + break; + + case choice2: + ejecuta este código + break; + + // Se pueden incluir todos los casos que quieras + + default: + por si acaso, corre este código +}</pre> + +<p>Aquí tenemos:</p> + +<ol> + <li><code><font face="Open Sans, arial, x-locale-body, sans-serif"><span style="background-color: #ffffff;">La palabra clave </span></font>switch</code>, seguida por un conjunto de paréntesis.</li> + <li>Una expresión o valor dentro de los paréntesis.</li> + <li>La palabra clave <code>case</code>, seguida de una elección con la expresión / valor que podría ser, seguido de dos puntos.</li> + <li>Algún código a correr si la elección coincide con la expresión.</li> + <li>Un declaración llamada <code>break</code>, seguida de un punto y coma. Si la elección previa coincide con la expresión / valor, el explorador dejará de ejecutar el bloque de código aquí, y continuará a la siguiente línea de código. Si la opción anterior coincide con la expresión / valor, aquí el navegador deja de ejecutar el bloque de código y pasa a cualquier código que aparezca debajo de la declaración de <code>switch</code>.</li> + <li>Como muchos otros casos, los que quieras.</li> + <li>La palabra clave <code>default</code>, seguido exactamente del mismo patrón de código que en los casos anteriores , excepto que el valor predeterminado no tiene opciónes después de él, y no es necesario que se use <code>break</code> porque no hay nada que ejecutar después de este bloque de todas formas. Esta es la opción predeterminada o por defecto que se ejecuta si ninguna de las opciones coincide.</li> +</ol> + +<div class="note"> +<p><strong>Nota</strong>: No tiene que incluir la sección <code>default</code>; se puede omitir con seguridad si no hay posibilidades de que la expresión termine igualando un valor desconocido. Sin embargo, si existe la posibilidad de que esto ocurra, debe incluirlo para evitar casos desconocidos o comportamientos extraños en tu código.</p> +</div> + +<h3 id="Un_ejemplo_con_switch">Un ejemplo con switch</h3> + +<p>Let's have a look at a real example — we'll rewrite our weather forecast application to use a switch statement instead:</p> + +<pre class="brush: html notranslate"><label for="weather">Select the weather type today: </label> +<select id="weather"> + <option value="">--Make a choice--</option> + <option value="sunny">Sunny</option> + <option value="rainy">Rainy</option> + <option value="snowing">Snowing</option> + <option value="overcast">Overcast</option> +</select> + +<p></p></pre> + +<pre class="brush: js notranslate">let select = document.querySelector('select'); +let para = document.querySelector('p'); + +select.addEventListener('change', setWeather); + + +function setWeather() { + let choice = select.value; + + switch (choice) { + case 'sunny': + para.textContent = 'It is nice and sunny outside today. Wear shorts! Go to the beach, or the park, and get an ice cream.'; + break; + case 'rainy': + para.textContent = 'Rain is falling outside; take a rain coat and a brolly, and don\'t stay out for too long.'; + break; + case 'snowing': + para.textContent = 'The snow is coming down — it is freezing! Best to stay in with a cup of hot chocolate, or go build a snowman.'; + break; + case 'overcast': + para.textContent = 'It isn\'t raining, but the sky is grey and gloomy; it could turn any minute, so take a rain coat just in case.'; + break; + default: + para.textContent = ''; + } +}</pre> + +<p>{{ EmbedLiveSample('A_switch_example', '100%', 100, "", "", "hide-codepen-jsfiddle") }}</p> + +<div class="note"> +<p><strong>Nota</strong>: Tambien puedes<a href="https://github.com/mdn/learning-area/blob/master/javascript/building-blocks/simple-switch.html"> encontrar este ejemplo en GitHub</a> (tambien puedes verlo <a href="http://mdn.github.io/learning-area/javascript/building-blocks/simple-switch.html">en ejecución aquí</a>.)</p> +</div> + +<h2 id="Operador_Ternario">Operador Ternario</h2> + +<p>Hay una última sintaxis que queremos presentarte antes de que juegues con algunos ejemplos. El <a href="/en-US/docs/Web/JavaScript/Reference/Operators/Conditional_Operator">operador ternario o condicional</a> es una pequeña sintaxis que prueba una condición y devuelve un valor/expresión, si es <code>true</code>, y otro si es <code>false</code> — Esto puede ser útil en algunas situaciones, y puede ocupar mucho menos código que un bloque <code>if...else</code> si simplemente tienes dos opciones que se eligen a través de una condición <code>true</code>/<code>false</code>. El pseudocódigo se ve así:</p> + +<pre class="notranslate">( condición ) ? ejecuta este código : ejecuta este código en su lugar</pre> + +<p>Veamos un ejemplo simple:</p> + +<pre class="brush: js notranslate">let greeting = ( isBirthday ) ? 'Happy birthday Mrs. Smith — we hope you have a great day!' : 'Good morning Mrs. Smith.';</pre> + +<p>Aquí tenemos una variable llamada <code>isBirthday</code> — si esta es <code>true</code>, le damos a nuestro invitado un mensaje de feliz cumpleaños; si no, le damos el saludo diario estándar.</p> + +<h3 id="Ejemplo_con_operador_ternario">Ejemplo con operador ternario</h3> + +<p>No solo puedes establecer valores variables con el operador ternario; También puedes ejecutar funciones o líneas de código — lo que quieras. El siguiente ejemplo muestra un selector de tema simple donde el estilo del sitio se aplica utilizando un operador ternario.</p> + +<pre class="brush: html notranslate"><label for="theme">Select theme: </label> +<select id="theme"> + <option value="white">White</option> + <option value="black">Black</option> +</select> + +<h1>This is my website</h1></pre> + +<pre class="brush: js notranslate">let select = document.querySelector('select'); +let html = document.querySelector('html'); +document.body.style.padding = '10px'; + +function update(bgColor, textColor) { + html.style.backgroundColor = bgColor; + html.style.color = textColor; +} + +select.onchange = function() { + ( select.value === 'black' ) ? update('black','white') : update('white','black'); +} +</pre> + +<p>{{ EmbedLiveSample('Ternary_operator_example', '100%', 300, "", "", "hide-codepen-jsfiddle") }}</p> + +<p>Aquí tenemos un elemento {{htmlelement('select')}} para elegir un tema (blanco o negro), más un simple (black or white), plus a simple {{htmlelement('h1')}} para mostrar el título de un sitio web. También tenemos una función llamada <code>update()</code>, que toma dos colores como parámetros (entradas). El color de fondo del sitio web se establece en el primer color proporcionado y el color del texto se establece en el segundo color proporcionado.</p> + +<p>Finalmente, también tenemos un detector de eventos <a href="/en-US/docs/Web/API/GlobalEventHandlers/onchange">onchange</a> que sirve para ejecutar una función que contiene un operador ternario. Comienza con una condición de prueba — <code>select.value === 'black'</code>. Si esto devuelve <code>true</code>, ejecutamos la función <code>update()</code> con parámetros de blanco y negro, lo que significa que terminamos con un color de fondo negro y un color de texto blanco. Si devuelve <code>false</code>, ejecutamos las función <code>update()</code> con parámetros de blanco y negro, lo que significa que el color del sitio está invertido.</p> + +<div class="note"> +<p><strong>Nota</strong>: También puedes <a href="https://github.com/mdn/learning-area/blob/master/javascript/building-blocks/simple-ternary.html">encontrar este ejemplo en GitHub</a> (y verlo <a href="http://mdn.github.io/learning-area/javascript/building-blocks/simple-ternary.html">en ejecución aquí</a>.)</p> +</div> + +<h2 id="Aprendizaje_activo_Un_calendario_simple">Aprendizaje activo: Un calendario simple</h2> + +<p>En este ejemplo, nos ayudará a terminar una aplicación de calendario simple. En el código tienes:</p> + +<ul> + <li>Un elemento {{htmlelement("select")}} para permitir al usuario elegir entre direfentes meses.</li> + <li>Un controlador de eventos <code>onchange</code> para detectar cuándo se cambia el valor seleccionado en el menú de <code><select></code>.</li> + <li>Una función llamada <code>createCalendar()</code> que dibuja el calendario y muestra el mes correcto en el elemento {{htmlelement("h1")}}.</li> +</ul> + +<p>Necesitamos que escriba una declaración condicional dentro de la función del controlador <code>onchange</code> justo debajo del comentario <code>// ADD CONDITIONAL HERE.</code> Debería:</p> + +<ol> + <li>Mire el mes seleccionado (almacenado en la variable <code>choice</code>. Este será el valor del elemento <code><select></code> después de que cambie el valor, por ejemplo "January")</li> + <li>Establezca una variable llamada <code>days</code> para que sea igual al número de días del mes seleccionado. Para hacer esto, tendrá que buscar el número de días en cada mes del año. Puede ignorar los años bisiestos a los efectos de este ejemplo.</li> +</ol> + +<p>Sugerencias:</p> + +<ul> + <li>Se le aconseja que utilice el operador lógico OR para agrupar varios meses en una sola condición; Muchos de ellos comparten el mismo número de días.</li> + <li>Piense qué número de días es le más común y utilícelo como valor predeterminado.</li> +</ul> + +<p>Si comete un error, siempre puede restablecer el ejemplo con el botón "Reset". Si se queda realmente atascado, presione "Show solution" para ver una solución.</p> + +<div class="hidden"> +<h6 id="Playable_code">Playable code</h6> + +<pre class="brush: html notranslate"><h2>Live output</h2> +<div class="output" style="height: 500px;overflow: auto;"> + <label for="month">Select month: </label> + <select id="month"> + <option value="January">January</option> + <option value="February">February</option> + <option value="March">March</option> + <option value="April">April</option> + <option value="May">May</option> + <option value="June">June</option> + <option value="July">July</option> + <option value="August">August</option> + <option value="September">September</option> + <option value="October">October</option> + <option value="November">November</option> + <option value="December">December</option> + </select> + + <h1></h1> + + <ul></ul> +</div> + +<h2>Editable code</h2> +<p class="a11y-label">Press Esc to move focus away from the code area (Tab inserts a tab character).</p> + +<textarea id="code" class="playable-code" style="height: 400px;width: 95%"> +var select = document.querySelector('select'); +var list = document.querySelector('ul'); +var h1 = document.querySelector('h1'); + +select.onchange = function() { + var choice = select.value; + + // ADD CONDITIONAL HERE + + createCalendar(days, choice); +} + +function createCalendar(days, choice) { + list.innerHTML = ''; + h1.textContent = choice; + for (var i = 1; i <= days; i++) { + var listItem = document.createElement('li'); + listItem.textContent = i; + list.appendChild(listItem); + } +} + +createCalendar(31,'January'); +</textarea> + +<div class="playable-buttons"> + <input id="reset" type="button" value="Reset"> + <input id="solution" type="button" value="Show solution"> +</div> +</pre> + +<pre class="brush: css notranslate">.output * { + box-sizing: border-box; +} + +.output ul { + padding-left: 0; +} + +.output li { + display: block; + float: left; + width: 25%; + border: 2px solid white; + padding: 5px; + height: 40px; + background-color: #4A2DB6; + color: white; +} + +html { + font-family: sans-serif; +} + +h2 { + font-size: 16px; +} + +.a11y-label { + margin: 0; + text-align: right; + font-size: 0.7rem; + width: 98%; +} + +body { + margin: 10px; + background: #f5f9fa; +}</pre> + +<pre class="brush: js notranslate">var textarea = document.getElementById('code'); +var reset = document.getElementById('reset'); +var solution = document.getElementById('solution'); +var code = textarea.value; +var userEntry = textarea.value; + +function updateCode() { + eval(textarea.value); +} + +reset.addEventListener('click', function() { + textarea.value = code; + userEntry = textarea.value; + solutionEntry = jsSolution; + solution.value = 'Show solution'; + updateCode(); +}); + +solution.addEventListener('click', function() { + if(solution.value === 'Show solution') { + textarea.value = solutionEntry; + solution.value = 'Hide solution'; + } else { + textarea.value = userEntry; + solution.value = 'Show solution'; + } + updateCode(); +}); + +var jsSolution = 'var select = document.querySelector(\'select\');\nvar list = document.querySelector(\'ul\');\nvar h1 = document.querySelector(\'h1\');\n\nselect.onchange = function() {\n var choice = select.value;\n var days = 31;\n if(choice === \'February\') {\n days = 28;\n } else if(choice === \'April\' || choice === \'June\' || choice === \'September\'|| choice === \'November\') {\n days = 30;\n }\n\n createCalendar(days, choice);\n}\n\nfunction createCalendar(days, choice) {\n list.innerHTML = \'\';\n h1.textContent = choice;\n for(var i = 1; i <= days; i++) {\n var listItem = document.createElement(\'li\');\n listItem.textContent = i;\n list.appendChild(listItem);\n }\n }\n\ncreateCalendar(31,\'January\');'; +var solutionEntry = jsSolution; + +textarea.addEventListener('input', updateCode); +window.addEventListener('load', updateCode); + +// stop tab key tabbing out of textarea and +// make it write a tab at the caret position instead + +textarea.onkeydown = function(e){ + if (e.keyCode === 9) { + e.preventDefault(); + insertAtCaret('\t'); + } + + if (e.keyCode === 27) { + textarea.blur(); + } +}; + +function insertAtCaret(text) { + var scrollPos = textarea.scrollTop; + var caretPos = textarea.selectionStart; + + var front = (textarea.value).substring(0, caretPos); + var back = (textarea.value).substring(textarea.selectionEnd, textarea.value.length); + textarea.value = front + text + back; + caretPos = caretPos + text.length; + textarea.selectionStart = caretPos; + textarea.selectionEnd = caretPos; + textarea.focus(); + textarea.scrollTop = scrollPos; +} + +// Update the saved userCode every time the user updates the text area code + +textarea.onkeyup = function(){ + // We only want to save the state when the user code is being shown, + // not the solution, so that solution is not saved over the user code + if(solution.value === 'Show solution') { + userEntry = textarea.value; + } else { + solutionEntry = textarea.value; + } + + updateCode(); +};</pre> +</div> + +<p>{{ EmbedLiveSample('Playable_code', '100%', 1110, "", "", "hide-codepen-jsfiddle") }}</p> + +<h2 id="Aprendizaje_activo_Más_opciones_de_colores!">Aprendizaje activo: Más opciones de colores!</h2> + +<p>In this example, you are going to take the ternary operator example we saw earlier and convert the ternary operator into a switch statement that will allow us to apply more choices to the simple website. Look at the {{htmlelement("select")}} — this time you'll see that it has not two theme options, but five. You need to add a switch statement just underneath the <code>// ADD SWITCH STATEMENT</code> comment:</p> + +<ul> + <li>It should accept the <code>choice</code> variable as its input expression.</li> + <li>For each case, the choice should equal one of the possible values that can be selected, i.e. white, black, purple, yellow, or psychedelic. Note that the values are case sensitive, and should equal the <code><option></code> element <code>value</code> values rather than the visual labels.</li> + <li>For each case, the <code>update()</code> function should be run, and be passed two color values, the first one for the background color, and the second one for the text color. Remember that color values are strings, so need to be wrapped in quotes. </li> +</ul> + +<p>If you make a mistake, you can always reset the example with the "Reset" button. If you get really stuck, press "Show solution" to see a solution.</p> + +<div class="hidden"> +<h6 id="Playable_code_2">Playable code 2</h6> + +<pre class="brush: html notranslate"><h2>Live output</h2> +<div class="output" style="height: 300px;"> + <label for="theme">Select theme: </label> + <select id="theme"> + <option value="white">White</option> + <option value="black">Black</option> + <option value="purple">Purple</option> + <option value="yellow">Yellow</option> + <option value="psychedelic">Psychedelic</option> + </select> + + <h1>This is my website</h1> +</div> + +<h2>Editable code</h2> +<p class="a11y-label">Press Esc to move focus away from the code area (Tab inserts a tab character).</p> + +<textarea id="code" class="playable-code" style="height: 450px;width: 95%"> +var select = document.querySelector('select'); +var html = document.querySelector('.output'); + +select.onchange = function() { + var choice = select.value; + + // ADD SWITCH STATEMENT +} + +function update(bgColor, textColor) { + html.style.backgroundColor = bgColor; + html.style.color = textColor; +}</textarea> + +<div class="playable-buttons"> + <input id="reset" type="button" value="Reset"> + <input id="solution" type="button" value="Show solution"> +</div> +</pre> + +<pre class="brush: css notranslate">html { + font-family: sans-serif; +} + +h2 { + font-size: 16px; +} + +.a11y-label { + margin: 0; + text-align: right; + font-size: 0.7rem; + width: 98%; +} + +body { + margin: 10px; + background: #f5f9fa; +}</pre> + +<pre class="brush: js notranslate">var textarea = document.getElementById('code'); +var reset = document.getElementById('reset'); +var solution = document.getElementById('solution'); +var code = textarea.value; +var userEntry = textarea.value; + +function updateCode() { + eval(textarea.value); +} + +reset.addEventListener('click', function() { + textarea.value = code; + userEntry = textarea.value; + solutionEntry = jsSolution; + solution.value = 'Show solution'; + updateCode(); +}); + +solution.addEventListener('click', function() { + if(solution.value === 'Show solution') { + textarea.value = solutionEntry; + solution.value = 'Hide solution'; + } else { + textarea.value = userEntry; + solution.value = 'Show solution'; + } + updateCode(); +}); + +var jsSolution = 'var select = document.querySelector(\'select\');\nvar html = document.querySelector(\'.output\');\n\nselect.onchange = function() {\n var choice = select.value;\n\n switch(choice) {\n case \'black\':\n update(\'black\',\'white\');\n break;\n case \'white\':\n update(\'white\',\'black\');\n break;\n case \'purple\':\n update(\'purple\',\'white\');\n break;\n case \'yellow\':\n update(\'yellow\',\'darkgray\');\n break;\n case \'psychedelic\':\n update(\'lime\',\'purple\');\n break;\n }\n}\n\nfunction update(bgColor, textColor) {\n html.style.backgroundColor = bgColor;\n html.style.color = textColor;\n}'; +var solutionEntry = jsSolution; + +textarea.addEventListener('input', updateCode); +window.addEventListener('load', updateCode); + +// stop tab key tabbing out of textarea and +// make it write a tab at the caret position instead + +textarea.onkeydown = function(e){ + if (e.keyCode === 9) { + e.preventDefault(); + insertAtCaret('\t'); + } + + if (e.keyCode === 27) { + textarea.blur(); + } +}; + +function insertAtCaret(text) { + var scrollPos = textarea.scrollTop; + var caretPos = textarea.selectionStart; + + var front = (textarea.value).substring(0, caretPos); + var back = (textarea.value).substring(textarea.selectionEnd, textarea.value.length); + textarea.value = front + text + back; + caretPos = caretPos + text.length; + textarea.selectionStart = caretPos; + textarea.selectionEnd = caretPos; + textarea.focus(); + textarea.scrollTop = scrollPos; +} + +// Update the saved userCode every time the user updates the text area code + +textarea.onkeyup = function(){ + // We only want to save the state when the user code is being shown, + // not the solution, so that solution is not saved over the user code + if(solution.value === 'Show solution') { + userEntry = textarea.value; + } else { + solutionEntry = textarea.value; + } + + updateCode(); +};</pre> +</div> + +<p>{{ EmbedLiveSample('Playable_code_2', '100%', 950, "", "", "hide-codepen-jsfiddle") }}</p> + +<h2 id="Conclusión">Conclusión</h2> + +<p>And that's all you really need to know about conditional structures in JavaScript right now! I'm sure you'll have understood these concepts and worked through the examples with ease; if there is anything you didn't understand, feel free to read through the article again, or <a href="/en-US/Learn#Contact_us">contact us</a> to ask for help.</p> + +<h2 id="Revisa_también">Revisa también</h2> + +<ul> + <li><a href="/en-US/Learn/JavaScript/First_steps/Math#Comparison_operators">Comparison operators</a></li> + <li><a href="/en-US/docs/Web/JavaScript/Guide/Control_flow_and_error_handling#Conditional_statements">Conditional statements in detail</a></li> + <li><a href="/en-US/docs/Web/JavaScript/Reference/Statements/if...else">if...else reference</a></li> + <li><a href="/en-US/docs/Web/JavaScript/Reference/Operators/Conditional_Operator">Conditional (ternary) operator reference</a></li> +</ul> + +<p>{{NextMenu("Learn/JavaScript/Building_blocks/Looping_code", "Learn/JavaScript/Building_blocks")}}</p> + +<h2 id="En_este_módulo">En este módulo</h2> + +<ul> + <li><a href="/es/docs/Learn/JavaScript/Building_blocks/conditionals">Tomando decisiones en tu código - Condicionales</a></li> + <li><a href="/en-US/docs/Learn/JavaScript/Building_blocks/Looping_code">Looping code</a></li> + <li><a href="/en-US/docs/Learn/JavaScript/Building_blocks/Functions">Functions — reusable blocks of code</a></li> + <li><a href="/en-US/docs/Learn/JavaScript/Building_blocks/Build_your_own_function">Build your own function</a></li> + <li><a href="/en-US/docs/Learn/JavaScript/Building_blocks/Return_values">Function return values</a></li> + <li><a href="/en-US/docs/Learn/JavaScript/Building_blocks/Events">Introduction to events</a></li> + <li><a href="/en-US/docs/Learn/JavaScript/Building_blocks/Image_gallery">Image gallery</a></li> +</ul> diff --git a/files/es/learn/javascript/building_blocks/construyendo_tu_propia_funcion/index.html b/files/es/learn/javascript/building_blocks/construyendo_tu_propia_funcion/index.html new file mode 100644 index 0000000000..5f9bcc7c8b --- /dev/null +++ b/files/es/learn/javascript/building_blocks/construyendo_tu_propia_funcion/index.html @@ -0,0 +1,252 @@ +--- +title: Construye tu propia función +slug: Learn/JavaScript/Building_blocks/Construyendo_tu_propia_funcion +tags: + - Aprender + - Artículo + - Construir + - Funciones + - Guía + - JavaScript + - Principiante + - Tutorial +translation_of: Learn/JavaScript/Building_blocks/Build_your_own_function +--- +<div>{{LearnSidebar}}</div> + +<div>{{PreviousMenuNext("Learn/JavaScript/Building_blocks/Functions","Learn/JavaScript/Building_blocks/Return_values", "Learn/JavaScript/Building_blocks")}}</div> + +<p class="summary">Con la mayor parte de la teoría esencial tratada en el artículo anterior, este artículo proporciona experiencia práctica. Aquí obtendrás práctica construyendo tu propia función personalizada. En el camino, también explicaremos algunos detalles útiles sobre cómo tratar las funciones.</p> + +<table class="learn-box standard-table"> + <tbody> + <tr> + <th scope="row">Prerequisites:</th> + <td>Conocimientos básicos de computación, una comprensión básica de HTML y CSS, <a href="/en-US/docs/Learn/JavaScript/First_steps">JavaScript first steps</a>, <a href="/en-US/docs/Learn/JavaScript/Building_blocks/Functions">Functions — reusable blocks of code</a>.</td> + </tr> + <tr> + <th scope="row">Objective:</th> + <td>Para proporcionar algo de práctica en la construcción de una función personalizada, y explicar algunos detalles asociados más útiles.</td> + </tr> + </tbody> +</table> + +<h2 id="Aprendizaje_activo_construyamos_una_función.">Aprendizaje activo: construyamos una función.</h2> + +<p>La función personalizada que vamos a construir se llamará <code>displayMessage()</code>. Mostrará un cuadro de mensaje personalizado en una página web y actuará como un reemplazo personalizado para la función de <a href="/en-US/docs/Web/API/Window/alert">alert()</a> incorporada de un navegador. Hemos visto esto antes, pero solo refresquemos nuestros recuerdos. Escriba lo siguiente en la consola de JavaScript de su navegador, en la página que desee:</p> + +<pre class="brush: js">alert('This is a message');</pre> + +<p>La función <code>alert</code> tiene un argumento — el string que se muestra en la alerta. Prueba a variar el string para cambiar el mensaje.</p> + +<p>La función <code>alert</code> es limitada: pueder cambiar el mensaje, pero no puedes cambiar de manera sencilla nada más, como el color, icono o cualquier otra cosa. Construiremos uno que resultará ser más divertido.</p> + +<div class="note"> +<p><strong>Nota</strong>: Este ejemplo debería funcionar bien en todos los navegadores modernos, pero el estilo puede parecer un poco divertido en los navegadores un poco más antiguos. Te recomendamos que hagas este ejercicio en un navegador moderno como Firefox, Opera o Chrome.</p> +</div> + +<h2 id="La_función_básica">La función básica</h2> + +<p>Para empezar, vamos a poner juntos una función básica.</p> + +<div class="note"> +<p><strong>Nota</strong>: Para las convenciones de nombres de las funciones, debes seguir las mismas reglas que <a href="/en-US/Learn/JavaScript/First_steps/Variables#An_aside_on_variable_naming_rules">convecion de nombres de variables</a>. Esto está bien, ya que puede distinguirlos: los nombres de las funciones aparecen entre paréntesis después de ellos y las variables no.</p> +</div> + +<ol> + <li>Comience accediendo al archivo <a href="https://github.com/mdn/learning-area/blob/master/javascript/building-blocks/functions/function-start.html">function-start.html</a> y haciendo una copia local. Verás que el HTML es simple — el body unicamente tiene un botón. También hemos propocionado algunos estilos básicos de CSS para customizar el mensaje y un elemento {{htmlelement("script")}} vacío para poner nuestro JavaScript dentro.</li> + <li>Luego añade lo siguiente dentro del elemento <code><script></code>: + <pre class="brush: js">function displayMessage() { + +}</pre> + Comenzamos con la palabra clave función, lo que significa que estamos definiendo una función. A esto le sigue el nombre que queremos darle a nuestra función, un conjunto de paréntesis y un conjunto de llaves. Todos los parámetros que queremos darle a nuestra función van dentro de los paréntesis, y el código que se ejecuta cuando llamamos a la función va dentro de las llaves.</li> + <li>Finalmente, agregue el siguiente código dentro de las llaves: + <pre class="brush: js">let html = document.querySelector('html'); + +let panel = document.createElement('div'); +panel.setAttribute('class', 'msgBox'); +html.appendChild(panel); + +let msg = document.createElement('p'); +msg.textContent = 'This is a message box'; +panel.appendChild(msg); + +let closeBtn = document.createElement('button'); +closeBtn.textContent = 'x'; +panel.appendChild(closeBtn); + +closeBtn.onclick = function() { + panel.parentNode.removeChild(panel); +}</pre> + </li> +</ol> + +<p>Esto es un montón de código por el que pasar, así que lo guiaremos paso a paso.</p> + +<p>La primera línea usa un función DOM API llamada {{domxref("document.querySelector()")}} para seleccionar el elemento {{htmlelement("html")}} y guardar una referencia a él en una variable llamada <code>html</code>, por lo que podemos hacer cosas para más adelante:</p> + +<pre class="brush: js">let html = document.querySelector('html');</pre> + +<p>La siguiente sección usa otra función del DOM API llamada {{domxref("Document.createElement()")}} para crear un elemento {{htmlelement("div")}} y guardar una referencia a él en una variable llamada <code>panel</code>. Este elemento será el contenedor exterior de nuestro cuadro de mensaje.</p> + +<p>Entonces usamos otra función del API DOM llamada {{domxref("Element.setAttribute()")}} para configurar un atributo a <code>class</code> en nuestro panel con un valor de <code>msgBox</code>. Esto es para facilitar el estilo del elemento. — Si echas un vistazo al CSS en la página, verás que estamos utilizando un selector de clases<code>.msgBox</code> para dar estilo al al contenedor del mensaje.</p> + +<p>Finalmente, llamamos a una función del DOM llamada {{domxref("Node.appendChild()")}} en la variable <code>html</code> que hemos guardado anteriormente, que anida un elemento dentro del otro como hijo de él. Hemos especificado el panel <code><div></code> como el hijo que queremos añadir dentro del elemento <code><html></code>. Debemos hacer esto ya que el elemento que creamos no aparecerá en la página por sí solo — tenemos que especificar donde ponerlo.</p> + +<pre class="brush: js">let panel = document.createElement('div'); +panel.setAttribute('class', 'msgBox'); +html.appendChild(panel);</pre> + +<p>Las siguientes dos secciones hacen uso de las mismas funciones <code>createElement()</code> y <code>appendChild()</code> que ya vimos para crear dos nuevos elementos — un {{htmlelement("p")}} y un {{htmlelement("button")}} — e insertarlo en la página como un hijo del panel <code><div></code>. Usamos su propiedad {{domxref("Node.textContent")}} — que representa el contenido de texto de un elemento: para insertar un mensaje dentro del párrafo y una 'x' dentro del botón. Este botón será lo que necesita hacer clic / activar cuando el usuario quiera cerrar el cuadro de mensaje.</p> + +<pre class="brush: js">let msg = document.createElement('p'); +msg.textContent = 'This is a message box'; +panel.appendChild(msg); + +let closeBtn = document.createElement('button'); +closeBtn.textContent = 'x'; +panel.appendChild(closeBtn);</pre> + +<p>Finalmente, usamos el manejador de evento {{domxref("GlobalEventHandlers.onclick")}} para hacerlo de modo que cuando se haga clic en el botón, se ejecute algún código para eliminar todo el panel de la página, para cerrar el cuadro de mensaje.</p> + +<p>Brevemente, el handler <code>onclick</code> es una propiedad disponible en el botón (o, de hecho, en cualquier elemento de la página) que se puede configurar en una función para especificar qué código ejecutar cuando se hace clic en el botón. Aprenderás mucho más sobre esto en nuestro artículo de eventos posteriores. Estamos haciendo el handler <code>onclick</code> igual que una función anónima, que contiene el código para ejecutar cuando se ha hecho click en el botón. La línea dentro de la función usa la función del DOM API {{domxref("Node.removeChild()")}} para especificar que queremos eliminar un elemento secundario específico del elemento HTML— en este caso el panel <code><div></code>.</p> + +<pre class="brush: js">closeBtn.onclick = function() { + panel.parentNode.removeChild(panel); +}</pre> + +<p>Básicamente, todo este bloque de código está generando un bloque de HTML que se ve así, y lo está insertando en la página:</p> + +<pre class="brush: html"><div class="msgBox"> + <p>This is a message box</p> + <button>x</button> +</div></pre> + +<p>Fue un montón de código con el que trabajar: ¡no te preocupes demasiado si no recuerdas exactamente cómo funciona todo ahora! La parte principal en la que queremos centrarnos aquí es la estructura y el uso de la función, pero queríamos mostrar algo interesante para este ejemplo.</p> + +<h2 id="Llamando_a_la_función">Llamando a la función</h2> + +<p>Ahora tienes la definición de tu función escrita en tu elemento <script> bien, pero no hará nada tal como está.</p> + +<ol> + <li>Intente incluir la siguiente línea debajo de su función para llamarla: + <pre class="brush: js">displayMessage();</pre> + Esta línea invoca la función, haciéndola correr inmediatamente. Cuando guarde el código y lo vuelva a cargar en el navegador, verá que el pequeño cuadro de mensaje aparece inmediatamente, solo una vez. Después de todo, solo lo llamamos una vez.</li> + <li> + <p>Ahora abra las herramientas de desarrollo de su navegador en la página de ejemplo, vaya a la consola de JavaScript y escriba la línea nuevamente allí, ¡verá que aparece nuevamente! Así que esto es divertido: ahora tenemos una función reutilizable que podemos llamar en cualquier momento que queramos.</p> + + <p>Pero probablemente queremos que aparezca en respuesta a las acciones del usuario y del sistema. En una aplicación real, tal cuadro de mensaje probablemente se llamará en respuesta a la disponibilidad de nuevos datos, a un error, al usuario que intenta eliminar su perfil ("¿está seguro de esto?"), O al usuario que agrega un nuevo contacto y la operación completando con éxito ... etc.</p> + + <p>En esta demostración, obtendremos el cuadro de mensaje que aparecerá cuando el usuario haga clic en el botón.</p> + </li> + <li>Elimina la línea anterior que agregaste.</li> + <li>A continuación, seleccionaremos el botón y guardaremos una referencia a él en una variable. Agregue la siguiente línea a su código, encima de la definición de la función: + <pre class="brush: js">let btn = document.querySelector('button');</pre> + </li> + <li>Finalmente, agregue la siguiente línea debajo de la anterior: + <pre class="brush: js">btn.onclick = displayMessage;</pre> + De una forma similar que nuestra línea dentro de la función <code>closeBtn.onclick...</code>, aquí estamos llamando a algún código en respuesta a un botón al hacer clic. Pero en este caso, en lugar de llamar a una función anónima que contiene algún código, estamos llamando directamente a nuestro nombre de función.</li> + <li>Intente guardar y actualizar la página: ahora debería ver aparecer el cuadro de mensaje cuando hace clic en el botón.</li> +</ol> + +<p>Quizás te estés preguntando por qué no hemos incluido los paréntesis después del nombre de la función. Esto se debe a que no queremos llamar a la función inmediatamente, solo después de hacer clic en el botón. Si intentas cambiar la línea a</p> + +<pre class="brush: js">btn.onclick = displayMessage();</pre> + +<p>y al guardar y volver a cargar, verás que aparece el cuadro de mensaje sin hacer clic en el botón. Los paréntesis en este contexto a veces se denominan "operador de invocación de función". Solo los utiliza cuando desea ejecutar la función inmediatamente en el ámbito actual. Del mismo modo, el código dentro de la función anónima no se ejecuta inmediatamente, ya que está dentro del alcance de la función.</p> + +<p>Si has intentado el último experimento, asegúrate de deshacer el último cambio antes de continuar.</p> + +<h2 id="Mejora_de_la_función_con_parámetros.">Mejora de la función con parámetros.</h2> + +<p>Tal como está, la función aún no es muy útil, no queremos mostrar el mismo mensaje predeterminado cada vez. Mejoremos nuestra función agregando algunos parámetros, permitiéndonos llamarla con algunas opciones diferentes.</p> + +<ol> + <li>En primer lugar, actualice la primera línea de la función: + <pre class="brush: js">function displayMessage() {</pre> + to this: + + <pre class="brush: js">function displayMessage(msgText, msgType) {</pre> + Ahora, cuando llamamos a la función, podemos proporcionar dos valores variables dentro de los paréntesis para especificar el mensaje que se mostrará en el cuadro de mensaje y el tipo de mensaje que es.</li> + <li>Para utilizar el primer parámetro, actualiza la siguiente línea dentro de su función: + <pre class="brush: js">msg.textContent = 'This is a message box';</pre> + to + + <pre class="brush: js">msg.textContent = msgText;</pre> + </li> + <li>Por último, pero no menos importante, ahora necesita actualizar su llamada de función para incluir un texto de mensaje actualizado. Cambia la siguiente línea: + <pre class="brush: js">btn.onclick = displayMessage;</pre> + to this block: + + <pre class="brush: js">btn.onclick = function() { + displayMessage('Woo, this is a different message!'); +};</pre> + Si queremos especificar parámetros dentro de paréntesis para la función a la que estamos llamando, no podemos llamarla directamente, necesitamos colocarla dentro de una función anónima para que no esté en el ámbito inmediato y, por lo tanto, no se llame de inmediato. Ahora no se llamará hasta que se haga clic en el botón.</li> + <li>Vuelva a cargar e intenta el código nuevamente y verás que aún funciona bien, ¡excepto que ahora también puede variar el mensaje dentro del parámetro para obtener diferentes mensajes mostrados en el cuadro!</li> +</ol> + +<h3 id="Un_parámetro_más_complejo.">Un parámetro más complejo.</h3> + +<p>En el siguiente parámetro. Este va a implicar un poco más de trabajo: lo configuraremos de modo que, dependiendo de la configuración del parámetro msgType, la función mostrará un icono diferente y un color de fondo diferente.</p> + +<ol> + <li>En primer lugar, descargue los iconos necesarios para este ejercicio (<a href="https://raw.githubusercontent.com/mdn/learning-area/master/javascript/building-blocks/functions/icons/warning.png">warning</a> y <a href="https://raw.githubusercontent.com/mdn/learning-area/master/javascript/building-blocks/functions/icons/chat.png">chat</a>) de GitHub. Guárdalos en una nueva carpeta llamada <code>icons</code> en la misma localización que tu HTML. + + <div class="note"><strong>Nota</strong>: los iconos <a href="https://www.iconfinder.com/icons/1031466/alarm_alert_error_warning_icon">warning</a> y <a href="https://www.iconfinder.com/icons/1031441/chat_message_text_icon">chat</a> que se encuentran en iconfinder.com, han sido diseñados por <a href="https://www.iconfinder.com/nazarr">Nazarrudin Ansyari</a>. Gracias!</div> + </li> + <li>A continuación, encuentra el CSS dentro de tu archivo HTML. Haremos algunos cambios para dar paso a los iconos. Primero, actualiza el ancho de .msgBox desde: + <pre class="brush: css">width: 200px;</pre> + to + + <pre class="brush: css">width: 242px;</pre> + </li> + <li>Luego, añade las siguientes líneas dentro de la regla<code>.msgBox p { ... }</code>: + <pre class="brush: css">padding-left: 82px; +background-position: 25px center; +background-repeat: no-repeat;</pre> + </li> + <li>Ahora necesitamos añadir código a la función <code>displayMessage()</code> para manejar la visualización de los iconos. Agrega el siguiente bloque justo encima de la llave de cierre (<code>}</code>) de tu función : + <pre class="brush: js">if (msgType === 'warning') { + msg.style.backgroundImage = 'url(icons/warning.png)'; + panel.style.backgroundColor = 'red'; +} else if (msgType === 'chat') { + msg.style.backgroundImage = 'url(icons/chat.png)'; + panel.style.backgroundColor = 'aqua'; +} else { + msg.style.paddingLeft = '20px'; +}</pre> + </li> + <li>Aquí, si el parámetro <code>msgType</code> se establece como <code>'warning'</code>, se muestra el icono de advertencia y el color de fondo del panel se establece en rojo. Si se establece en <code>'chat'</code>, se muestra el icono de chat y el color de fondo del panel se establece en azul aguamarina. Si el parámetro <code>msgType</code> no está configurado en absoluto (o en algo diferente), entonces la parte <code>else { ... }</code> del código entra en juego, y al párrafo simplemente se le da un relleno predeterminado y ningún icono, sin el conjunto de colores del panel de fondo ya sea. Esto proporciona un estado predeterminado si no se proporciona ningún parámetro <code>msgType</code> , lo que significa que es un parámetro opcional.</li> + <li>Vamos a probar nuestra función actualizada , prueba a actualizar la llamada a <code>displayMessage()</code> con esto: + <pre class="brush: js">displayMessage('Woo, this is a different message!');</pre> + to one of these: + + <pre class="brush: js">displayMessage('Your inbox is almost full — delete some mails', 'warning'); +displayMessage('Brian: Hi there, how are you today?','chat');</pre> + Puedes ver cuán útil se está volviendo nuestra (ahora no tan) poca función.</li> +</ol> + +<div class="note"> +<p><strong>Nota</strong>: Si estas teniendo problemas con el ejemplo, sientente libre para coger el ejemplo para trabajar con él, <a href="https://github.com/mdn/learning-area/blob/master/javascript/building-blocks/functions/function-stage-4.html">finished version on GitHub</a> (<a href="http://mdn.github.io/learning-area/javascript/building-blocks/functions/function-stage-4.html">see it running live</a> también), o pídenos ayuda.</p> +</div> + +<h2 id="Conclusión">Conclusión</h2> + +<p>¡Felicidades por llegar al final! Este artículo lo llevó a través de todo el proceso de creación de una función personalizada y práctica, que con un poco más de trabajo podría trasplantarse en un proyecto real. En el siguiente artículo resumiremos las funciones explicando otro concepto esencial relacionado: valores de retorno.</p> + +<ul> +</ul> + +<p>{{PreviousMenuNext("Learn/JavaScript/Building_blocks/Functions","Learn/JavaScript/Building_blocks/Return_values", "Learn/JavaScript/Building_blocks")}}</p> + +<h2 id="En_este_módulo">En este módulo</h2> + +<ul> + <li><a href="/en-US/docs/Learn/JavaScript/Building_blocks/conditionals">Making decisions in your code — conditionals</a></li> + <li><a href="/en-US/docs/Learn/JavaScript/Building_blocks/Looping_code">Looping code</a></li> + <li><a href="/en-US/docs/Learn/JavaScript/Building_blocks/Functions">Functions — reusable blocks of code</a></li> + <li><a href="/en-US/docs/Learn/JavaScript/Building_blocks/Build_your_own_function">Build your own function</a></li> + <li><a href="/en-US/docs/Learn/JavaScript/Building_blocks/Return_values">Function return values</a></li> + <li><a href="/en-US/docs/Learn/JavaScript/Building_blocks/Events">Introduction to events</a></li> + <li><a href="/en-US/docs/Learn/JavaScript/Building_blocks/Image_gallery">Image gallery</a></li> +</ul> diff --git a/files/es/learn/javascript/building_blocks/eventos/index.html b/files/es/learn/javascript/building_blocks/eventos/index.html new file mode 100644 index 0000000000..7bdb81768a --- /dev/null +++ b/files/es/learn/javascript/building_blocks/eventos/index.html @@ -0,0 +1,578 @@ +--- +title: Introducción a eventos +slug: Learn/JavaScript/Building_blocks/Eventos +translation_of: Learn/JavaScript/Building_blocks/Events +--- +<div>{{LearnSidebar}}</div> + +<div>{{PreviousMenuNext("Learn/JavaScript/Building_blocks/Return_values","Learn/JavaScript/Building_blocks/Image_gallery", "Learn/JavaScript/Building_blocks")}}</div> + +<p class="summary">Los eventos son acciones u ocurrencias que suceden en el sistema que está programando y que el sistema le informa para que pueda responder de alguna manera si lo desea. Por ejemplo, si el usuario hace clic en un botón en una página web, es posible que desee responder a esa acción mostrando un cuadro de información. En este artículo, discutiremos algunos conceptos importantes que rodean los eventos y veremos cómo funcionan en los navegadores. Este no será un estudio exhaustivo; solo lo que necesitas saber en esta etapa.</p> + +<table class="learn-box standard-table"> + <tbody> + <tr> + <th scope="row">Prerrequisitos:</th> + <td>Conocimientos básicos de informática, entendimiento básico de HTML y CSS, <a href="https://developer.mozilla.org/es/docs/Learn/JavaScript/First_steps">Primeros pasos con JavaScript</a>.</td> + </tr> + <tr> + <th scope="row">Objetivo:</th> + <td>Comprender la teoría fundamental de los eventos, cómo funcionan en los navegadores y cómo los eventos pueden diferir en distintos entornos de programación.</td> + </tr> + </tbody> +</table> + +<h2 id="Una_serie_de_eventos_afortunados">Una serie de eventos afortunados</h2> + +<p>Como se mencionó anteriormente, los <strong>eventos</strong> son acciones u ocurrencias que suceden en el sistema que está programando — el sistema disparará una señal de algún tipo cuando un evento ocurra y también proporcionará un mecanismo por el cual se puede tomar algún tipo de acción automáticamente (p.e., ejecutando algún código) cuando se produce el evento. Por ejemplo, en un aeropuerto cuando la pista está despejada para que despegue un avión, se comunica una señal al piloto y, como resultado, comienzan a pilotar el avión.</p> + +<p><img alt="" src="https://mdn.mozillademos.org/files/14077/MDN-mozilla-events-runway.png" style="display: block; margin: 0px auto;"></p> + +<p>En el caso de la Web, los eventos se desencadenan dentro de la ventana del navegador y tienden a estar unidos a un elemento específico que reside en ella — podría ser un solo elemento, un conjunto de elementos, el documento HTML cargado en la pestaña actual o toda la ventana del navegador. Hay muchos tipos diferentes de eventos que pueden ocurrir, por ejemplo:</p> + +<ul> + <li>El usuario hace clic con el mouse sobre un elemento determinado o coloca el cursor sobre un elemento determinado.</li> + <li>El usuario presiona una tecla en el teclado.</li> + <li>El usuario cambia el tamaño o cierra la ventana del navegador.</li> + <li>Una página web termina de cargar.</li> + <li>Un formulario se envía</li> + <li>Un video se reproduce, pausa o finaliza la reproducción.</li> + <li>Un error ocurre.</li> +</ul> + +<p>Se deducirá de esto (y echar un vistazo a MDN <a href="https://developer.mozilla.org/es/docs/Web/Events">Referencia de eventos</a>) que hay <strong>muchos</strong> eventos a los que se puede responder.</p> + +<p>Cada evento disponible tiene un <strong>controlador de eventos</strong>, que es un bloque de código (generalmente una función JavaScript definida por el usuario) que se ejecutará cuando se active el evento. Cuando dicho bloque de código se define para ejecutarse en respuesta a un disparo de evento, decimos que estamos <strong>registrando un controlador de eventos</strong>. Tenga en cuenta que los controladores de eventos a veces se llaman <strong>oyentes de eventos</strong> — son bastante intercambiables para nuestros propósitos, aunque estrictamente hablando, trabajan juntos. El oyente escucha si ocurre el evento y el controlador es el código que se ejecuta en respuesta a que ocurra.</p> + +<div class="note"> +<p><strong>Nota</strong>: Es útil tener en cuenta que los eventos web no son parte del lenguaje central de JavaScript: se definen como parte de las API integradas en el navegador.</p> +</div> + +<h3 id="Un_ejemplo_simple">Un ejemplo simple</h3> + +<p>Veamos un ejemplo simple para explicar lo que queremos decir aquí. Ya has visto eventos y controladores de eventos en muchos de los ejemplos de este curso, pero vamos a recapitular solo para consolidar nuestro conocimiento. En el siguiente ejemplo, tenemos un solo {{htmlelement ("button")}}, que cuando se presiona, hará que el fondo cambie a un color aleatorio:</p> + +<pre class="brush: html notranslate"><button>Cambiar color</button></pre> + +<div class="hidden"> +<pre class="brush: css notranslate">button { margin: 10px };</pre> +</div> + +<p>El JavaScript se ve así:</p> + +<pre class="brush: js notranslate">const btn = document.querySelector('button'); + +function random(number) { + return Math.floor(Math.random() * (number+1)); +} + +btn.onclick = function() { + const rndCol = 'rgb(' + random(255) + ',' + random(255) + ',' + random(255) + ')'; + document.body.style.backgroundColor = rndCol; +}</pre> + +<p>En este código, almacenamos una referencia al botón dentro de una variable llamada <code>btn</code>, usando la función {{domxref ("Document.querySelector ()")}}. También definimos una función que devuelve un número aleatorio. La tercera parte del código es el controlador de eventos. La variable <code>btn</code> apunta a un elemento <code><button></code>, y este tipo de objeto tiene una serie de eventos que pueden activarse y, por lo tanto, los controladores de eventos están disponibles. Estamos escuchando el disparo del evento "click", estableciendo la propiedad del controlador de eventos <code>onclick</code> para que sea igual a una función anónima que contiene código que generó un color RGB aleatorio y establece el <code><body></code> color de fondo igual a este.</p> + +<p>Este código ahora se ejecutará cada vez que se active el evento "click" en el elemento <code><button></code>, es decir, cada vez que un usuario haga clic en él.</p> + +<p>El resultado de ejemplo es el siguiente:</p> + +<p>{{ EmbedLiveSample('A_simple_example', '100%', 200, "", "", "hide-codepen-jsfiddle") }}</p> + +<h3 id="No_son_solo_páginas_web">No son solo páginas web</h3> + +<p>Otra cosa que vale la pena mencionar en este punto es que los eventos no son particulares de JavaScript — la mayoría de los lenguajes de programación tienen algún tipo de modelo de eventos, y la forma en que funciona a menudo diferirá de la forma en que funciona en JavaScript. De hecho, el modelo de eventos en JavaScript para páginas web difiere del modelo de eventos para JavaScript, ya que se utiliza en otros entornos.</p> + +<p>Por ejemplo, <a href="/en-US/docs/Learn/Server-side/Express_Nodejs">Node.js</a> es un entorno en tiempo de ejecución de JavaScript muy popular que permite a los desarrolladores usar JavaScript para crear aplicaciones de red y del lado del servidor. El <a href="https://nodejs.org/docs/latest-v5.x/api/events.html">modelo de eventos de Node.js</a> se basa en que los oyentes (<em>listeners</em>) escuchen eventos y los emisores (<em>emitters</em>) emitan eventos periódicamente — no suena tan diferentes, pero el código es bastante diferente, haciendo uso de funciones como <code>on()</code> para registrar un oyente de eventos, y <code>once()</code> para registrar un oyente de eventos que anula el registro después de que se haya ejecutado una vez. The <a href="https://nodejs.org/docs/latest-v8.x/api/http.html#http_event_connect">documentos de eventos de conexión HTTP</a> proporcionan un buen ejemplo de uso.</p> + +<p>Como otro ejemplo, ahora también puede usar JavaScript para crear complementos de navegadores — mejoras de funcionalidad del navegador — utilizando una tecnología llamada <a href="/en-US/docs/Mozilla/Add-ons/WebExtensions">WebExtensions</a>. El modelo de eventos es similar al modelo de eventos web, pero un poco diferente — las propiedades de los oyentes de eventos se escriben en <em>camel-case</em> (ej. <code>onMessage</code> en lugar de <code>onmessage</code>), y deben combinarse con la función <code>addListener</code>. Consulte la página <a href="/en-US/Add-ons/WebExtensions/API/runtime/onMessage#Examples">runtime.onMessage </a>para ver un ejemplo.</p> + +<p>No necesita comprender nada sobre otros entornos en esta etapa de su aprendizaje; solo queríamos dejar en claro que los eventos pueden diferir en diferentes entornos de programación.</p> + +<h2 id="Diferentes_formas_de_uso_de_eventos">Diferentes formas de uso de eventos</h2> + +<p>Hay muchas maneras distintas en las que puedes agregar event listeners a los sitios web, que se ejecutara cuando el evento asociado se dispare. En esta sección, revisaremos los diferentes mecanismos y discutiremos cuales deberias usar..</p> + +<h3 id="Propiedades_de_manejadores_de_eventos">Propiedades de manejadores de eventos</h3> + +<p>Estas son las propiedades que existen, que contienen codigo de manejadores de eventos(Event Handler) que vemos frecuentemente durante el curso.. Volviendo al ejemplo de arriba:</p> + +<pre class="brush: js notranslate">var btn = document.querySelector('button'); + +btn.onclick = function() { + var rndCol = 'rgb(' + random(255) + ',' + random(255) + ',' + random(255) + ')'; + document.body.style.backgroundColor = rndCol; +}</pre> + +<p>La propiedad <code><a href="/en-US/docs/Web/API/GlobalEventHandlers/onclick">onclick</a></code> es la propiedad del manejador de eventos que está siendo usada en esta situación. Es escencialmente una propiedad como cualquier otra disponible en el botón (por ejemplo: <code><a href="/en-US/docs/Web/API/Node/textContent">btn.textContent</a></code>, or <code><a href="/en-US/docs/Web/API/HTMLElement/style">btn.style</a></code>), pero es de un tipo especial — cuando lo configura para ser igual a algún código, ese código se ejecutará cuando el evento se dispare en el botón.</p> + +<p>You could also set the handler property to be equal to a named function name (like we saw in <a href="/en-US/docs/Learn/JavaScript/Building_blocks/Build_your_own_function">Build your own function</a>). The following would work just the same:</p> + +<pre class="brush: js notranslate">var btn = document.querySelector('button'); + +function bgChange() { + var rndCol = 'rgb(' + random(255) + ',' + random(255) + ',' + random(255) + ')'; + document.body.style.backgroundColor = rndCol; +} + +btn.onclick = bgChange;</pre> + +<p>There are many different event handler properties available. Let's do an experiment.</p> + +<p>First of all, make a local copy of <a href="https://github.com/mdn/learning-area/blob/master/javascript/building-blocks/events/random-color-eventhandlerproperty.html">random-color-eventhandlerproperty.html</a>, and open it in your browser. It's just a copy of the simple random color example we've been playing with already in this article. Now try changing <code>btn.onclick</code> to the following different values in turn, and observing the results in the example:</p> + +<ul> + <li><code><a href="/en-US/docs/Web/API/GlobalEventHandlers/onfocus">btn.onfocus</a></code> and <code><a href="/en-US/docs/Web/API/GlobalEventHandlers/onblur">btn.onblur</a></code> — The color will change when the button is focused and unfocused (try pressing tab to tab on to the button and off again). These are often used to display information about how to fill in form fields when they are focused, or display an error message if a form field has just been filled in with an incorrect value.</li> + <li><code><a href="/en-US/docs/Web/API/GlobalEventHandlers/ondblclick">btn.ondblclick</a></code> — The color will change only when it is double-clicked.</li> + <li><code><a href="/en-US/docs/Web/API/GlobalEventHandlers/onkeypress">window.onkeypress</a></code>, <code><a href="/en-US/docs/Web/API/GlobalEventHandlers/onkeydown">window.onkeydown</a></code>, <code><a href="/en-US/docs/Web/API/GlobalEventHandlers/onkeyup">window.onkeyup</a></code> — The color will change when a key is pressed on the keyboard. <code>keypress</code> refers to a general press (button down and then up), while <code>keydown</code> and <code>keyup</code> refer to just the key down and key up parts of the keystroke, respectively. Note that it doesn't work if you try to register this event handler on the button itself — we've had to register it on the <a href="/en-US/docs/Web/API/Window">window</a> object, which represents the entire browser window.</li> + <li><code><a href="/en-US/docs/Web/API/GlobalEventHandlers/onmouseover">btn.onmouseover</a></code> and <code><a href="/en-US/docs/Web/API/GlobalEventHandlers/onmouseout">btn.onmouseout</a></code> — The color will change when the mouse pointer is moved so it begins hovering over the button, or when it stops hovering over the button and moves off of it, respectively.</li> +</ul> + +<p>Some events are very general and available nearly anywhere (for example an <code>onclick</code> handler can be registered on nearly any element), whereas some are more specific and only useful in certain situations (for example it makes sense to use <a href="/en-US/docs/Web/API/GlobalEventHandlers/GlobalEventHandlers.onplay">onplay</a> only on specific elements, such as {{htmlelement("video")}}).</p> + +<h3 id="Inline_event_handlers_—_dont_use_these">Inline event handlers — don't use these</h3> + +<p>You might also see a pattern like this in your code:</p> + +<pre class="brush: html notranslate"><button onclick="bgChange()">Press me</button> +</pre> + +<pre class="brush: js notranslate">function bgChange() { + var rndCol = 'rgb(' + random(255) + ',' + random(255) + ',' + random(255) + ')'; + document.body.style.backgroundColor = rndCol; +}</pre> + +<div class="note"> +<p><strong>Note</strong>: You can find the <a href="https://github.com/mdn/learning-area/blob/master/javascript/building-blocks/events/random-color-eventhandlerattributes.html">full source code</a> for this example on GitHub (also <a href="http://mdn.github.io/learning-area/javascript/building-blocks/events/random-color-eventhandlerattributes.html">see it running live</a>).</p> +</div> + +<p>The earliest method of registering event handlers found on the Web involved <strong>event handler HTML attributes</strong> (aka <strong>inline event handlers</strong>) like the one shown above — the attribute value is literally the JavaScript code you want to run when the event occurs. The above example invokes a function defined inside a {{htmlelement("script")}} element on the same page, but you could also insert JavaScript directly inside the attribute, for example:</p> + +<pre class="brush: html notranslate"><button onclick="alert('Hello, this is my old-fashioned event handler!');">Press me</button></pre> + +<p>You'll find HTML attribute equivalents for many of the event handler properties; however, you shouldn't use these — they are considered bad practice. It might seem easy to use an event handler attribute if you are just doing something really quick, but they very quickly become unmanageable and inefficient.</p> + +<p>For a start, it is not a good idea to mix up your HTML and your JavaScript, as it becomes hard to parse — keeping your JavaScript all in one place is better; if it is in a separate file you can apply it to multiple HTML documents.</p> + +<p>Even in a single file, inline event handlers are not a good idea. One button is OK, but what if you had 100 buttons? You'd have to add 100 attributes to the file; it would very quickly turn into a maintenance nightmare. With JavaScript, you could easily add an event handler function to all the buttons on the page no matter how many there were, using something like this:</p> + +<pre class="brush: js notranslate">var buttons = document.querySelectorAll('button'); + +for (var i = 0; i < buttons.length; i++) { + buttons[i].onclick = bgChange; +}</pre> + +<p class="brush: js">Note that another option here would be to use the <code><a href="/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/forEach">forEach()</a></code> built-in method available on all Array objects:</p> + +<pre class="brush: js notranslate">buttons.forEach(function(button) { + button.onclick = bgChange; +});</pre> + +<div class="note"> +<p><strong>Note</strong>: Separating your programming logic from your content also makes your site more friendly to search engines.</p> +</div> + +<h3 id="addEventListener_and_removeEventListener">addEventListener() and removeEventListener()</h3> + +<p>The newest type of event mechanism is defined in the <a href="https://www.w3.org/TR/DOM-Level-2-Events/">Document Object Model (DOM) Level 2 Events</a> Specification, which provides browsers with a new function — <code><a href="/en-US/docs/Web/API/EventTarget/addEventListener">addEventListener()</a></code>. This functions in a similar way to the event handler properties, but the syntax is obviously different. We could rewrite our random color example to look like this:</p> + +<pre class="brush: js notranslate">var btn = document.querySelector('button'); + +function bgChange() { + var rndCol = 'rgb(' + random(255) + ',' + random(255) + ',' + random(255) + ')'; + document.body.style.backgroundColor = rndCol; +} + +btn.addEventListener('click', bgChange);</pre> + +<div class="note"> +<p><strong>Note</strong>: You can find the <a href="https://github.com/mdn/learning-area/blob/master/javascript/building-blocks/events/random-color-addeventlistener.html">full source code</a> for this example on GitHub (also <a href="http://mdn.github.io/learning-area/javascript/building-blocks/events/random-color-addeventlistener.html">see it running live</a>).</p> +</div> + +<p>Inside the <code>addEventListener()</code> function, we specify two parameters — the name of the event we want to register this handler for, and the code that comprises the handler function we want to run in response to it. Note that it is perfectly appropriate to put all the code inside the <code>addEventListener()</code> function, in an anonymous function, like this:</p> + +<pre class="brush: js notranslate">btn.addEventListener('click', function() { + var rndCol = 'rgb(' + random(255) + ',' + random(255) + ',' + random(255) + ')'; + document.body.style.backgroundColor = rndCol; +});</pre> + +<p>This mechanism has some advantages over the older mechanisms discussed earlier. For a start, there is a counterpart function, <code><a href="/en-US/docs/Web/API/EventTarget/removeEventListener">removeEventListener()</a></code>, which removes a previously added listener. For example, this would remove the listener set in the first code block in this section:</p> + +<pre class="brush: js notranslate">btn.removeEventListener('click', bgChange);</pre> + +<p>This isn't significant for simple, small programs, but for larger, more complex programs it can improve efficiency to clean up old unused event handlers. Plus, for example, this allows you to have the same button performing different actions in different circumstances — all you've got to do is add/remove event handlers as appropriate.</p> + +<p>Second, you can also register multiple handlers for the same listener. The following two handlers would not be applied:</p> + +<pre class="brush: js notranslate">myElement.onclick = functionA; +myElement.onclick = functionB;</pre> + +<p>As the second line would overwrite the value of <code>onclick</code> set by the first. This would work, however:</p> + +<pre class="brush: js notranslate">myElement.addEventListener('click', functionA); +myElement.addEventListener('click', functionB);</pre> + +<p>Both functions would now run when the element is clicked.</p> + +<p>In addition, there are a number of other powerful features and options available with this event mechanism. These are a little out of scope for this article, but if you want to read up on them, have a look at the <code><a href="/en-US/docs/Web/API/EventTarget/addEventListener">addEventListener()</a></code> and <code><a href="/en-US/docs/Web/API/EventTarget/removeEventListener">removeEventListener()</a></code> reference pages.</p> + +<h3 id="What_mechanism_should_I_use">What mechanism should I use?</h3> + +<p>Of the three mechanisms, you definitely shouldn't use the HTML event handler attributes — these are outdated, and bad practice, as mentioned above.</p> + +<p>The other two are relatively interchangeable, at least for simple uses:</p> + +<ul> + <li>Event handler properties have less power and options, but better cross-browser compatibility (being supported as far back as Internet Explorer 8). You should probably start with these as you are learning.</li> + <li>DOM Level 2 Events (<code>addEventListener()</code>, etc.) are more powerful, but can also become more complex and are less well supported (supported as far back as Internet Explorer 9). You should also experiment with these, and aim to use them where possible.</li> +</ul> + +<p>The main advantages of the third mechanism are that you can remove event handler code if needed, using <code>removeEventListener()</code>, and you can add multiple listeners of the same type to elements if required. For example, you can call <code>addEventListener('click', function() { ... })</code> on an element multiple times, with different functions specified in the second argument. This is impossible with event handler properties because any subsequent attempts to set a property will overwrite earlier ones, e.g.:</p> + +<pre class="brush: js notranslate">element.onclick = function1; +element.onclick = function2; +etc.</pre> + +<div class="note"> +<p><strong>Note</strong>: If you are called upon to support browsers older than Internet Explorer 8 in your work, you may run into difficulties, as such ancient browsers use different event models from newer browsers. But never fear, most JavaScript libraries (for example <code>jQuery</code>) have built-in functions that abstract away cross-browser differences. Don't worry about this too much at this stage in your learning journey.</p> +</div> + +<h2 id="Other_event_concepts">Other event concepts</h2> + +<p>In this section, we will briefly cover some advanced concepts that are relevant to events. It is not important to understand these fully at this point, but it might serve to explain some code patterns you'll likely come across from time to time.</p> + +<h3 id="Event_objects">Event objects</h3> + +<p>Sometimes inside an event handler function, you might see a parameter specified with a name such as <code>event</code>, <code>evt</code>, or simply <code>e</code>. This is called the <strong>event object</strong>, and it is automatically passed to event handlers to provide extra features and information. For example, let's rewrite our random color example again slightly:</p> + +<pre class="brush: js notranslate">function bgChange(e) { + var rndCol = 'rgb(' + random(255) + ',' + random(255) + ',' + random(255) + ')'; + e.target.style.backgroundColor = rndCol; + console.log(e); +} + +btn.addEventListener('click', bgChange);</pre> + +<div class="note"> +<p><strong>Note</strong>: You can find the <a href="https://github.com/mdn/learning-area/blob/master/javascript/building-blocks/events/random-color-eventobject.html">full source code</a> for this example on GitHub (also <a href="http://mdn.github.io/learning-area/javascript/building-blocks/events/random-color-eventobject.html">see it running live</a>).</p> +</div> + +<p>Here you can see that we are including an event object, <strong>e</strong>, in the function, and in the function setting a background color style on <code>e.target</code> — which is the button itself. The <code>target</code> property of the event object is always a reference to the element that the event has just occurred upon. So in this example, we are setting a random background color on the button, not the page.</p> + +<div class="note"> +<p><strong>Note</strong>: You can use any name you like for the event object — you just need to choose a name that you can then use to reference it inside the event handler function. <code>e</code>/<code>evt</code>/<code>event</code> are most commonly used by developers because they are short and easy to remember. It's always good to stick to a standard.</p> +</div> + +<p><code>e.target</code> is incredibly useful when you want to set the same event handler on multiple elements and do something to all of them when an event occurs on them. You might, for example, have a set of 16 tiles that disappear when they are clicked on. It is useful to always be able to just set the thing to disappear as <code>e.target</code>, rather than having to select it in some more difficult way. In the following example (see <a href="https://github.com/mdn/learning-area/blob/master/javascript/building-blocks/events/useful-eventtarget.html">useful-eventtarget.html</a> for the full source code; also see it <a href="http://mdn.github.io/learning-area/javascript/building-blocks/events/useful-eventtarget.html">running live</a> here), we create 16 {{htmlelement("div")}} elements using JavaScript. We then select all of them using {{domxref("document.querySelectorAll()")}}, then loop through each one, adding an <code>onclick</code> handler to each that makes it so that a random color is applied to each one when clicked:</p> + +<pre class="brush: js notranslate">var divs = document.querySelectorAll('div'); + +for (var i = 0; i < divs.length; i++) { + divs[i].onclick = function(e) { + e.target.style.backgroundColor = bgChange(); + } +}</pre> + +<p>The output is as follows (try clicking around on it — have fun):</p> + +<div class="hidden"> +<h6 id="Hidden_example">Hidden example</h6> + +<pre class="brush: html notranslate"><!DOCTYPE html> +<html> + <head> + <meta charset="utf-8"> + <title>Useful event target example</title> + <style> + div { + height: 100px; + width: 25%; + float: left; + } + </style> + </head> + <body> + <script> + for (var i = 1; i <= 16; i++) { + var myDiv = document.createElement('div'); + myDiv.style.backgroundColor = "red"; + document.body.appendChild(myDiv); + } + + function random(number) { + return Math.floor(Math.random()*number); + } + + function bgChange() { + var rndCol = 'rgb(' + random(255) + ',' + random(255) + ',' + random(255) + ')'; + return rndCol; + } + + var divs = document.querySelectorAll('div'); + + for (var i = 0; i < divs.length; i++) { + divs[i].onclick = function(e) { + e.target.style.backgroundColor = bgChange(); + } + } + </script> + </body> +</html></pre> +</div> + +<p>{{ EmbedLiveSample('Hidden_example', '100%', 400, "", "", "hide-codepen-jsfiddle") }}</p> + +<p>Most event handlers you'll encounter just have a standard set of properties and functions (methods) available on the event object (see the {{domxref("Event")}} object reference for a full list). Some more advanced handlers, however, add specialist properties containing extra data that they need to function. The <a href="/en-US/docs/Web/API/MediaRecorder_API">Media Recorder API</a>, for example, has a <code>dataavailable</code> event, which fires when some audio or video has been recorded and is available for doing something with (for example saving it, or playing it back). The corresponding <a href="/en-US/docs/Web/API/MediaRecorder/ondataavailable">ondataavailable</a> handler's event object has a <code>data</code> property available containing the recorded audio or video data to allow you to access it and do something with it.</p> + +<h3 id="Preventing_default_behavior">Preventing default behavior</h3> + +<p>Sometimes, you'll come across a situation where you want to stop an event doing what it does by default. The most common example is that of a web form, for example, a custom registration form. When you fill in the details and press the submit button, the natural behaviour is for the data to be submitted to a specified page on the server for processing, and the browser to be redirected to a "success message" page of some kind (or the same page, if another is not specified.)</p> + +<p>The trouble comes when the user has not submitted the data correctly — as a developer, you'll want to stop the submission to the server and give them an error message telling them what's wrong and what needs to be done to put things right. Some browsers support automatic form data validation features, but since many don't, you are advised to not rely on those and implement your own validation checks. Let's look at a simple example.</p> + +<p>First, a simple HTML form that requires you to enter your first and last name:</p> + +<pre class="brush: html notranslate"><form> + <div> + <label for="fname">First name: </label> + <input id="fname" type="text"> + </div> + <div> + <label for="lname">Last name: </label> + <input id="lname" type="text"> + </div> + <div> + <input id="submit" type="submit"> + </div> +</form> +<p></p></pre> + +<div class="hidden"> +<pre class="brush: css notranslate">div { + margin-bottom: 10px; +} +</pre> +</div> + +<p>Now some JavaScript — here we implement a very simple check inside an <a href="/en-US/docs/Web/API/GlobalEventHandlers/onsubmit">onsubmit</a> event handler (the submit event is fired on a form when it is submitted) that tests whether the text fields are empty. If they are, we call the <code><a href="/en-US/docs/Web/API/Event/preventDefault">preventDefault()</a></code> function on the event object — which stops the form submission — and then display an error message in the paragraph below our form to tell the user what's wrong:</p> + +<pre class="brush: js notranslate">var form = document.querySelector('form'); +var fname = document.getElementById('fname'); +var lname = document.getElementById('lname'); +var submit = document.getElementById('submit'); +var para = document.querySelector('p'); + +form.onsubmit = function(e) { + if (fname.value === '' || lname.value === '') { + e.preventDefault(); + para.textContent = 'You need to fill in both names!'; + } +}</pre> + +<p>Obviously, this is pretty weak form validation — it wouldn't stop the user validating the form with spaces or numbers entered into the fields, for example — but it is ok for example purposes. The output is as follows:</p> + +<p>{{ EmbedLiveSample('Preventing_default_behavior', '100%', 140, "", "", "hide-codepen-jsfiddle") }}</p> + +<div class="note"> +<p><strong>Note</strong>: for the full source code, see <a href="https://github.com/mdn/learning-area/blob/master/javascript/building-blocks/events/preventdefault-validation.html">preventdefault-validation.html</a> (also see it <a href="http://mdn.github.io/learning-area/javascript/building-blocks/events/preventdefault-validation.html">running live</a> here.)</p> +</div> + +<h3 id="Event_bubbling_and_capture">Event bubbling and capture</h3> + +<p>The final subject to cover here is something that you'll not come across often, but it can be a real pain if you don't understand it. Event bubbling and capture are two mechanisms that describe what happens when two handlers of the same event type are activated on one element. Let's look at an example to make this easier — open up the <a href="http://mdn.github.io/learning-area/javascript/building-blocks/events/show-video-box.html">show-video-box.html</a> example in a new tab (and the <a href="https://github.com/mdn/learning-area/blob/master/javascript/building-blocks/events/show-video-box.html">source code</a> in another tab.) It is also available live below:</p> + +<div class="hidden"> +<h6 id="Hidden_video_example">Hidden video example</h6> + +<pre class="brush: html notranslate"><!DOCTYPE html> +<html> + <head> + <meta charset="utf-8"> + <title>Show video box example</title> + <style> + div { + position: absolute; + top: 50%; + transform: translate(-50%,-50%); + width: 480px; + height: 380px; + border-radius: 10px; + background-color: #eee; + background-image: linear-gradient(to bottom, rgba(0,0,0,0), rgba(0,0,0,0.1)); + } + + .hidden { + left: -50%; + } + + .showing { + left: 50%; + } + + div video { + display: block; + width: 400px; + margin: 40px auto; + } + + </style> + </head> + <body> + <button>Display video</button> + + <div class="hidden"> + <video> + <source src="https://raw.githubusercontent.com/mdn/learning-area/master/javascript/building-blocks/events/rabbit320.mp4" type="video/mp4"> + <source src="https://raw.githubusercontent.com/mdn/learning-area/master/javascript/building-blocks/events/rabbit320.webm" type="video/webm"> + <p>Your browser doesn't support HTML5 video. Here is a <a href="rabbit320.mp4">link to the video</a> instead.</p> + </video> + </div> + + <script> + + var btn = document.querySelector('button'); + var videoBox = document.querySelector('div'); + var video = document.querySelector('video'); + + btn.onclick = function() { + displayVideo(); + } + + function displayVideo() { + if(videoBox.getAttribute('class') === 'hidden') { + videoBox.setAttribute('class','showing'); + } + } + + videoBox.addEventListener('click',function() { + videoBox.setAttribute('class','hidden'); + }); + + video.addEventListener('click',function() { + video.play(); + }); + + </script> + </body> +</html></pre> +</div> + +<p>{{ EmbedLiveSample('Hidden_video_example', '100%', 500, "", "", "hide-codepen-jsfiddle") }}</p> + +<p>This is a pretty simple example that shows and hides a {{htmlelement("div")}} with a {{htmlelement("video")}} element inside it:</p> + +<pre class="brush: html notranslate"><button>Display video</button> + +<div class="hidden"> + <video> + <source src="rabbit320.mp4" type="video/mp4"> + <source src="rabbit320.webm" type="video/webm"> + <p>Your browser doesn't support HTML5 video. Here is a <a href="rabbit320.mp4">link to the video</a> instead.</p> + </video> +</div></pre> + +<p>When the {{htmlelement("button")}} is clicked, the video is displayed, by changing the class attribute on the <code><div></code> from <code>hidden</code> to <code>showing</code> (the example's CSS contains these two classes, which position the box off the screen and on the screen, respectively):</p> + +<pre class="brush: js notranslate">btn.onclick = function() { + videoBox.setAttribute('class', 'showing'); +}</pre> + +<p>We then add a couple more <code>onclick</code> event handlers — the first one to the <code><div></code> and the second one to the <code><video></code>. The idea is that when the area of the <code><div></code> outside the video is clicked, the box should be hidden again; when the video itself is clicked, the video should start to play.</p> + +<pre class="brush: js notranslate">videoBox.onclick = function() { + videoBox.setAttribute('class', 'hidden'); +}; + +video.onclick = function() { + video.play(); +};</pre> + +<p>But there's a problem — currently, when you click the video it starts to play, but it causes the <code><div></code> to also be hidden at the same time. This is because the video is inside the <code><div></code> — it is part of it — so clicking on the video actually runs <em>both</em> the above event handlers.</p> + +<h4 id="Bubbling_and_capturing_explained">Bubbling and capturing explained</h4> + +<p>When an event is fired on an element that has parent elements (e.g. the {{htmlelement("video")}} in our case), modern browsers run two different phases — the <strong>capturing</strong> phase and the <strong>bubbling</strong> phase.</p> + +<p>In the <strong>capturing</strong> phase:</p> + +<ul> + <li>The browser checks to see if the element's outer-most ancestor ({{htmlelement("html")}}) has an <code>onclick</code> event handler registered on it in the capturing phase, and runs it if so.</li> + <li>Then it moves on to the next element inside <code><html></code> and does the same thing, then the next one, and so on until it reaches the element that was actually clicked on.</li> +</ul> + +<p>In the <strong>bubbling</strong> phase, the exact opposite occurs:</p> + +<ul> + <li>The browser checks to see if the element that was actually clicked on has an <code>onclick</code> event handler registered on it in the bubbling phase, and runs it if so.</li> + <li>Then it moves on to the next immediate ancestor element and does the same thing, then the next one, and so on until it reaches the <code><html></code> element.</li> +</ul> + +<p><a href="https://mdn.mozillademos.org/files/14075/bubbling-capturing.png"><img alt="" src="https://mdn.mozillademos.org/files/14075/bubbling-capturing.png" style="display: block; height: 452px; margin: 0px auto; width: 960px;"></a></p> + +<p>(Click on image for bigger diagram)</p> + +<p>In modern browsers, by default, all event handlers are registered in the bubbling phase. So in our current example, when you click the video, the click event bubbles from the <code><video></code> element outwards to the <code><html></code> element. Along the way:</p> + +<ul> + <li>It finds the <code>video.onclick...</code> handler and runs it, so the video first starts playing.</li> + <li>It then finds the <code>videoBox.onclick...</code> handler and runs it, so the video is hidden as well.</li> +</ul> + +<h4 id="Fixing_the_problem_with_stopPropagation">Fixing the problem with stopPropagation()</h4> + +<p>This is annoying behavior, but there is a way to fix it! The standard event object has a function available on it called <code><a href="/en-US/docs/Web/API/Event/stopPropagation">stopPropagation()</a></code>, which when invoked on a handler's event object makes it so that handler is run, but the event doesn't bubble any further up the chain, so no more handlers will be run.</p> + +<p>We can, therefore, fix our current problem by changing the second handler function in the previous code block to this:</p> + +<pre class="brush: js notranslate">video.onclick = function(e) { + e.stopPropagation(); + video.play(); +};</pre> + +<p>You can try making a local copy of the <a href="https://github.com/mdn/learning-area/blob/master/javascript/building-blocks/events/show-video-box.html">show-video-box.html source code</a> and having a go at fixing it yourself, or looking at the fixed result in <a href="http://mdn.github.io/learning-area/javascript/building-blocks/events/show-video-box-fixed.html">show-video-box-fixed.html</a> (also see the <a href="https://github.com/mdn/learning-area/blob/master/javascript/building-blocks/events/show-video-box-fixed.html">source code</a> here).</p> + +<div class="note"> +<p><strong>Note</strong>: Why bother with both capturing and bubbling? Well, in the bad old days when browsers were much less cross-compatible than they are now, Netscape only used event capturing, and Internet Explorer used only event bubbling. When the W3C decided to try to standardize the behavior and reach a consensus, they ended up with this system that included both, which is the one modern browsers implemented.</p> +</div> + +<div class="note"> +<p><strong>Note</strong>: As mentioned above, by default all event handlers are registered in the bubbling phase, and this makes more sense most of the time. If you really want to register an event in the capturing phase instead, you can do so by registering your handler using <code><a href="/en-US/docs/Web/API/EventTarget/addEventListener">addEventListener()</a></code>, and setting the optional third property to <code>true</code>.</p> +</div> + +<h4 id="Event_delegation">Event delegation</h4> + +<p>Bubbling also allows us to take advantage of <strong>event delegation</strong> — this concept relies on the fact that if you want some code to run when you click on any one of a large number of child elements, you can set the event listener on their parent and have events that happen on them bubble up to their parent rather than having to set the event listener on every child individually. Remember earlier that we said bubbling involves checking the element the event is fired on for an event handler first, then moving up to the element's parent, etc.?</p> + +<p>A good example is a series of list items — if you want each one of them to pop up a message when clicked, you can set the <code>click</code> event listener on the parent <code><ul></code>, and events will bubble from the list items to the <code><ul></code>.</p> + +<p>This concept is explained further on David Walsh's blog, with multiple examples — see <a href="https://davidwalsh.name/event-delegate">How JavaScript Event Delegation Works</a>.</p> + +<h2 id="Conclusion">Conclusion</h2> + +<p>You should now know all you need to know about web events at this early stage. As mentioned above, events are not really part of the core JavaScript — they are defined in browser Web APIs.</p> + +<p>Also, it is important to understand that the different contexts in which JavaScript is used tend to have different event models — from Web APIs to other areas such as browser WebExtensions and Node.js (server-side JavaScript). We are not expecting you to understand all these areas now, but it certainly helps to understand the basics of events as you forge ahead with learning web development.</p> + +<p>If there is anything you didn't understand, feel free to read through the article again, or <a href="/en-US/Learn#Contact_us">contact us</a> to ask for help.</p> + +<h2 id="See_also">See also</h2> + +<ul> + <li><a href="http://www.quirksmode.org/js/events_order.html">Event order</a> (discussion of capturing and bubbling) — an excellently detailed piece by Peter-Paul Koch.</li> + <li><a href="http://www.quirksmode.org/js/events_access.html">Event accessing</a> (discussion of the event object) — another excellently detailed piece by Peter-Paul Koch.</li> + <li><a href="/en-US/docs/Web/Events">Event reference</a></li> +</ul> + +<p>{{PreviousMenuNext("Learn/JavaScript/Building_blocks/Return_values","Learn/JavaScript/Building_blocks/Image_gallery", "Learn/JavaScript/Building_blocks")}}</p> + +<h2 id="In_this_module">In this module</h2> + +<ul> + <li><a href="/en-US/docs/Learn/JavaScript/Building_blocks/conditionals">Making decisions in your code — conditionals</a></li> + <li><a href="/en-US/docs/Learn/JavaScript/Building_blocks/Looping_code">Looping code</a></li> + <li><a href="/en-US/docs/Learn/JavaScript/Building_blocks/Functions">Functions — reusable blocks of code</a></li> + <li><a href="/en-US/docs/Learn/JavaScript/Building_blocks/Build_your_own_function">Build your own function</a></li> + <li><a href="/en-US/docs/Learn/JavaScript/Building_blocks/Return_values">Function return values</a></li> + <li><a href="/en-US/docs/Learn/JavaScript/Building_blocks/Events">Introduction to events</a></li> + <li><a href="/en-US/docs/Learn/JavaScript/Building_blocks/Image_gallery">Image gallery</a></li> +</ul> diff --git a/files/es/learn/javascript/building_blocks/functions/index.html b/files/es/learn/javascript/building_blocks/functions/index.html new file mode 100644 index 0000000000..d05ae34969 --- /dev/null +++ b/files/es/learn/javascript/building_blocks/functions/index.html @@ -0,0 +1,400 @@ +--- +title: Funciones — bloques de código reutilizables +slug: Learn/JavaScript/Building_blocks/Functions +tags: + - API + - Funciones + - JavaScript + - Métodos + - Navegador +translation_of: Learn/JavaScript/Building_blocks/Functions +--- +<div>{{LearnSidebar}}</div> + +<div>{{PreviousMenuNext("Learn/JavaScript/Building_blocks/Looping_code","Learn/JavaScript/Building_blocks/Build_your_own_function", "Learn/JavaScript/Building_blocks")}}</div> + +<p class="summary">Otro concepto esencial en la codificación son las <strong>funciones</strong>, que te permiten almacenar un fragmento de código que realiza una única tarea dentro de un bloque definido, y luego llamar a ese código siempre que lo necesites utilizando un único comando breve -- en lugar de tener que escribir el mismo codigo varias veces. En este artículo exploraremos conceptos fundamentales detrás de funciones tales como sintaxis básica, cómo invocarlas y definirlas, alcance(scope) y parámetros.</p> + +<table class="learn-box standard-table"> + <tbody> + <tr> + <th scope="row">Prerequisites:</th> + <td>Conocimientos basicos de informatica, conocimiento basico de HTML y CSS, <a href="/en-US/docs/Learn/JavaScript/First_steps">JavaScript first steps</a>.</td> + </tr> + <tr> + <th scope="row">Objective:</th> + <td>Entender los conceptos fundamentales detras de las funciones JavaScript.</td> + </tr> + </tbody> +</table> + +<h2 id="¿Dónde_encuentro_las_funciones">¿Dónde encuentro las funciones? </h2> + +<p>En JavaScript vas a encontrar funciones por todos lados. De hecho, nosotros hemos usados funciones todo el tiempo a lo largo del curso; solo que no hemos hablado mucho sobre ellas. Ahora es el momento, igual, para comenzar a hablar explicitamente sobre las funciones y explorar su sintaxis.</p> + +<p>Básicamente cada vez que haces uso de código JavaScript que contiene parentesis como () y no estás usando estructuras de lenguaje como for loop, while, do, do while, estás usando una función! </p> + +<p>Funciones incluídas en los navegadores</p> + +<p>A lo largo de este curso hemos usado muchas funciones incluídas del navegador. Por ejemplo, cuando manipulamos una cadena de texto o <a href="/es/docs/Web/JavaScript/Referencia/Objetos_globales/String">string</a>:</p> + +<pre class="brush: js notranslate">let miTexto = 'Soy una cadena de texto!'; +let nuevaCadena = miTexto.replace('cadena', 'ensalada'); +console.log(nuevaCadena); +// la función de cadena de texto <strong>replace()</strong> toma una cadena, +// reemplaza una palabra por otra, y devuelve +// una nueva cadena con el reemplazo hecho.</pre> + +<p>O cada vez que manipulamos un <a href="/es/docs/Web/JavaScript/Referencia/Objetos_globales/Array">array</a>:</p> + +<pre class="brush: js notranslate">let miArray = ['Yo', 'amo', 'el', 'chocolate', 'y', 'las', 'ranas']; +let armarCadena = miArray.join(' '); +console.log(armarCadena); +// La función join() toma un array, +// une todos sus elementos en una cadena o string +// y devuelve esta nueva cadena.</pre> + +<p>O cada vez que generamos un número al azar:</p> + +<pre class="brush: js notranslate">var miNumero = Math.random(); +console.log(miNumero); +// La función <a href="/es/docs/Web/JavaScript/Referencia/Objetos_globales/Math/random">Math.random()</a> genera un número aleatorio +// entre 0 and 1 y devuelve ese número. +</pre> + +<p>...estamos usando una función!</p> + +<div class="note"> +<p><strong>Nota</strong>: Sientase libre de ingresar esas líneas de código en la consola JavaScript de su navegador, para familiarizarse con sus funcionalidades. </p> +</div> + +<p>El lenguaje JavaScript contiene muchas funciones integradas que te permiten realizar cosas muy utilies sin escribir el código tu mismo. De hecho, parte del código que llamas (una palabra elegante para decir correr o ejecutar) cuando invocas una función integrada puede no estar escrita en JavaScript —muchas de estas funciones están llamando partes del código del navegador de fondo, que está escrito principalmente en lenguajes de sistema de bajo nivel como C ++, no en lenguajes web como JavaScript.</p> + +<p>Bear in mind that some built-in browser functions are not part of the core JavaScript language — some are defined as part of browser APIs, which build on top of the default language to provide even more functionality (refer to <a href="/en-US/Learn/JavaScript/First_steps/What_is_JavaScript#So_what_can_it_really_do">this early section of our course</a> for more descriptions). We'll look at using browser APIs in more detail in a later module.</p> + +<h2 id="Functions_versus_methods">Functions versus methods</h2> + +<p>One thing we need to clear up before we move on — technically speaking, built in browser functions are not functions — they are <strong>methods</strong>. This sounds a bit scary and confusing, but don't worry — the words function and method are largely interchangeable, at least for our purposes, at this stage in your learning.</p> + +<p>The distinction is that methods are functions defined inside objects. Built-in browser functions (methods) and variables (which are called <strong>properties</strong>) are stored inside structured objects, to make the code more efficient and easier to handle.</p> + +<p>You don't need to learn about the inner workings of structured JavaScript objects yet — you can wait until our later module that will teach you all about the inner workings of objects, and how to create your own. For now, we just wanted to clear up any possible confusion of method versus function — you are likely to meet both terms as you look at the available related resources across the Web.</p> + +<h2 id="Custom_functions">Custom functions</h2> + +<p>You've also seen a lot of <strong>custom functions</strong> in the course so far — functions defined in your code, not inside the browser. Anytime you saw a custom name with parentheses straight after it, you were using a custom function. In our <a href="http://mdn.github.io/learning-area/javascript/building-blocks/loops/random-canvas-circles.html">random-canvas-circles.html</a> example (see also the full <a href="https://github.com/mdn/learning-area/blob/master/javascript/building-blocks/loops/random-canvas-circles.html">source code</a>) from our <a href="/en-US/docs/Learn/JavaScript/Building_blocks/Looping_code">loops article</a>, we included a custom <code>draw()</code> function that looked like this:</p> + +<pre class="brush: js notranslate">function draw() { + ctx.clearRect(0,0,WIDTH,HEIGHT); + for (var i = 0; i < 100; i++) { + ctx.beginPath(); + ctx.fillStyle = 'rgba(255,0,0,0.5)'; + ctx.arc(random(WIDTH), random(HEIGHT), random(50), 0, 2 * Math.PI); + ctx.fill(); + } +}</pre> + +<p>This function draws 100 random circles inside an {{htmlelement("canvas")}} element. Every time we want to do that, we can just invoke the function with this</p> + +<pre class="brush: js notranslate">draw();</pre> + +<p>rather than having to write all that code out again every time we want to repeat it. And functions can contain whatever code you like — you can even call other functions from inside functions. The above function for example calls the <code>random()</code> function three times, which is defined by the following code:</p> + +<pre class="brush: js notranslate">function random(number) { + return Math.floor(Math.random()*number); +}</pre> + +<p>We needed this function because the browser's built-in <a href="/en-US/docs/Web/JavaScript/Reference/Global_Objects/Math/random">Math.random()</a> function only generates a random decimal number between 0 and 1. We wanted a random whole number between 0 and a specified number.</p> + +<h2 id="Invoking_functions">Invoking functions</h2> + +<p>You are probably clear on this by now, but just in case ... to actually use a function after it has been defined, you've got to run — or invoke — it. This is done by including the name of the function in the code somewhere, followed by parentheses.</p> + +<pre class="brush: js notranslate">function myFunction() { + alert('hello'); +} + +myFunction() +// calls the function once</pre> + +<h2 id="Anonymous_functions">Anonymous functions</h2> + +<p>You may see functions defined and invoked in slightly different ways. So far we have just created a function like so:</p> + +<pre class="brush: js notranslate">function myFunction() { + alert('hello'); +}</pre> + +<p>But you can also create a function that doesn't have a name:</p> + +<pre class="brush: js notranslate">function() { + alert('hello'); +}</pre> + +<p>This is called an <strong>anonymous function</strong> — it has no name! It also won't do anything on its own. You generally use an anonymous function along with an event handler, for example the following would run the code inside the function whenever the associated button is clicked:</p> + +<pre class="brush: js notranslate">var myButton = document.querySelector('button'); + +myButton.onclick = function() { + alert('hello'); +}</pre> + +<p>The above example would require there to be a {{htmlelement("button")}} element available on the page to select and click. You've already seen this structure a few times throughout the course, and you'll learn more about and see it in use in the next article.</p> + +<p>You can also assign an anonymous function to be the value of a variable, for example:</p> + +<pre class="brush: js notranslate">var myGreeting = function() { + alert('hello'); +}</pre> + +<p>This function could now be invoked using:</p> + +<pre class="brush: js notranslate">myGreeting();</pre> + +<p>This effectively gives the function a name; you can also assign the function to be the value of multiple variables, for example:</p> + +<pre class="brush: js notranslate">var anotherGreeting = function() { + alert('hello'); +}</pre> + +<p>This function could now be invoked using either of</p> + +<pre class="brush: js notranslate">myGreeting(); +anotherGreeting();</pre> + +<p>But this would just be confusing, so don't do it! When creating functions, it is better to just stick to this form:</p> + +<pre class="brush: js notranslate">function myGreeting() { + alert('hello'); +}</pre> + +<p>You will mainly use anonymous functions to just run a load of code in response to an event firing — like a button being clicked — using an event handler. Again, this looks something like this:</p> + +<pre class="brush: js notranslate">myButton.onclick = function() { + alert('hello'); + // I can put as much code + // inside here as I want +}</pre> + +<h2 id="Function_parameters">Function parameters</h2> + +<p>Some functions require <strong>parameters</strong> to be specified when you are invoking them — these are values that need to be included inside the function parentheses, which it needs to do its job properly.</p> + +<div class="note"> +<p><strong>Note</strong>: Parameters are sometimes called arguments, properties, or even attributes.</p> +</div> + +<p>As an example, the browser's built-in <a href="/en-US/docs/Web/JavaScript/Reference/Global_Objects/Math/random">Math.random()</a> function doesn't require any parameters. When called, it always returns a random number between 0 and 1:</p> + +<pre class="brush: js notranslate">var myNumber = Math.random();</pre> + +<p>The browser's built-in string <a href="/en-US/docs/Web/JavaScript/Reference/Global_Objects/String/replace">replace()</a> function however needs two parameters — the substring to find in the main string, and the substring to replace that string with:</p> + +<pre class="brush: js notranslate">var myText = 'I am a string'; +var newString = myText.replace('string', 'sausage');</pre> + +<div class="note"> +<p><strong>Note</strong>: When you need to specify multiple parameters, they are separated by commas.</p> +</div> + +<p>It should also be noted that sometimes parameters are optional — you don't have to specify them. If you don't, the function will generally adopt some kind of default behavior. As an example, the array <a href="/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/join">join()</a> function's parameter is optional:</p> + +<pre class="brush: js notranslate">var myArray = ['I', 'love', 'chocolate', 'frogs']; +var madeAString = myArray.join(' '); +// returns 'I love chocolate frogs' +var madeAString = myArray.join(); +// returns 'I,love,chocolate,frogs'</pre> + +<p>If no parameter is included to specify a joining/delimiting character, a comma is used by default.</p> + +<h2 id="Function_scope_and_conflicts">Function scope and conflicts</h2> + +<p>Let's talk a bit about {{glossary("scope")}} — a very important concept when dealing with functions. When you create a function, the variables and other things defined inside the function are inside their own separate <strong>scope</strong>, meaning that they are locked away in their own separate compartments, unreachable from inside other functions or from code outside the functions.</p> + +<p>The top level outside all your functions is called the <strong>global scope</strong>. Values defined in the global scope are accessible from everywhere in the code.</p> + +<p>JavaScript is set up like this for various reasons — but mainly because of security and organization. Sometimes you don't want variables to be accessible from everywhere in the code — external scripts that you call in from elsewhere could start to mess with your code and cause problems because they happen to be using the same variable names as other parts of the code, causing conflicts. This might be done maliciously, or just by accident.</p> + +<p>For example, say you have an HTML file that is calling in two external JavaScript files, and both of them have a variable and a function defined that use the same name:</p> + +<pre class="brush: html notranslate"><!-- Excerpt from my HTML --> +<script src="first.js"></script> +<script src="second.js"></script> +<script> + greeting(); +</script></pre> + +<pre class="brush: js notranslate">// first.js +var name = 'Chris'; +function greeting() { + alert('Hello ' + name + ': welcome to our company.'); +}</pre> + +<pre class="brush: js notranslate">// second.js +var name = 'Zaptec'; +function greeting() { + alert('Our company is called ' + name + '.'); +}</pre> + +<p>Both functions you want to call are called <code>greeting()</code>, but you can only ever access the <code>second.js</code> file's <code>greeting()</code> function — it is applied to the HTML later on in the source code, so its variable and function overwrite the ones in <code>first.js</code>.</p> + +<div class="note"> +<p><strong>Note</strong>: You can see this example <a href="http://mdn.github.io/learning-area/javascript/building-blocks/functions/conflict.html">running live on GitHub</a> (see also the <a href="https://github.com/mdn/learning-area/tree/master/javascript/building-blocks/functions">source code</a>).</p> +</div> + +<p>Keeping parts of your code locked away in functions avoids such problems, and is considered best practice.</p> + +<p>It is a bit like a zoo. The lions, zebras, tigers, and penguins are kept in their own enclosures, and only have access to the things inside their enclosures — in the same manner as the function scopes. If they were able to get into other enclosures, problems would occur. At best, different animals would feel really uncomfortable inside unfamiliar habitats — a lion or tiger would feel terrible inside the penguins' watery, icy domain. At worst, the lions and tigers might try to eat the penguins!</p> + +<p><img alt="" src="https://mdn.mozillademos.org/files/14079/MDN-mozilla-zoo.png" style="display: block; margin: 0 auto;"></p> + +<p>The zoo keeper is like the global scope — he or she has the keys to access every enclosure, to restock food, tend to sick animals, etc.</p> + +<h3 id="Active_learning_Playing_with_scope">Active learning: Playing with scope</h3> + +<p>Let's look at a real example to demonstrate scoping.</p> + +<ol> + <li>First, make a local copy of our <a href="https://github.com/mdn/learning-area/blob/master/javascript/building-blocks/functions/function-scope.html">function-scope.html</a> example. This contains two functions called <code>a()</code> and <code>b()</code>, and three variables — <code>x</code>, <code>y</code>, and <code>z</code> — two of which are defined inside the functions, and one in the global scope. It also contains a third function called <code>output()</code>, which takes a single parameter and outputs it in a paragraph on the page.</li> + <li>Open the example up in a browser and in your text editor.</li> + <li>Open the JavaScript console in your browser developer tools. In the JavaScript console, enter the following command: + <pre class="brush: js notranslate">output(x);</pre> + You should see the value of variable <code>x</code> output to the screen.</li> + <li>Now try entering the following in your console + <pre class="brush: js notranslate">output(y); +output(z);</pre> + Both of these should return an error along the lines of "<a href="/en-US/docs/Web/JavaScript/Reference/Errors/Not_defined">ReferenceError: y is not defined</a>". Why is that? Because of function scope — <code>y</code> and <code>z</code> are locked inside the <code>a()</code> and <code>b()</code> functions, so <code>output()</code> can't access them when called from the global scope.</li> + <li>However, what about when it's called from inside another function? Try editing <code>a()</code> and <code>b()</code> so they look like this: + <pre class="brush: js notranslate">function a() { + var y = 2; + output(y); +} + +function b() { + var z = 3; + output(z); +}</pre> + Save the code and reload it in your browser, then try calling the <code>a()</code> and <code>b()</code> functions from the JavaScript console: + + <pre class="brush: js notranslate">a(); +b();</pre> + You should see the <code>y</code> and <code>z</code> values output in the page. This works fine, as the <code>output()</code> function is being called inside the other functions — in the same scope as the variables it is printing are defined in, in each case. <code>output()</code> itself is available from anywhere, as it is defined in the global scope.</li> + <li>Now try updating your code like this: + <pre class="brush: js notranslate">function a() { + var y = 2; + output(x); +} + +function b() { + var z = 3; + output(x); +}</pre> + Save and reload again, and try this again in your JavaScript console: + + <pre class="brush: js notranslate">a(); +b();</pre> + Both the <code>a()</code> and <code>b()</code> call should output the value of x — 1. These work fine because even though the <code>output()</code> calls are not in the same scope as <code>x</code> is defined in, <code>x</code> is a global variable so is available inside all code, everywhere.</li> + <li>Finally, try updating your code like this: + <pre class="brush: js notranslate">function a() { + var y = 2; + output(z); +} + +function b() { + var z = 3; + output(y); +}</pre> + Save and reload again, and try this again in your JavaScript console: + + <pre class="brush: js notranslate">a(); +b();</pre> + This time the <code>a()</code> and <code>b()</code> calls will both return that annoying "<a href="/en-US/docs/Web/JavaScript/Reference/Errors/Not_defined">ReferenceError: z is not defined</a>" error — this is because the <code>output()</code> calls and the variables they are trying to print are not defined inside the same function scopes — the variables are effectively invisible to those function calls.</li> +</ol> + +<div class="note"> +<p><strong>Note</strong>: The same scoping rules do not apply to loop (e.g. <code>for() { ... }</code>) and conditional blocks (e.g. <code>if() { ... }</code>) — they look very similar, but they are not the same thing! Take care not to get these confused.</p> +</div> + +<div class="note"> +<p><strong>Note</strong>: The <a href="/en-US/docs/Web/JavaScript/Reference/Errors/Not_defined">ReferenceError: "x" is not defined</a> error is one of the most common you'll encounter. If you get this error and you are sure that you have defined the variable in question, check what scope it is in.</p> +</div> + +<ul> +</ul> + +<h3 id="Functions_inside_functions">Functions inside functions</h3> + +<p>Keep in mind that you can call a function from anywhere, even inside another function. This is often used as a way to keep code tidy — if you have a big complex function, it is easier to understand if you break it down into several sub-functions:</p> + +<pre class="brush: js notranslate">function myBigFunction() { + var myValue; + + subFunction1(); + subFunction2(); + subFunction3(); +} + +function subFunction1() { + console.log(myValue); +} + +function subFunction2() { + console.log(myValue); +} + +function subFunction3() { + console.log(myValue); +} +</pre> + +<p>Just make sure that the values being used inside the function are properly in scope. The example above would throw an error <code>ReferenceError: myValue is not defined</code>, because although the <code>myValue</code> variable is defined in the same scope as the function calls, it is not defined inside the function definitions — the actual code that is run when the functions are called. To make this work, you'd have to pass the value into the function as a parameter, like this:</p> + +<pre class="brush: js notranslate">function myBigFunction() { + var myValue = 1; + + subFunction1(myValue); + subFunction2(myValue); + subFunction3(myValue); +} + +function subFunction1(value) { + console.log(value); +} + +function subFunction2(value) { + console.log(value); +} + +function subFunction3(value) { + console.log(value); +}</pre> + +<h2 id="Conclusion">Conclusion</h2> + +<p>This article has explored the fundamental concepts behind functions, paving the way for the next one in which we get practical and take you through the steps to building up your own custom function.</p> + +<h2 id="See_also">See also</h2> + +<ul> + <li><a href="/en-US/docs/Web/JavaScript/Guide/Functions">Functions detailed guide</a> — covers some advanced features not included here.</li> + <li><a href="/en-US/docs/Web/JavaScript/Reference/Functions">Functions reference</a></li> + <li><a href="/en-US/docs/Web/JavaScript/Reference/Functions/Default_parameters">Default parameters</a>, <a href="/en-US/docs/Web/JavaScript/Reference/Functions/Arrow_functions">Arrow functions</a> — advanced concept references</li> +</ul> + +<ul> +</ul> + +<p>{{PreviousMenuNext("Learn/JavaScript/Building_blocks/Looping_code","Learn/JavaScript/Building_blocks/Build_your_own_function", "Learn/JavaScript/Building_blocks")}}</p> + +<h2 id="In_this_module">In this module</h2> + +<ul> + <li><a href="/en-US/docs/Learn/JavaScript/Building_blocks/conditionals">Making decisions in your code — conditionals</a></li> + <li><a href="/en-US/docs/Learn/JavaScript/Building_blocks/Looping_code">Looping code</a></li> + <li><a href="/en-US/docs/Learn/JavaScript/Building_blocks/Functions">Functions — reusable blocks of code</a></li> + <li><a href="/en-US/docs/Learn/JavaScript/Building_blocks/Build_your_own_function">Build your own function</a></li> + <li><a href="/en-US/docs/Learn/JavaScript/Building_blocks/Return_values">Function return values</a></li> + <li><a href="/en-US/docs/Learn/JavaScript/Building_blocks/Events">Introduction to events</a></li> + <li><a href="/en-US/docs/Learn/JavaScript/Building_blocks/Image_gallery">Image gallery</a></li> +</ul> +<gdiv></gdiv> diff --git a/files/es/learn/javascript/building_blocks/galeria_de_imagenes/index.html b/files/es/learn/javascript/building_blocks/galeria_de_imagenes/index.html new file mode 100644 index 0000000000..205f1a11aa --- /dev/null +++ b/files/es/learn/javascript/building_blocks/galeria_de_imagenes/index.html @@ -0,0 +1,144 @@ +--- +title: Galería de imágenes +slug: Learn/JavaScript/Building_blocks/Galeria_de_imagenes +translation_of: Learn/JavaScript/Building_blocks/Image_gallery +--- +<div>{{LearnSidebar}}</div> + +<div>{{PreviousMenu("Learn/JavaScript/Building_blocks/Events", "Learn/JavaScript/Building_blocks")}}</div> + +<p class="summary"><span class="tlid-translation translation" lang="es"><span title="">Ahora que hemos analizado los bloques de construcción fundamentales de JavaScript, pongamos a prueba tu conocimiento de bucles, funciones, condicionales y eventos, creando un elemento que comumente vemos en muchos sitios web, una </span> <span title="">Galería de imágenes "motorizada" por JavaScript .</span></span></p> + +<table class="learn-box standard-table"> + <tbody> + <tr> + <th scope="row">Prerequisitos:</th> + <td>Antes de intentar esta evaluación deberías de haber trabajado con todos los artículos en éste módulo.</td> + </tr> + <tr> + <th scope="row">Objetivo:</th> + <td>Evaluar la comprensión de los bucles, funciones, condicionales y eventos de JavaScript..</td> + </tr> + </tbody> +</table> + +<h2 id="Punto_de_partida">Punto de partida</h2> + +<p>Para realizar esta evaluación, debería descárgarse <a href="https://github.com/mdn/learning-area/blob/master/javascript/building-blocks/gallery/gallery-start.zip?raw=true">archivoZip</a> para el ejemplo, descomprímalo en algún lugar de su computadora y haga el ejercicio localmente para empezar.</p> + +<p>Opcionalmente, puedes usar un sitio como <a class="external external-icon" href="http://jsbin.com/">JSBin</a> o <a href="https://glitch.com/">Glitch</a> para realizar tu evaluación. Puede pegar el HTML, CSS y JavaScript dentro de uno de estos editores online. <span class="tlid-translation translation" lang="es"><span title="">Si el editor en línea que está utilizando no tiene paneles JavaScript / CSS separados, siéntase libre de ponerlos en línea <script> / <style> elementos dentro de la página HTML.</span></span></p> + +<div class="blockIndicator note"> +<p><strong>Nota</strong>: Si se atascascas con algo, entonces pregúntenos para ayudarlo — vea la sección de {{anch("evaluación o ayuda adicional")}} al final de esta página.</p> +</div> + +<h2 id="Resumen_del_proyecto">Resumen del proyecto</h2> + +<p>Ha sido provisto con algún contenido de HTML, CSS e imágenes, también algunas líneas de código en JavaScript; necesitas escribir las líneas de código en JavaScript necesatio para transformarse en un programa funcional. El HTML body luce así:</p> + +<pre class="brush: html"><h1>Image gallery example</h1> + +<div class="full-img"> + <img class="displayed-img" src="images/pic1.jpg"> + <div class="overlay"></div> + <button class="dark">Darken</button> +</div> + +<div class="thumb-bar"> + +</div></pre> + +<p>El ejemplo se ve así:</p> + +<p><img alt="" src="https://mdn.mozillademos.org/files/13787/gallery.png" style="display: block; margin: 0 auto;"></p> + +<ul> +</ul> + +<p>Las partes más interesantes del archivo example's CSS :</p> + +<ul> + <li>It absolutely positions the three elements inside the <code>full-img <div></code> — the <code><img></code> in which the full-sized image is displayed, an empty <code><div></code> that is sized to be the same size as the <code><img></code> and put right over the top of it (this is used to apply a darkening effect to the image via a semi-transparent background color), and a <code><button></code> that is used to control the darkening effect.</li> + <li>It sets the width of any images inside the <code>thumb-bar <div></code> (so-called "thumbnail" images) to 20%, and floats them to the left so they sit next to one another on a line.</li> +</ul> + +<p>Your JavaScript needs to:</p> + +<ul> + <li>Loop through all the images, and for each one insert an <code><img></code> element inside the <code>thumb-bar <div></code> that embeds that image in the page.</li> + <li>Attach an <code>onclick</code> handler to each <code><img></code> inside the <code>thumb-bar <div></code> so that when they are clicked, the corresponding image is displayed in the <code>displayed-img <img></code> element.</li> + <li>Attach an <code>onclick</code> handler to the <code><button></code> so that when it is clicked, a darken effect is applied to the full-size image. When it is clicked again, the darken effect is removed again.</li> +</ul> + +<p>To give you more of an idea, have a look at the <a href="http://mdn.github.io/learning-area/javascript/building-blocks/gallery/">finished example</a> (no peeking at the source code!)</p> + +<h2 id="Steps_to_complete">Steps to complete</h2> + +<p>The following sections describe what you need to do.</p> + +<h3 id="Looping_through_the_images">Looping through the images</h3> + +<p>We've already provided you with lines that store a reference to the <code>thumb-bar <div></code> inside a constant called <code>thumbBar</code>, create a new <code><img></code> element, set its <code>src</code> attribute to a placeholder value <code>xxx</code>, and append this new <code><img></code> element inside <code>thumbBar</code>.</p> + +<p>You need to:</p> + +<ol> + <li>Put the section of code below the "Looping through images" comment inside a loop that loops through all 5 images — you just need to loop through five numbers, one representing each image.</li> + <li>In each loop iteration, replace the <code>xxx</code> placeholder value with a string that will equal the path to the image in each case. We are setting the value of the <code>src</code> attribute to this value in each case. Bear in mind that in each case, the image is inside the images directory and its name is <code>pic1.jpg</code>, <code>pic2.jpg</code>, etc.</li> +</ol> + +<h3 id="Adding_an_onclick_handler_to_each_thumbnail_image">Adding an onclick handler to each thumbnail image</h3> + +<p>In each loop iteration, you need to add an <code>onclick</code> handler to the current <code>newImage</code> — this handler should find the value of the <code>src</code> attribute of the current image. Set the <code>src</code> attribute value of the <code>displayed-img <img></code> to the <code>src</code> value passed in as a parameter.</p> + +<h3 id="Writing_a_handler_that_runs_the_darkenlighten_button">Writing a handler that runs the darken/lighten button</h3> + +<p>That just leaves our darken/lighten <code><button></code> — we've already provided a line that stores a reference to the <code><button></code> in a constant called <code>btn</code>. You need to add an <code>onclick</code> handler that:</p> + +<ol> + <li>Checks the current class name set on the <code><button></code> — you can again achieve this by using <code>getAttribute()</code>.</li> + <li>If the class name is <code>"dark"</code>, changes the <code><button></code> class to <code>"light"</code> (using <code><a href="/en-US/docs/Web/API/Element/setAttribute">setAttribute()</a></code>), its text content to "Lighten", and the {{cssxref("background-color")}} of the overlay <code><div></code> to <code>"rgba(0,0,0,0.5)"</code>.</li> + <li>If the class name not <code>"dark"</code>, changes the <code><button></code> class to <code>"dark"</code>, its text content back to "Darken", and the {{cssxref("background-color")}} of the overlay <code><div></code> to <code>"rgba(0,0,0,0)"</code>.</li> +</ol> + +<p>The following lines provide a basis for achieving the changes stipulated in points 2 and 3 above.</p> + +<pre class="brush: js">btn.setAttribute('class', xxx); +btn.textContent = xxx; +overlay.style.backgroundColor = xxx;</pre> + +<h2 id="Hints_and_tips">Hints and tips</h2> + +<ul> + <li>You don't need to edit the HTML or CSS in any way.</li> +</ul> + +<h2 id="Assessment_or_further_help">Assessment or further help</h2> + +<p>If you would like your work assessed, or are stuck and want to ask for help:</p> + +<ol> + <li>Put your work into an online shareable editor such as <a href="https://codepen.io/">CodePen</a>, <a href="https://jsfiddle.net/">jsFiddle</a>, or <a href="https://glitch.com/">Glitch</a>.</li> + <li>Write a post asking for assessment and/or help at the <a href="https://discourse.mozilla.org/c/mdn/learn">MDN Discourse forum Learning category</a>. Your post should include: + <ul> + <li>A descriptive title such as "Assessment wanted for Image gallery".</li> + <li>Details of what you have already tried, and what you would like us to do, e.g. if you are stuck and need help, or want an assessment.</li> + <li>A link to the example you want assessed or need help with, in an online shareable editor (as mentioned in step 1 above). This is a good practice to get into — it's very hard to help someone with a coding problem if you can't see their code.</li> + <li>A link to the actual task or assessment page, so we can find the question you want help with.</li> + </ul> + </li> +</ol> + +<p>{{PreviousMenu("Learn/JavaScript/Building_blocks/Events", "Learn/JavaScript/Building_blocks")}}</p> + +<h2 id="In_this_module">In this module</h2> + +<ul> + <li><a href="/en-US/docs/Learn/JavaScript/Building_blocks/conditionals">Making decisions in your code — conditionals</a></li> + <li><a href="/en-US/docs/Learn/JavaScript/Building_blocks/Looping_code">Looping code</a></li> + <li><a href="/en-US/docs/Learn/JavaScript/Building_blocks/Functions">Functions — reusable blocks of code</a></li> + <li><a href="/en-US/docs/Learn/JavaScript/Building_blocks/Build_your_own_function">Build your own function</a></li> + <li><a href="/en-US/docs/Learn/JavaScript/Building_blocks/Return_values">Function return values</a></li> + <li><a href="/en-US/docs/Learn/JavaScript/Building_blocks/Events">Introduction to events</a></li> + <li><a href="/en-US/docs/Learn/JavaScript/Building_blocks/Image_gallery">Image gallery</a></li> +</ul> diff --git a/files/es/learn/javascript/building_blocks/index.html b/files/es/learn/javascript/building_blocks/index.html new file mode 100644 index 0000000000..de9e7c7c4a --- /dev/null +++ b/files/es/learn/javascript/building_blocks/index.html @@ -0,0 +1,71 @@ +--- +title: Elementos básicos de JavaScript +slug: Learn/JavaScript/Building_blocks +tags: + - CodingScripting + - Condicionales + - Evaluación + - Funciones + - Guía + - JavaScript + - Landing + - NeedsTranslation + - Principiante + - TopicStub + - bucles + - eventos + - introducción + - 'l10n:priority' + - modulo +translation_of: Learn/JavaScript/Building_blocks +--- +<div>{{LearnSidebar}}</div> + +<p class="summary">En este módulo, continuamos nuestra cobertura de todas las características clave de JavaScript, tornando nuestra atención a tipos de código comúnmente encontrados tales como enunciados condicionales, bucles (loops), funciones, y eventos. Ya has visto estas cosas en este curso, pero solo de pasada aquí lo hablaremos mas explícitamente.</p> + +<h3 id="Quieres_transformarte_en_un_desarrollador_web_front-end">Quieres transformarte en un desarrollador web front-end?</h3> + +<p>Hemos reunido un curso que incluye toda la información esencial que necesitas para trabajar hacia tu objetivo.</p> + +<p><a class="cta primary" href="https://developer.mozilla.org/docs/Learn/Front-end_web_developer">Empieza aquí</a></p> + +<h2 id="Pre-requisitos">Pre-requisitos</h2> + +<p>Antes de empezar este módulo, deberías ya tener alguna familiaridad con lo básico de <a href="/en-US/docs/Learn/HTML/Introduction_to_HTML">HTML</a> y <a href="/en-US/docs/Learn/CSS/Introduction_to_CSS">CSS</a>, y también deberías haber trabajado todos lo módulos previos, <a href="/en-US/docs/Learn/JavaScript/First_steps">JavaScript primeros pasos</a>.</p> + +<div class="note"> +<p><strong>Nota</strong>: Si estas trabajando en una computadora/tablet/otro dispositivo donde no tienes la capacidad de crear tus propios archivos, podrías practicar (la mayoría de) los ejemplos de código en un programa en linea tales como <a href="http://jsbin.com/">JSBin</a> o <a href="https://thimble.mozilla.org/">Thimble</a>.</p> +</div> + +<h2 id="Guías">Guías</h2> + +<dl> + <dt><a href="/es/docs/Learn/JavaScript/Building_blocks/conditionals"> Tomando decisiones en tu código — condicionales</a></dt> + <dd>En cualquier lenguaje de programación, el código necesita tomar decisiones y efectuar acciones consiguientemente dependiendo de las diferentes ordenes ingresadas. Por ejemplo, en un juego, si el numero de vidas del jugador es 0, entonces se termina el juego. En una aplicación del clima, si esta siendo vista por la mañana, muestra un gráfico del amanecer; muestra estrellas y una luna si es de noche. En este artículo exploraremos como los condicionales estructuran el trabajo en Javascript.</dd> + <dt><a href="/es/docs/Learn/JavaScript/Building_blocks/Bucle_codigo">Bucles de código</a></dt> + <dd>A veces necesitas que una tarea se haga más de una vez. Por ejemplo, revisar toda una lista de nombres. En programación, los bucles ('<em>loops'</em> en inglés) hacen este trabajo muy bien. Aca veremos la estructura de loops en Javascript.</dd> + <dt><a href="/es/docs/Learn/JavaScript/Building_blocks/Functions">Funciones — bloques de código reusables </a></dt> + <dd>Otro concepto fundamental en código es <strong>funciones. Funciones</strong> te permite almacenar una pieza de código que ejecuta una sola tarea dentro de un bloque definido, y después llamar ese código cuando lo necesitas usando un comando corto en lugar de tener que escribir el mismo código varias veces. En este articulo exploraremos conceptos fundamentales detrás de las funciones tales como sintaxis básica, cómo invocar y definir funciones, ámbito o alcance (scope), y parámetros.</dd> + <dt><a href="/es/docs/Learn/JavaScript/Building_blocks/Construyendo_tu_propia_funcion">Crea tu propia función </a></dt> + <dd>Con la información presentada en el artículo anterior, este artículo, pretende demostrar una parte práctica. Se podrá desarrollar una función propia, y durante el desarrollo se presentarán algunos consejos prácticos y útiles para trabajar con funciones.</dd> + <dt><a href="/es/docs/Learn/JavaScript/Building_blocks/Return_values"> Una función devuelve valores</a></dt> + <dd>Un concepto fundamental que ha de tenerse en cuenta, es que las funciones pueden devolver valores al finalizar su ejecución, aunque algunas funciones también pueden no devolver ningún valor. Es importante entender como son esos valores, qué tipos pueden tener y cómo aprovechar el valor devuelto por la función en el programa.</dd> + <dt><a href="/es/docs/Learn/JavaScript/Building_blocks/Eventos">Introducción a eventos</a></dt> + <dd>Los eventos son acciones u ocurrencias que aparecen durante la ejecución del programa, y que son reportadas por el sistema, de forma que se pueda responder a los eventos de la forma deseada. Por ejemplo, si un usuario hace un click en un botón de una página web, puede que se quiera que ese evento inicie una acción en el que se muestre cierta información en un cuadro de información. En este último artículo se presentarán y describirán los conceptos necesarios con respecto a los eventos, y como funcionan en un navegador.</dd> +</dl> + +<h2 id="Evaluaciones">Evaluaciones</h2> + +<p>La siguiente evaluación probara tu entendimiento de lo básico de Javascript cubierto en las guias anteriores.</p> + +<dl> + <dt><a href="/en-US/docs/Learn/JavaScript/Building_blocks/Image_gallery">Galeria de imagen</a></dt> + <dd>Ahora que hemos visto los bloques constructores fundamentales de JavaScript, probaremos tus conocimientos en bucles, funciones, condicionales y eventos construyendo un item bastante común en muchos sitios web — una galería de imágenes creada con JavaScript. </dd> +</dl> + +<h2 id="Ver_también">Ver también</h2> + +<dl> + <dt><a href="https://learnjavascript.online/">Aprender JavaScript</a></dt> + <dd>Un excelente recurso para aspirantes a desarrolladores web — Aprenda JavaScript en un entorno interactivo, con lecciones cortas y pruebas interactivas, guiadas por una evaluación automatizada. Las primeras 40 lecciones son gratuitas, y el curso completo está disponible por un pequeño pago único.</dd> +</dl> diff --git a/files/es/learn/javascript/building_blocks/return_values/index.html b/files/es/learn/javascript/building_blocks/return_values/index.html new file mode 100644 index 0000000000..2602a7217f --- /dev/null +++ b/files/es/learn/javascript/building_blocks/return_values/index.html @@ -0,0 +1,168 @@ +--- +title: Una función retorna valores +slug: Learn/JavaScript/Building_blocks/Return_values +translation_of: Learn/JavaScript/Building_blocks/Return_values +--- +<div>{{LearnSidebar}}</div> + +<div>{{PreviousMenuNext("Learn/JavaScript/Building_blocks/Build_your_own_function","Learn/JavaScript/Building_blocks/Events", "Learn/JavaScript/Building_blocks")}}</div> + +<p class="summary">Hay un último concepto esencial para que discutamos en este curso, para cerrar nuestra visión de las funciones: — lo valores que se devuelven. Algunas funciones no devuelven un valor significativo después de su finalización, pero otras sí, y es importante comprender cuáles son sus valores, cómo utilizarlos en su código y cómo hacer que sus propias funciones personalizadas devuelvan valores útiles. Cubriremos todos estos a continuación.</p> + +<table class="learn-box standard-table"> + <tbody> + <tr> + <th scope="row">Prerequisites:</th> + <td> + <p>Basic computer literacy, a basic understanding of HTML and CSS, <a href="/en-US/docs/Learn/JavaScript/First_steps">JavaScript first steps</a>, <a href="/en-US/docs/Learn/JavaScript/Building_blocks/Functions">Functions — reusable blocks of code</a>.</p> + </td> + </tr> + <tr> + <th scope="row">Objective:</th> + <td>To understand function return values, and how to make use of them.</td> + </tr> + </tbody> +</table> + +<h2 id="¿Qué_son_los_valores_de_retorno">¿Qué son los valores de retorno?</h2> + +<p><strong>Los valores de retorno </strong>son exactamente como suenan: los valores devueltos por la función cuando se completa. Ya has alcanzado los valores de retorno varias veces, aunque es posible que no hayas pensado en ellos explícitamente. Volvamos a un código familiar:</p> + +<pre class="brush: js notranslate">var myText = 'I am a string'; +var newString = myText.replace('string', 'sausage'); +console.log(newString); +// la función de cadena replace () toma una cadena, +// sustituyendo una subcadena con otra y devoviendo +// una cadena nueva con la sustitución realizada</pre> + +<p>Vimos exactamente este bloque de código en nuestro primer artículo de función. Estamos invocando la función <a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String/replace">replace ()</a> en la cadena <code>myText</code>, y le pasamos dos parámetros: la subcadena a encontrar y la subcadena con la que reemplazarla. Cuando esta función se completa (termina de ejecutarse), devuelve un valor, que es una nueva cadena con el reemplazo realizado. En el código anterior, estamos guardando este valor de retorno como el valor de la variable <code>newString</code>.</p> + +<p>Si observa la página de referencia MDN de la función de reemplazo, verá una sección llamada <a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String/replace#Return_value">Valor de retorno.</a> Es muy útil conocer y comprender qué valores devuelven las funciones, por lo que tratamos de incluir esta información siempre que sea posible.</p> + +<p>Algunas funciones no devuelven un valor de retorno como tal (en nuestras páginas de referencia, el valor de retorno aparece como <code>void</code> o <code>undefined</code> en tales casos). Por ejemplo, en la función <a href="https://github.com/mdn/learning-area/blob/master/javascript/building-blocks/functions/function-stage-4.html#L50">displayMessage ()</a> que creamos en el artículo anterior, no se devuelve ningún valor específico como resultado de la función que se invoca. Simplemente hace que aparezca un cuadro en algún lugar de la pantalla, ¡eso es todo!</p> + +<p>Generalmente, se usa un valor de retorno donde la función es un paso intermedio en un cálculo de algún tipo. Quieres llegar a un resultado final, que involucra algunos valores. Esos valores deben ser calculados por una función, que luego devuelve los resultados para que puedan usarse en la siguiente etapa del cálculo.</p> + +<h3 id="Using_return_values_in_your_own_functions">Using return values in your own functions</h3> + +<p>To return a value from a custom function, you need to use ... wait for it ... the <a href="/en-US/docs/Web/JavaScript/Reference/Statements/return">return</a> keyword. We saw this in action recently in our <a href="https://github.com/mdn/learning-area/blob/master/javascript/building-blocks/loops/random-canvas-circles.html">random-canvas-circles.html</a> example. Our <code>draw()</code> function draws 100 random circles somewhere on an HTML {{htmlelement("canvas")}}:</p> + +<pre class="brush: js notranslate">function draw() { + ctx.clearRect(0,0,WIDTH,HEIGHT); + for (var i = 0; i < 100; i++) { + ctx.beginPath(); + ctx.fillStyle = 'rgba(255,0,0,0.5)'; + ctx.arc(random(WIDTH), random(HEIGHT), random(50), 0, 2 * Math.PI); + ctx.fill(); + } +}</pre> + +<p>Inside each loop iteration, three calls are made to the <code>random()</code> function, to generate a random value for the current circle's x coordinate, y coordinate, and radius, respectively. The <code>random()</code> function takes one parameter — a whole number — and it returns a whole random number between 0 and that number. It looks like this:</p> + +<pre class="brush: js notranslate">function randomNumber(number) { + return Math.floor(Math.random()*number); +}</pre> + +<p>This could be written as follows:</p> + +<pre class="brush: js notranslate">function randomNumber(number) { + var result = Math.floor(Math.random()*number); + return result; +}</pre> + +<p>But the first version is quicker to write, and more compact.</p> + +<p>We are returning the result of the calculation <code>Math.floor(Math.random()*number)</code> each time the function is called. This return value appears at the point the function was called, and the code continues. So for example, if we ran the following line:</p> + +<pre class="brush: js notranslate">ctx.arc(random(WIDTH), random(HEIGHT), random(50), 0, 2 * Math.PI);</pre> + +<p>and the three <code>random()</code> calls returned the values 500, 200, and 35, respectively, the line would actually be run as if it were this:</p> + +<pre class="brush: js notranslate">ctx.arc(500, 200, 35, 0, 2 * Math.PI);</pre> + +<p>The function calls on the line are run first and their return values substituted for the function calls, before the line itself is then executed.</p> + +<h2 id="Active_learning_our_own_return_value_function">Active learning: our own return value function</h2> + +<p>Let's have a go at writing our own functions featuring return values.</p> + +<ol> + <li>First of all, make a local copy of the <a href="https://github.com/mdn/learning-area/blob/master/javascript/building-blocks/functions/function-library.html">function-library.html</a> file from GitHub. This is a simple HTML page containing a text {{htmlelement("input")}} field and a paragraph. There's also a {{htmlelement("script")}} element in which we have stored a reference to both HTML elements in two variables. This little page will allow you to enter a number into the text box, and display different numbers related to it in the paragraph below.</li> + <li>Let's add some useful functions to this <code><script></code> element. Below the existing two lines of JavaScript, add the following function definitions: + <pre class="brush: js notranslate">function squared(num) { + return num * num; +} + +function cubed(num) { + return num * num * num; +} + +function factorial(num) { + var x = num; + while (x > 1) { + num *= x-1; + x--; + } + return num; +}</pre> + The <code>squared()</code> and <code>cubed()</code> functions are fairly obvious — they return the square or cube of the number given as a parameter. The <code>factorial()</code> function returns the <a href="https://en.wikipedia.org/wiki/Factorial">factorial</a> of the given number.</li> + <li>Next, we're going to include a way to print out information about the number entered into the text input. Enter the following event handler below the existing functions: + <pre class="brush: js notranslate">input.onchange = function() { + var num = input.value; + if (isNaN(num)) { + para.textContent = 'You need to enter a number!'; + } else { + para.textContent = num + ' squared is ' + squared(num) + '. ' + + num + ' cubed is ' + cubed(num) + '. ' + + num + ' factorial is ' + factorial(num) + '.'; + } +}</pre> + + <p>Here we are creating an <code>onchange</code> event handler that runs whenever the change event fires on the text input — that is, when a new value is entered into the text input, and submitted (enter a value then press tab for example). When this anonymous function runs, the existing value entered into the input is stored in the <code>num</code> variable.</p> + + <p>Next, we do a conditional test — if the entered value is not a number, we print an error message into the paragraph. The test looks at whether the expression <code>isNaN(num)</code> returns true. We use the <a href="/en-US/docs/Web/JavaScript/Reference/Global_Objects/isNaN">isNaN()</a> function to test whether the num value is not a number — if so, it returns <code>true</code>, and if not, <code>false</code>.</p> + + <p>If the test returns <code>false</code>, the <code>num</code> value is a number, so we print out a sentence inside the paragraph element stating what the square, cube, and factorial of the number are. The sentence calls the <code>squared()</code>, <code>cubed()</code>, and <code>factorial()</code> functions to get the required values.</p> + </li> + <li>Save your code, load it in a browser, and try it out.</li> +</ol> + +<div class="note"> +<p><strong>Note</strong>: If you have trouble getting the example to work, feel free to check your code against the <a href="https://github.com/mdn/learning-area/blob/master/javascript/building-blocks/functions/function-library-finished.html">finished version on GitHub</a> (<a href="http://mdn.github.io/learning-area/javascript/building-blocks/functions/function-library-finished.html">see it running live</a> also), or ask us for help.</p> +</div> + +<p>At this point, we'd like you to have a go at writing out a couple of functions of your own and adding them to the library. How about the square or cube root of the number, or the circumference of a circle with a radius of length <code>num</code>?</p> + +<p>This exercise has brought up a couple of important points besides being a study on how to use the <code>return</code> statement. In addition, we have:</p> + +<ul> + <li>Looked at another example of writing error handling into our functions. It is generally a good idea to check that any necessary parameters have been provided, and in the right datatype, and if they are optional, that some kind of default value is provided to allow for that. This way, your program will be less likely to throw errors.</li> + <li>Thought about the idea of creating a function library. As you go further into your programming career, you'll start to do the same kinds of things over and over again. It is a good idea to start keeping your own library of utility functions that you use very often — you can then copy them over to your new code, or even just apply it to any HTML pages where you need it.</li> +</ul> + +<h2 id="Conclusion">Conclusion</h2> + +<p>So there we have it — functions are fun, very useful and, although there's a lot to talk about in regards to their syntax and functionality, fairly understandable given the right articles to study.</p> + +<p>If there is anything you didn't understand, feel free to read through the article again, or <a href="/en-US/Learn#Contact_us">contact us</a> to ask for help.</p> + +<h2 id="See_also">See also</h2> + +<ul> + <li><a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Functions">Functions in-depth</a> — a detailed guide covering more advanced functions-related information.</li> + <li><a href="https://www.impressivewebs.com/callback-functions-javascript/">Callback functions in JavaScript</a> — a common JavaScript pattern is to pass a function into another function as an argument, which is then called inside the first function. This is a little beyond the scope of this course, but worth studying before too long.</li> +</ul> + +<p>{{PreviousMenuNext("Learn/JavaScript/Building_blocks/Build_your_own_function","Learn/JavaScript/Building_blocks/Events", "Learn/JavaScript/Building_blocks")}}</p> + +<h2 id="In_this_module">In this module</h2> + +<ul> + <li><a href="/en-US/docs/Learn/JavaScript/Building_blocks/conditionals">Making decisions in your code — conditionals</a></li> + <li><a href="/en-US/docs/Learn/JavaScript/Building_blocks/Looping_code">Looping code</a></li> + <li><a href="/en-US/docs/Learn/JavaScript/Building_blocks/Functions">Functions — reusable blocks of code</a></li> + <li><a href="/en-US/docs/Learn/JavaScript/Building_blocks/Build_your_own_function">Build your own function</a></li> + <li><a href="/en-US/docs/Learn/JavaScript/Building_blocks/Return_values">Function return values</a></li> + <li><a href="/en-US/docs/Learn/JavaScript/Building_blocks/Events">Introduction to events</a></li> + <li><a href="/en-US/docs/Learn/JavaScript/Building_blocks/Image_gallery">Image gallery</a></li> +</ul> |