entre Desarrolladores

Recibe ayuda de expertos

Registrate y pregunta

Es gratis y fácil

Recibe respuestas

Respuestas, votos y comentarios

Vota y selecciona respuestas

Recibe puntos, vota y da la solución

Pregunta

2votos

Cambiar background por "sesiones"

Buenas, el caso es que estoy haciendo una interfaz "metro" en html y css (cosas que se me dan muy bien). El js y php los controlo para cosas muy específicas y no sé como hacer un script que por cada consulta a la web los div se cambien de color, pero no aleatoriamente con números hexa. Quiero que sea aleatorio pero entre unos 8 colores que tengo preparados.

Muchas gracias de antemano y saludos!

0voto

carlossevi comentado

Diferenciación importante: ¿que se cambie "por sesiones" o "aleatoriamente" en cada petición al servidor? Nombras las dos cosas y no queda totalmente claro.

Es decir, ¿quieres que a una visita se le asigne un color durante toda la sesión o que cada vez que se recarga la página lo haga con un color diferente entre tu colección de posibilidades?

0voto

SynSor comentado

Me refiero a que por cada visita se le asigne un color durante toda la sesión de la colección de colores que poseo.

Perdón por la confusión y gracias por responder.

Un saludo!

1 Respuesta

4votos

carlossevi Puntos63580

Te hago un ejemplo de cómo quedaría un código PHP simplificado al máximo.

  • Utiliza un array con la lista de posibles colores y selecciona uno aleatoriamente
  • Utiliza funciones de sesión propias de PHP

Se me han ocurrido varias opciones:

  1. Que el script PHP genere la hoja CSS personalizada para la sesión, pero no me gusta porque el CSS entonces se vuelve más complejo de mantener..
  2. Que el script PHP genere el HTML escribiendo directamente el color en el HTML, pero no me parece limpio porque no separa la capa de presentación de los datos.
  3. Que el script PHP genere una función Javascript que cambia el color de la página al mostrarse. He elegido esta opción.

También he puesto un pequeño contador a la sesión para hacer pruebas.

<?php 
// Iniciar SESSION
session_start();
if (!isset($_SESSION['color'])) {
    // Si la variable de sesión no existe, se fija el color e 
    // inicia el contador de cargas:
    $colores = array("red","orange","yellow");           
    $_SESSION['color'] = $colores[array_rand($colores,1)];
    $_SESSION['cont'] = 1;
} else {
    // Si ya existía, solo se incrementa el contador:
    $_SESSION['cont']++;
}
?>
<html>
    <script>
    function changeBackground() {
       document.body.style.background = '<?php print($_SESSION['color']);?>';
    }
    </script>
    <body onload="changeBackground();">
        Se ha mostrado el color <?php print($_SESSION['cont']);?> veces.
    </body>
</html>

Para destruir la sesión y hacer pruebas puedes ejecutar:

<?php
session_start();
var_dump($_SESSION);
session_destroy();
?>

0voto

SynSor comentado

Guau! voy a probarlo, de verdad que muchas gracias.

0voto

SynSor comentado

He usado el código tal cual, solo que en vez de aplicar en el "body" lo he aplicado directamente a los div's vía ID que conformarán la interfaz metro.
Pero ocurre que ésto no funciona bien, alguna solución?

<?php 
// Iniciar SESSION
session_start();
if (!isset($_SESSION['color'])) {
    // Si la variable de sesión no existe, se fija el color e 
    // inicia el contador de cargas:
    $colores = array("#2ecc71","#e67e22","#3498db","#9b59b6","#f1c40f","#1abc9c","#008299","#e74c3c");           
    $_SESSION['color'] = $colores[array_rand($colores,1)];
    $_SESSION['cont'] = 1;
} else {
    // Si ya existía, solo se incrementa el contador:
    $_SESSION['cont']++;
}
?>
    <!DOCTYPE html>
    <html lang="en">
    <script>
        function changeBackground() {
            document.getElementById("globo").style.backgroundColor = '<?php print($_SESSION['color ']);?>';
        }
    </script>

    <head>
        <?php header('Content-Type: text/html; charset=UTF-8'); ?>
            <meta charset="utf-8">
            <meta name="viewport" content="user-scalable=no, width=device-width, initial-scale=1">
            <title>Integral | MOBI</title>
            <link rel="stylesheet" href="css/integral.css" type="text/css">
            <link rel="stylesheet" href="css/animate.css" type="text/css">
    </head>

    <body>
        <div class="container">
            <div class="row">
                <div id="barra"></div>
                <div id="globo"></div>
                <div id="globo"></div>
                <div id="globo"></div>
                <div id="globo"></div>
                <div id="globo"></div>
                <div id="globo"></div>
                <div id="barra"></div>
                <div id="globo"></div>
                <div id="globo"></div>
                <div id="globo"></div>
                <div id="globo"></div>
                <div id="globo"></div>
                <div id="globo"></div>
                <div id="barra"></div>
            </div>
        </div>
    </body>

Y eso, gracias por la ayuda.

Saludos!

0voto

carlossevi comentado

Hay unos cuantos errores en tu código:

  1. La función changeBackground() de Javascript no se está ejecutando nunca. En mi ejemplo añadí la función al evento onload de body, que puedes ponerlo a nivel de HTML o a nivel de Javascript.
    Ejemplo JS:
    <script type="text/javascript">
    function changeBackground() {
        // ... 
    }
    window.onload = changeBackground;
    </script>

    o ejemplo HTML:

    <body onload="changeBackground();">
  2. La función JS que estás generando no fija ningún color, genera una línea tal que:

    document.getElementById("globo").style.backgroundColor = '';

    Y eso es porque pusiste $_SESSION['color '] en lugar de $_SESSION['color'] (ojo al espacio) en el print().

  3. Has repetido el mismo id en varios div, por lo que solo se cambiará el color al primero de ellos. Si quieres que afecte a varios div deberías utilizar clases y desde JS modificar la clase.

  4. Aunque todo lo anterior estuviera correcto seguirías sin ver nada porque tal y como está tu código los divs no ocupan espacio en la pantalla. Tendrás que ponerles tamaños vía CSS o rellenarlos con algo de texto para poder verlos.

0voto

SynSor comentado

Ya he logrado hacer que funcione, pero efectivamente, solo funciona para el primer div, podría ilustrarme como usar las clases para hacer un conjunto?

Un saludo, y gracias nuevamente.
PD:

<?php 
// Iniciar SESSION
session_start();
if (!isset($_SESSION['color'])) {
    // Si la variable de sesión no existe, se fija el color e 
    // inicia el contador de cargas:
    $colores = array("#2ecc71","#e67e22","#3498db","#9b59b6","#f1c40f","#1abc9c","#008299","#e74c3c");           
    $_SESSION['color'] = $colores[array_rand($colores,1)];
    $_SESSION['cont'] = 1;
} else {
    // Si ya existía, solo se incrementa el contador:
    $_SESSION['cont']++;
}
?>
    <!DOCTYPE html>
    <html lang="en">
    <script>
        function changeBackground() {
            document.getElementById("prueba").style.backgroundColor = '<?php print($_SESSION['color']);?>';
        }
        window.onload = changeBackground;
    </script>

<head>
    <?php header('Content-Type: text/html; charset=UTF-8'); ?>
        <meta charset="utf-8">
        <meta name="viewport" content="user-scalable=no, width=device-width, initial-scale=1">
        <title>Integral | MOBI</title>
        <link rel="stylesheet" href="css/integral.css" type="text/css">
        <link rel="stylesheet" href="css/animate.css" type="text/css">
</head>

<body>

  <div class="container">
      <div id="prueba"></div>
  </div>

</body>

</html>

0voto

carlossevi comentado

Puedes hacer que en lugar de cambiar el color desde Javascript, se añada dinámicamente una clase preestablecida en tu CSS.

Supongamos que tienes todas las clases creadas para los colores, por ejemplo:

div .rojo{
    background-color: red;
}
div .azul{
    background-color: blue;
}

Desde el JS sólo tendrías que asignar esa clase. ¿Utilizas algún plugin de Javascript?

Cómo sería el JS puro:

var myElements = document.querySelectorAll(".prueba");
for (var i = 0; i < myElements.length; i++) {
    myElements[i].classList.add("rojo");
}

Cómo sería el JS con jQuery:

$(".prueba").addClass('rojo');

Lógicamente en ese escenario desde PHP no tendrías que "sortear" el color sino el nombre de la clase a asignar.

0voto

SynSor comentado

Lo he hecho tal cual me has dicho. Y parece que no funciona. Algo habré hecho mal, te lo dejo para que le eches un ojos. Gracias de verdad.

<?php 

class colorines{
}
session_start();
if (!isset($_SESSION['color'])) {
    $colores = array("color1","color2","color3","color4","color5","#color6","color7","color8");
    //$colores = array("#2ecc71","#e67e22","#3498db","#9b59b6","#f1c40f","#1abc9c","#008299","#e74c3c");           
    $_SESSION['color'] = $colores[array_rand($colores,1)];
    $_SESSION['cont'] = 1;
} else {
    $_SESSION['cont']++;
}
?>
    <!DOCTYPE html>
    <html lang="en">
    <script>
        var myElements = document.querySelectorAll("#prueba");
        for (var i = 0; i < myElements.length; i++) {
            myElements[i].classList.add("<?php print($_SESSION['color']);?>");
        }
        /** function changeBackground() {
             document.getElementById("prueba").style.backgroundColor = '<?php //print($_SESSION['color']);?>';
         }
         window.onload = changeBackground; **/
    </script>

    <head>
        <?php header('Content-Type: text/html; charset=UTF-8'); ?>
            <meta charset="utf-8">
            <meta name="viewport" content="user-scalable=no, width=device-width, initial-scale=1">
            <title>Integral | MOBI</title>
            <link rel="stylesheet" href="css/integral.css" type="text/css">
            <link rel="stylesheet" href="css/animate.css" type="text/css">
            <script src="js/jquery-1.11.3.min.js" type="application/javascript"></script>
    </head>

    <body>

        <div class="container">
            <div id="prueba"></div>
            <div id="prueba"></div>
            <div id="prueba"></div>
            <div id="prueba"></div>
            <div id="prueba"></div>
            <div id="prueba"></div>
            <div id="prueba"></div>
            <div id="prueba"></div>
            <div id="prueba"></div>
            <div id="prueba"></div>
        </div>

    </body>

    </html>

Style:

<style>
#prueba {
    margin: 5px;
    padding: 5px;
    width: 300px;
    height: 300px;
    float: left;
    border-radius: 2px;
}

.color1{background: #2ecc71;}
.color2{background: #e67e22;}
.color3{background: #3498db;}
.color4{background: #9b59b6;}
.color5{background: #f1c40f;}
.color6{background: #1abc9c;}
.color7{background: #008299;}
.color8{background: #e74c3c;}
</style>

0voto

Peter comentado

@SynSor muevo tus respuestas a comentarios. Recuerda que las respuestas son únicamente para la pregunta inicial y no para otras respuestas, eso son comentarios.

Saludos.

1voto

carlossevi comentado

Si publicas tus comentarios como nuevas respuestas no me llegan las notificaciones, menos mal que Peter está al quite ;)

¿Dónde referencias el <style>...</style> que pones abajo? ¿Está todo en el mismo archivo o en varios?

0voto

SynSor comentado

El style, simplemente lo cité para que lo puedas ver y contemplar si existen fallos. Realmente está en un archivo a parte y perfectamente indexado en el archivo html/php.

Un saludo.

PD: Disculpas por lo de las respuestas en vez de comentar!!

0voto

carlossevi comentado

Sigues teniendos los errores 1 y 3 de la lista original: El código JS no se ejecuta (comentaste la llamada al window.onload) y has puesto a todos los div el mismo ID en lugar de utilizar clases. Has hecho cambios a medias, me da la impresión que sin entender lo que estás cambiando.

0voto

SynSor comentado

Comenté el "onload sin querer" -.-' Lo que no te acabo de entender es el tema de usar clases en los div ¿Te refieres a usar "class" y no "id"?¿o como va la cosa?. Un saludo y gracias de antemano

0voto

carlossevi comentado

En HTML el valor del atributo id debe ser único en todo el documento, algo que no estás cumpliendo y por lo que no se aplican bien las reglas de CSS o los selectores de JS. Fuente W3C.

Si quieres identificar varios elementos de una misma forma para poder aplicarles un estilo o que se comporten de la misma manera, el atributo a utilizar es la clase.

0voto

SynSor comentado

Entiendo pero, pongamos que quiero que éste proceso haga efecto a todos los div con el mismo "class", pero viendo el código, opino que será así, pero tendrán todos el mismo color. Cuando me intereza que cada div tenga un color diferente.

Agregué las respectivas clases, he hice los cambio que yo creí oportuno y sigo sin llevarlo a camino. Te lo dejo ver:

<?php 

class colorines{
}
session_start();
if (!isset($_SESSION['color'])) {
    $colores = array("#color1","#color2","#color3","#color4","#color5","#color6","#color7","#color8");
    //$colores = array("#2ecc71","#e67e22","#3498db","#9b59b6","#f1c40f","#1abc9c","#008299","#e74c3c");           
    $_SESSION['color'] = $colores[array_rand($colores,1)];
    $_SESSION['cont'] = 1;
} else {
    $_SESSION['cont']++;
}
?>
    <!DOCTYPE html>
    <html lang="en">
    <script>
        function changeBackground() {
        var myElements = document.querySelectorAll("#prueba");
        for (var i = 0; i < myElements.length; i++) {
            myElements[i].classList.add("<?php print($_SESSION['color']);?>");
        }
        }
        /** function changeBackground() {
             document.getElementById("prueba").style.backgroundColor = '<?php //print($_SESSION['color']);?>';
         } **/
         window.onload = changeBackground; 
    </script>

    <head>
        <?php header('Content-Type: text/html; charset=UTF-8'); ?>
            <meta charset="utf-8">
            <meta name="viewport" content="user-scalable=no, width=device-width, initial-scale=1">
            <title>Integral | MOBI</title>
            <link rel="stylesheet" href="css/integral.css" type="text/css">
            <link rel="stylesheet" href="css/animate.css" type="text/css">
            <script src="js/jquery-1.11.3.min.js" type="application/javascript"></script>
    </head>

    <body>

        <div class="container">
            <div class="prueba"></div>
            <div class="prueba"></div>
            <div class="prueba"></div>
            <div class="prueba"></div>
            <div class="prueba"></div>
            <div class="prueba"></div>
            <div class="prueba"></div>
            <div class="prueba"></div>
            <div class="prueba"></div>
            <div class="prueba"></div>
        </div>
</html>

0voto

carlossevi comentado

Tienes un error en el selector, dentro de la función changeBackground() en JS:

// Esta línea:
var myElements = document.querySelectorAll("#prueba");
// Debería ser:
var myElements = document.querySelectorAll(".prueba");

Más información Guía de Referencia Rápida CSS de W3C.

0voto

SynSor comentado

A mi entender para id es ".ejemplo" y para class "#ejemplo". Por lo menos así lo hago yo con brackets. De todos modos, hice el cambio por si acaso y sigue sin funcionar.

0voto

carlossevi comentado

Puedes comprobar en el enlace que estás confundido, es justo al revés.

Yo he copiado el código que tu has puesto añadiendo el link al CSS que pegaste entre etiquetas style que "Realmente está en un archivo a parte y perfectamente indexado en el archivo html/php" pero que no aparece en el código que has puesto y me ha funcionado correctamente.

Este problema tiene 2 partes:

  1. Montar una página con HTML, JS y CSS que permita modificar el color de fondo de los elementos desde JS.
  2. Hacer que el valor informado al JS se genere desde PHP y se almacene en la sesión.

Tu decías en tu pregunta que necesitabas ayuda para el segundo punto porque el primero lo tenías controlado, pero deberías intentar resolverlo por partes.

Te copio un enlace de JSFiddle en el que puede jugarse con el comportamiento: https://jsfiddle.net/wzxy4ex5/

0voto

SynSor comentado

OK! El caso es que antes trabajaba en Dreamweaver y efectivamente el id era para el "#" y el class para ".". Cuando dí el salto a un Open Source como lo es "brackets" cuando asignaba clases o id's no me funcionaban, fue entonces cuando probé a cambiar, y por arte de magia funciono, entonces, no de dí importancia hasta el día de hoy.

Ya todo funciona correctamente. Muchas gracias por todo y perdón por las molestias, postearé luego mi verdadera meta.

PD: He venido y me quedo por aquí!

0voto

SynSor comentado

Mi intención desde un principio era que cada DIV tuviera su propio color, con el script que "desarrollamos" arriba funcionaba, pero a todos los div les daba el mismo color. Entonces incluí un bucle en el código JS:

var n = 0;

        function changeBackground() {
            while (n < 10) {
                if (n == 10) {
                    n = 0;
                }
                var myElements = document.querySelectorAll('.prueba' + n);
                for (var i = 0; i < myElements.length; i++) {
                    myElements[i].classList.add("<?php print($_SESSION['color']);?>");
                }
                n++;
            }

        }
        window.onload = changeBackground;

Pero sigue sin funcionar, por lo tanto creo que es problema del script en php que "sortea" un color y lo mantiene.

¿Como se haría para que repartiera color por "consulta" o bucle?

Código completo:

<?php 

class colorines{
}
session_start();
if (!isset($_SESSION['color'])) {
    $colores = array("color1","color2","color3","color4","color5","color6","color7","color8");        
    $_SESSION['color'] = $colores[array_rand($colores,1)];
    $_SESSION['cont'] = 1;
} else {
    $_SESSION['cont']++;
} 
?>
    <!DOCTYPE html>
    <html lang="en">
    <script>
        var n = 0;

        function changeBackground() {
            while (n < 10) {
                if (n == 10) {
                    n = 0;
                }
                var myElements = document.querySelectorAll('.prueba' + n);
                for (var i = 0; i < myElements.length; i++) {
                    myElements[i].classList.add("<?php print($_SESSION['color']);?>");
                }
                n++;
            }

        }
        window.onload = changeBackground;
    </script>

    <head>
        <?php header('Content-Type: text/html; charset=UTF-8'); ?>
            <meta charset="utf-8">
            <meta name="viewport" content="user-scalable=no, width=device-width, initial-scale=1">
            <title>Integral | MOBI</title>
            <link rel="stylesheet" href="css/integral.css" type="text/css">
            <link rel="stylesheet" href="css/animate.css" type="text/css">
            <script src="js/jquery-1.11.3.min.js" type="application/javascript"></script>
    </head>

    <body>

        <div class="container">
            <div class="prueba0"></div>
            <div class="prueba1"></div>
            <div class="prueba2"></div>
            <div class="prueba3"></div>
            <div class="prueba4"></div>
            <div class="prueba5"></div>
            <div class="prueba6"></div>
            <div class="prueba7"></div>
            <div class="prueba8"></div>
            <div class="prueba9"></div>
        </div>

    </body>

    </html>

Un saludo y muchas gracias por todo!

0voto

carlossevi comentado

Yo eliminaría este comentario y crearía una pregunta nueva o pregunta relacionada (tienes el botón en la parte inferior de la respuesta) porque este hilo puede ser infinito y la final el tema va derivando y hablando de cosas no relacionadas con lo que preguntabas.

Tu pregunta original ya está respondida con algo que funciona y un visitante futuro podría utilizar en caso de tener el mismo problema. Si te parece puedes iniciar un nuevo hilo para preguntar todo lo que quieras, porque te recuerdo la primera aclaración que hicimos sobre esta pregunta:

Es decir, ¿quieres que a una visita se le asigne un color durante toda la sesión o que cada vez que se recarga la página lo haga con un color diferente entre tu colección de posibilidades?

Me refiero a que por cada visita se le asigne un color durante toda la sesión de la colección de colores que poseo.

Ahora ya sabes cómo asignar un color aleatorio desde PHP, guardarlo en la sesión y cambiarlo mediante JS en cada generación de la página. ¡Vamos a por el siguiente reto!

0voto

Peter comentado

@SynSor como dice @carlossevi para dudas nuevas, por favor abre preguntas nuevas. Así todo será claro para todos.

Saludos.

1voto

SynSor comentado

Entiendo, pueden proceder a eliminar los comentarios!

Un saludo!

Por favor, accede o regístrate para responder a esta pregunta.

Otras Preguntas y Respuestas


...

Bienvenido a entre Desarrolladores, donde puedes realizar preguntas y recibir respuestas de otros miembros de la comunidad.

Conecta