Ver Mensaje Individual
  #2 (permalink)  
Antiguo 30/11/2014, 11:34
Avatar de marlanga
marlanga
 
Fecha de Ingreso: enero-2011
Ubicación: Murcia
Mensajes: 1.024
Antigüedad: 13 años, 11 meses
Puntos: 206
Respuesta: Cambiar color de una celda mediante un boton

Los estilos, a la hoja de estilos. Hacerlo con javascript es siempre mala idea.
Código CSS:
Ver original
  1. td.elegible { cursor:pointer; }
  2. td.elegido { background-color: green; }
  3. td.procesado { background-color: red; cursor: not-allowed; }

Para el javascript he usado varias ideas:

Encapsular todo el código en un espacio de nombre llamado PRG, así no habrá conflictos con otros códigos que use la página, y personalmente lo veo mas bonito. Cuando no uso orientación a objetos, como en éste caso, suelo partir el código en tres bloques: datos, elementos HTML y funciones que usan esos datos y elementos para hacer cosas.

Como norma general, intenta que una función haga una única cosa, así el código es mas sencillo de entender, de modificar, de detectar errores, y de reusar en otros códigos. Todo ventajas, y ni una sola desventaja.

Es por ello que las declaraciones de eventos las he sacado a otra función, y ahí he usado una técnica llamada "delegación de eventos", que básicamente consiste en crear un evento en un único elemento contenedor que luego se ejecutará cuando salte ese mismo evento en sus hijos. ësto funciona porque los eventos en javascritp se disparan en cadena, primero el hijo, luego el padre, despues el abuelo, etc, hasta llegar al "<body>". Así en memoria sólo hay declarado un único evento sobre la tabla, pero en la práctica es como si en todos los TD's de tu tabla tuvieran ese evento declarado. Otra ventaja que tiene esta técnica es que si insertas futuros TD's en esa tabla, automáticamente también tendrán ese evento asociado.

Y por último he aprovechado el classList que tienen todos los elementos html de JAVASCRIPT para manejar su listado de clases. Con él tienes add, remove, toggle y contains. El primero añade clases, mirando de no meterla otra vez si ya la tiene. El segundo, elimina. El tercero mete la clase si no la tiene, o la elimina si la tiene. El cuarto te dice si una clase existe en un elemento.

Así que la lógica javascript sólo se encarga de meter clases a los elementos TD's, y el CSS les da color.

Como curiosidad, todos los GetElement[s]By(Id | ClassName | TagName) devuelven lista dinámicas. Es decir, si hago un getElementByClassName, y luego con un bucle lo recorro, y borro la clase que usé en la función de antes, el listado se actualizará (se borrará esa posición que usas en el bucle) y probablemente ocurran errores en tu código del bucle. Lo he solucionado simplemente recorriendo el blucle alrevés y haciendo el borrado de la clase en último lugar. Otra posible solución es clonar el array de elementos obtenido, y así éste no se modificará dinámicamente dentro del bucle.

Por último, y haciendo referencia a lo que dije en primer lugar: Los estilos a la hoja de estilos. No escribas estilos dentro de elementos <HTML> ni se los metas con javascript. Es un coñazo de mantener, y muy pesado de entender. Por la misma razón, no metas javascript a los elementos HTML. El onload del body se reescribe fácilmente a javascript con un simple window.onload, por ejemplo. O con un window.addEventListener('load') por si alguno de los otros códigos también necesitara usar el evento load.

Código Javascript:
Ver original
  1. var PRG = {
  2.     datos : {
  3.         columnas : 6,
  4.         filas : 5,
  5.         clase_elegible : 'elegible',
  6.         clase_elegido : 'elegido',
  7.         clase_procesado : 'procesado'
  8.     },
  9.     elementos : {
  10.         div_reservar : null,
  11.         tabla : null,
  12.         btn_comprar : null
  13.     },
  14.     funciones : {
  15.         cargar : function() {
  16.             PRG.elementos.div_reservar = document.getElementById("reservar");
  17.             PRG.elementos.tabla = document.getElementById("tabla");
  18.             PRG.elementos.btn_comprar = document.getElementById("comprar");
  19.             PRG.funciones.crearTabla();
  20.             PRG.funciones.crearEvento();
  21.         },
  22.         crearTabla : function() {
  23.             var tblBody = document.createElement("tbody");
  24.             for (var i = 0; i < PRG.datos.columnas; i++) {
  25.                 var fila = document.createElement("tr");
  26.                 for (var j = 0; j < PRG.datos.filas; j++) {
  27.                     var celda = document.createElement("td");
  28.                     var textoCelda = document.createTextNode(i+"-"+j);
  29.                     celda.classList.add(PRG.datos.clase_elegible);
  30.                     celda.appendChild(textoCelda);
  31.                     fila.appendChild(celda);
  32.                 }
  33.                 tblBody.appendChild(fila);
  34.             }
  35.             PRG.elementos.tabla.appendChild(tblBody);
  36.             PRG.elementos.tabla.setAttribute("border", "2");
  37.         },
  38.         accionClickTd : function (td) {
  39.             if (!td.classList.contains(PRG.datos.clase_procesado)) {
  40.                 td.classList.toggle(PRG.datos.clase_elegido);
  41.             }
  42.         },
  43.         accionClickComprar : function () {
  44.             var elegidas = PRG.elementos.tabla.getElementsByClassName(PRG.datos.clase_elegido);
  45.             var n_ini = elegidas.length, n = n_ini;
  46.             console.log(elegidas);
  47.             while (n--) {
  48.                 elegidas[n].classList.add(PRG.datos.clase_procesado);
  49.                 elegidas[n].classList.remove(PRG.datos.clase_elegido);
  50.             }
  51.             alert('Ha comprado ' + n_ini + ' asientos');
  52.         },
  53.         crearEvento : function() {
  54.             PRG.elementos.tabla.addEventListener("click", function(e) {
  55.                 if(e.target) {
  56.                     if (e.target.classList.contains(PRG.datos.clase_elegible)) {
  57.                         PRG.funciones.accionClickTd(e.target);
  58.                     }
  59.                 }
  60.             });
  61.             PRG.elementos.btn_comprar.addEventListener("click", function() {
  62.                 PRG.funciones.accionClickComprar();
  63.             });
  64.         }
  65.     }
  66. };
  67.  
  68. window.onload = function () {
  69.     PRG.funciones.cargar();
  70. }

PD. Me he molestado en soltar este rollazo porque te veo maneras aunque no demasiada experiencia, por lo menos con JS; y porque has usado correctamente las herramientas del foro para escribir HTML por un lado y JAVASCRIPT por otro, haciendo que no me sangren los ojos al leer.

Última edición por marlanga; 30/11/2014 a las 11:44