2012-05-22 9 views
12

Acabo de desarrollar un pequeño código para crear una tabla de 24x60. Quiero imprimir el id de cada <td> en mouseover: trabajaEficiencia de crear un controlador de eventos en un bucle anidado: ¿estoy creando 1440 funciones aquí?

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> 
<html xmlns="http://www.w3.org/1999/xhtml"> 
<head> 
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" /> 
<title>Untitled Document</title> 
<style type="text/css"> 
table { 
    background-color:blue; 
} 
td { 
    width: 2px; 
    height: 2px; 
    background-color:red; 
} 
</style> 
</head> 
<body> 
<table id="time-table"></table> 
<script type="text/javascript"> 
var table = document.getElementById("time-table"); 
for (var r = 0; r < 24; r++) { 
    var row = document.createElement("tr"); 
    for (var c = 0; c < 60; c++) { 
     var td = document.createElement("td"); 
     td.id = "td-" + r + "-" + c; 
     td.onmouseover = function (e) { 
      console.log(this.id); 
     } 
     row.appendChild(td); 
    } 
    table.appendChild(row); 
} 
</script> 
</body> 
</html> 

El código, pero ahora estoy preocupado si está optimizado? ¿Estoy creando 1440 funciones de manejo de eventos en los bucles anidados? ¿O es el intérprete de JavaScript lo suficientemente inteligente como para crear solo una función y asignarla a 1440 <td> elementos?

+4

Para estar 100% seguro de que solo está haciendo una función, puede declararla fuera del ciclo. –

+0

¿Qué intérprete? ¿Qué versión? Cada vez que pregunta si JavaScript es lo suficientemente inteligente, la respuesta suele ser no. – Joe

+1

No sé si eso causa una nueva función para cada uno, pero si defines una función y luego simplemente la asignas, en lugar de usar la función anónima, debes tener referencias a la misma función. – JerseyMike

Respuesta

13

No, JavaScript no hará ninguna optimización (bueno, tal vez algunas implementaciones sí, pero no debería confiar en eso). Realmente estás creando tantas funciones.

definir mejor la función vez y reutilizarla:

var handler = function() { 
    console.log(this.id); 
} 

for (var r = 0; r < 24; r++) { 
    var row = document.createElement("tr"); 
    for (var c = 0; c < 60; c++) { 
     var td = document.createElement("td"); 
     td.id = "td-" + r + "-" + c; 
     td.onmouseover = handler; 
     row.appendChild(td); 
    } 
    table.appendChild(row); 
} 

O considere utilizar delegación de eventos, es decir, la unión del manejador a un antepasado de las células:

table.onmouseover = function(event) { 
    event = event || window.event; 
    var target = event.target || event.srcElement; 

    if(target.nodeName === 'TD') { 
     console.log(target.id); 
    } 
}; 

Esto funciona, ya que los eventos aumentan el árbol DOM y pueden mejorar aún más el rendimiento en algunos navegadores.

Un buen recurso para aprender sobre el manejo de eventos es the articles at quirksmode.org.

+3

+1 para la delegación – jbabey

+0

Solo una nota acerca de la delegación: solo funciona para eventos que en realidad crean el árbol DOM. Los eventos como enviar, enfocar, desenfocar, cargar, descargar, cambiar, restablecer y desplazarse * no hacen burbujas *, por lo que la delegación no funcionará. – jordancpaul

1

un pequeño cambio, para estar en el lado seguro:

var myFunc = function (e) { 
    console.log(this.id); 
}; 

var table = document.getElementById("time-table"); 
for (var r = 0; r < 24; r++) { 
    var row = document.createElement("tr"); 
    for (var c = 0; c < 60; c++) { 
     var td = document.createElement("td"); 
     td.id = "td-" + r + "-" + c; 
     td.onmouseover = myFunc; 
     row.appendChild(td); 
    } 
    table.appendChild(row); 
} 
1

yo sugeriría poner un manejador de eventos sobre la mesa y el uso de la propagación de eventos para manejarlo en un solo lugar:

var table = document.getElementById("time-table"); 
for (var r = 0; r < 24; r++) { 
    var row = document.createElement("tr"); 
    for (var c = 0; c < 60; c++) { 
     var td = document.createElement("td"); 
     td.id = "td-" + r + "-" + c; 
     row.appendChild(td); 
    } 
    table.appendChild(row); 
} 
table.addEventListener('mouseover', function(e) { 
    console.log(e.target.id); 
}, false); 

Para versiones anteriores de IE, usaría attachEvent en lugar de addEventListener.

1

Sí, define una función sin nombre para cada elemento, pero simplemente podría definir la función fuera del ciclo y hacer referencia a ella.

var printMyId = function(e) { 
    console.log(e.srcElement.id); 
}; 
var table = document.getElementById("time-table"); 
for (var r = 0; r < 24; r++) { 
    var row = document.createElement("tr"); 
    for (var c = 0; c < 60; c++) { 
    var td = document.createElement("td"); 
    td.id = "td-" + r + "-" + c; 
    td.onmouseover = printMyId; 
    row.appendChild(td); 
    } 
    table.appendChild(row); 
} 
Cuestiones relacionadas