2012-05-22 10 views
12

Właśnie opracowałam mały kod do stworzenia stołu 24x60. Chcę drukować identyfikator każdego <td> na mouseover:Efektywność tworzenia obsługi zdarzeń w zagnieżdżonej pętli: czy w tym miejscu tworzę 1440 funkcji?

<!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> 

Kod działa, ale teraz jestem zaniepokojony, jeśli jest zoptymalizowana? Czy tworzę funkcje obsługi zdarzeń 1440 w zagnieżdżonych pętlach? Czy też interpreter JavaScript jest wystarczająco inteligentny, aby utworzyć tylko jedną funkcję i przypisać ją do elementów 1440 <td>?

+4

Aby mieć 100% pewności, że wykonujesz tylko jedną funkcję, możesz ją zadeklarować poza pętlą. –

+0

Który tłumacz? Jaka wersja? Za każdym razem, gdy spytasz, czy JavaScript jest wystarczająco inteligentny, zwykle nie ma odpowiedzi. – Joe

+1

Nie wiem, czy to powoduje nową funkcję dla każdego, ale jeśli zdefiniować funkcję, a następnie po prostu przypisać, że zamiast korzystania z funkcji anonimowej, powinieneś mieć odniesienia do tej samej funkcji. – JerseyMike

Odpowiedz

13

Nie, JavaScript nie będzie dla żadnej optymalizacji (no, może niektóre implementacje, ale nie powinieneś polegać na tym). Naprawdę tworzysz wiele funkcji.

lepiej zdefiniować funkcję raz i używać go:

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); 
} 

Albo rozważyć użycie zdarzeń delegację, czyli wiązania obsługi do przodka komórki:

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

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

Działa to, ponieważ zdarzenia powodują bąble w drzewie DOM i mogą nawet poprawić wydajność w niektórych przeglądarkach.

Dobre źródło informacji na temat obsługi zdarzeń to the articles at quirksmode.org.

+3

+1 dla delegacji – jbabey

+0

Tylko uwaga na temat delegacji: działa tylko w przypadku zdarzeń, które faktycznie powodują bańki w drzewie DOM. Zdarzenia takie jak przesłanie, fokus, rozmycie, wczytanie, zwalnianie, zmiana, resetowanie i przewijanie * nie powodują bańki *, więc delegacja nie będzie działać. – jordancpaul

1

niewielka zmiana, być na bezpiecznej stronie:

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

sugeruję oddanie obsługi jednego zdarzenia na stole i przy użyciu zdarzenie propagacji obsługiwać go w jednym miejscu:

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); 

Dla starszych wersji IE należy użyć metody attachEvent zamiast addEventListener.

1

Tak, użytkownik definiuje funkcję bez nazwy dla każdego elementu w tym miejscu, ale można po prostu zdefiniować funkcję poza pętlą i odnieść ją.

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); 
} 
Powiązane problemy