Foros aprenderaprogramar.com

Aprender a programar => C, C++, C#, Java, Visual Basic, HTML, PHP, CSS, Javascript, Ajax, Joomla, MySql y más => Mensaje iniciado por: bermartinv en 02 de Febrero 2016, 13:27

Título: JavaScript HTMLCollection vs NodeList querySelectorAll no funciona? CU01138E#
Publicado por: bermartinv en 02 de Febrero 2016, 13:27
Hola chicos, adjunto codigo que veo más cómodo que el que hace un tiempo adjuntaron nuestros compañeros.

Código: [Seleccionar]
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Document</title>
<style>
#cuadrado{
    position:absolute;
    width:204px;
    height:204px;
    border:solid thin red;
    top:30%;
    left:30%;
    }
div.cuadrante{
    border:solid thin red;
    text-align: center;
    width:100px;
    height:100px;
    float:left;
    line-height: 100px;
   
}
input{
    float:right;
    margin-top:2em;
}

</style>
</head>
<body>
    <div id="cuadrado">
        <div class="cuadrante">
            <span>?</span>                                                                                     
        </div>
        <div class="cuadrante">
            <span>?</span>
        </div>
        <div class="cuadrante">
            <span>?</span>
        </div>       
        <div class="cuadrante">
            <span>?</span>
        </div>
        <input type="button" onclick="avanzar()" value="Avanzar">
    </div>
</body>
<script>
var contador=0;
var cuadrante=document.querySelectorAll(".cuadrante");
function avanzar(){
 
   
    switch (contador){
        case 0: cuadrante[contador].style.backgroundColor="black";
                cuadrante[contador].style.color="white";
                cuadrante[contador].innerHTML="El";
            break;
        case 1:
                cuadrante[contador].innerHTML="poder ";
            break;
        case 2:
                cuadrante[contador].innerHTML="de";
            break;
        case 3: cuadrante[contador].style.backgroundColor="yellow";
                cuadrante[contador].innerHTML="JavaScript";
            break;
        default: alert ("No es posible hacer mas ");
    }
    contador++;
   
}
</script>
</html>
Título: Re:JavaScript innerHTML efecto cuadrado cambia color al pulsar botón load CU01138E
Publicado por: Ogramar en 04 de Febrero 2016, 09:38
Buenas bermartinv el código está bien planteado y resuelve lo que pedía el ejercicio a la perfección.

Recomendarte que los scripts con las funciones los incluyas dentro de las etiquetas <head> ... </head> y no en otros lugares para tener mejor organizado el código.

En el código que has propuesto si trasladamos el código de lugar no funciona ¿Por qué? Porque si declaramos var cuadrante=document.querySelectorAll(".cuadrante"); antes de que se haya cargado la página, al hacer la selección no obtenemos nada (ya que no hay nada porque todavía no ha cargado la página). Esto se puede resolver de varias maneras, una de ellas sería utilizar el evento onload y obtener cuadrante después del evento onload, una vez ya existan los elementos con class cuadrante.

Otra opción es meter la creación de cuadrante dentro de la función, como esta función es respuesta a un botón, cuando el usuario pulse el botón ya se habrá cargado la página. Aquí tenemos la pequeña ineficiencia de estar haciendo la selección cada vez que se pulse el botón pero en este ejercicio esto no tiene demasiada importancia. El código sería:

Código: [Seleccionar]
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Ejercicios aprenderaprogramar.com</title>
<style>
#cuadrado{
    position:absolute;
    width:204px;
    height:204px;
    border:solid thin red;
    top:30%;
    left:30%;
    }
div.cuadrante{
    border:solid thin red;
    text-align: center;
    width:100px;
    height:100px;
    float:left;
    line-height: 100px;
   
}
input{
    float:right;
    margin-top:2em;
}

</style>
<script>
var contador=0;

function avanzar(){
var cuadrante=document.querySelectorAll(".cuadrante");
    switch (contador){
        case 0: cuadrante[contador].style.backgroundColor="black";
                cuadrante[contador].style.color="white";
                cuadrante[contador].innerHTML="El";
            break;
        case 1:
                cuadrante[contador].innerHTML="poder ";
            break;
        case 2:
                cuadrante[contador].innerHTML="de";
            break;
        case 3: cuadrante[contador].style.backgroundColor="yellow";
                cuadrante[contador].innerHTML="JavaScript";
            break;
        default: alert ("No es posible hacer mas ");
    }
    contador++;
   
}
</script>
</head>
<body>
    <div id="cuadrado">
        <div class="cuadrante">
            <span>?</span>                                                                                     
        </div>
        <div class="cuadrante">
            <span>?</span>
        </div>
        <div class="cuadrante">
            <span>?</span>
        </div>       
        <div class="cuadrante">
            <span>?</span>
        </div>
        <input type="button" onclick="avanzar()" value="Avanzar">
    </div>
</body>
</html>

Si lo resuelves con onload te quedará mejor porque solo tendrás que cargar cuadrante una vez.

Salu2
Título: Re:JavaScript innerHTML efecto cuadrado cambia color al pulsar botón load CU01138E
Publicado por: bermartinv en 04 de Febrero 2016, 11:01
Gracias Ogramar, por tu respuesta.

He intentado hacer lo de onload pero no me ha convencido, porque tal como está el código al hacer <body onload="nombre de la funcion">  ya se inicializa la función.

Entonces he decidido cambiar querySelectorAll(".cuadrante") por un getElementsByClass("cuadrante") y cambiar el script dentro de head.

Código: [Seleccionar]
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Document</title>
<style>
#cuadrado{
    position:absolute;
    width:204px;
    height:204px;
    border:solid thin red;
    top:30%;
    left:30%;
    }
div.cuadrante{
    border:solid thin red;
    text-align: center;
    width:100px;
    height:100px;
    float:left;
    line-height: 100px;
   
}
input{
    float:right;
    margin-top:2em;
}

</style>
<script>
var contador=0;
var cuadrante=document.getElementsByClassName("cuadrante");
function avanzar(){
 
   
    switch (contador){
        case 0: cuadrante[contador].style.backgroundColor="black";
                cuadrante[contador].style.color="white";
                cuadrante[contador].innerHTML="El";
            break;
        case 1:
                cuadrante[contador].innerHTML="poder ";
            break;
        case 2:
                cuadrante[contador].innerHTML="de";
            break;
        case 3: cuadrante[contador].style.backgroundColor="yellow";
                cuadrante[contador].innerHTML="JavaScript";
            break;
        default: alert ("No es posible hacer mas ");
    }
    contador++;
   
}
</script>
</head>
<body>
    <div id="cuadrado">
        <div class="cuadrante">
            <span>?</span>                                                                                     
        </div>
        <div class="cuadrante">
            <span>?</span>
        </div>
        <div class="cuadrante">
            <span>?</span>
        </div>       
        <div class="cuadrante">
            <span>?</span>
        </div>
        <input type="button" onclick="avanzar()" value="Avanzar">
    </div>

</body>

</html>
Gracias por tus sugerencias
Título: Re:JavaScript HTMLCollection vs NodeList querySelectorAll no funciona? CU01138E
Publicado por: Alex Rodríguez en 04 de Febrero 2016, 13:00
Hola hay algo interesante en el código que se está estudiando y por qué en unos casos funciona y en otros no ¿Por qué querySelectorAll no funciona? Esto está relacionado con la diferencia entre HTMLCollection y NodeList

document.querySelectorAll(".cuadrante") devuelve un object HTMLCollection, esto significa que este método devuelve una lista estática donde los cambios que tengan lugar a posteriori de su inicialización no se reflejan. En este caso en el momento de la inicialización no había nodos, de ahí que la lista estática esté vacía y el método no funcione.

document.getElementsByClassName("cuadrante") devuelve un object NodeList vivo, esto es, una lista dinámica de nodos donde se referencia a los elementos incluyendo los cambios que puedan existir en ellos durante la ejecución. En este caso en el momento de la inicialización no había nodos, pero luego son creados y la referencia dinámica permite acceder a estos elementos cuando se invoca la función.

Aclaración terminológica: a veces se habla de NodeList vivos o dinámicos frente a NodeList no-vivos o estáticos. En ocasiones hay métodos que devuelven NodeList no-vivos (estáticos), por ejemplo document.querySelectorAll se diría que devuelve un NodeList no-vivo o estático. Es un tanto confuso y depende de la referencia que miremos, la cuestión es tener clara la diferencia entre dinámico y estático.

Saludos
Título: Re:JavaScript HTMLCollection vs NodeList querySelectorAll no funciona? CU01138E
Publicado por: bermartinv en 04 de Febrero 2016, 13:24
Con eso último que has explicado se entiende mucho mejor.
Muchas gracias