javascript - Efficiency of creating an event handler in a nested loop: am I creating 1440 functions here? - Stack Overflow

I just developed a little code to create a 24x60 table. I want to print the id of each <td> on mo

I just developed a little code to create a 24x60 table. I want to print the id of each <td> on mouseover:

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" ".dtd">
<html xmlns="">
<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>

The code works, but now I'm concerned if it is optimized? Am I creating 1440 event handling functions in the nested loops? Or is the JavaScript interpreter smart enough to only create one function and assign it to 1440 <td> elements?

I just developed a little code to create a 24x60 table. I want to print the id of each <td> on mouseover:

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3/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>

The code works, but now I'm concerned if it is optimized? Am I creating 1440 event handling functions in the nested loops? Or is the JavaScript interpreter smart enough to only create one function and assign it to 1440 <td> elements?

Share Improve this question edited May 22, 2012 at 20:25 AlexStack asked May 22, 2012 at 20:10 AlexStackAlexStack 17.4k22 gold badges74 silver badges107 bronze badges 5
  • 4 To be 100% sure that you're only making one function, you can declare it outside the loop. – gen_Eric Commented May 22, 2012 at 20:14
  • Which interpreter? What version? Anytime you ask if JavaScript is smart enough, the answer is usually no. – Joe Commented May 22, 2012 at 20:14
  • 1 I don't know if that causes a new function for each, but if you define a function and then just assign that, instead of using the anonymous function, you should have references to the same function. – JerseyMike Commented May 22, 2012 at 20:14
  • JavaScript, I think, does what you ask it to do; not what you meant/want it to do. – David Thomas Commented May 22, 2012 at 20:14
  • This is a good question... consider changing the title into something someone would google for. – BeemerGuy Commented May 22, 2012 at 20:20
Add a ment  | 

4 Answers 4

Reset to default 12

No, JavaScript won't to any optimizations (well, maybe some implementations do, but you should not rely on that). You are really creating that many functions.

Better define the function once and reuse it:

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

Or consider to use event delegation, that is, binding the handler to an ancestor of the cells:

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

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

This works, since events bubble up the DOM tree and might even better performance-wise in some browsers.

A good resource to learn about event handling are the articles at quirksmode.

a small change, to be on the safe side:

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

I'd suggest putting one event handler on the table and using event bubbling to handle it in one place:

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

For older versions of IE, you would use attachEvent instead of addEventListener.

Yes, you define an unnamed function for every element in there, but you could simply define the function outside of the loop and reference it.

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

发布者:admin,转转请注明出处:http://www.yc00.com/questions/1743727576a4496878.html

相关推荐

发表回复

评论列表(0条)

  • 暂无评论

联系我们

400-800-8888

在线咨询: QQ交谈

邮件:admin@example.com

工作时间:周一至周五,9:30-18:30,节假日休息

关注微信