考虑以下事项:
gridID = datagridID;
//column headers
domConstruct.place("<div class=\"gridheaderrow\" data-type =\"BolingerGridHeaderRow\" ></div>", gridID, "first");
var node = query("div[data-type=\"BolingerGridRow\"]", gridID);
var headerNode = query("div[data-type=\"BolingerGridHeaderRow\"]", gridID);
var cells = query("div[data-type=\"BolingerGridCell\"]", node[0]);
for (var i = 0; i < cells.length; i++)
{
var columnname;
columnname = attr.get(cells[i], "data-columnname");
var headernode = domConstruct.place("<div class=\"gridheadercell\" data-type=\"BolingerGridHeaderCell\">" + columnname + "</div>", headerNode[0], "last");
var sortup = domConstruct.place("<div id=column'" + i + "' data-columnupid = '" + i + "' data-type='sortuparrow' style='display:inline; cursor:pointer'>▲</div>", headernode, "last");
var sortdown = domConstruct.place("<div id=column'" + i + "' data-columndownid = '" + i + "' data-type='sortdownarrow' style='display:inline; cursor:pointer'>▼</div>", headernode, "last");
}
for (var i = 0; i < cells.length; i++)
{
var sortupnode = query("[data-columnupid = '" + i + "']", gridID)[0];
var sortdownnode = query("[data-columndownid = '" + i + "']", gridID)[0];
on(sortupnode, "click", function (e) {
var num = attr.get(sortupnode, "data-columnupid");
sort(true, num);
});
on(sortdownnode, "click", function (e) {
var num = attr.get(sortdownnode, "data-columndownid");
sort(false, num);
});
}
此代码在每列上方放置很少的向上和向下箭头,并在点击事件上附加到它们,调用sort函数。我很确定我每次向上或向下箭头附加事件。然而,无论什么箭头,我点击处理它的处理程序属于最后一列的箭头。为什么是这样?我认为它与将处理程序附加到我刚刚放置的节点有关。想法?
答案 0 :(得分:2)
变量在JavaScript中没有块范围。您期望通过第二个for
循环的每次迭代都有自己的sortupnode
和sortdownnode
变量,但实际上每次循环时,相同的变量都被重新声明,其值为被替换。您的on
处理程序继续引用相同的sortupnode
和sortdownnode
变量,这些变量在运行时始终会引用最后迭代的节点。
在这种情况下,绝对最简单的修复可能是用sortupnode
替换事件处理程序中的sortdownnode
和this
,它应该引用处理程序触发的元素。但是,您应该能够完全避免此问题,并使用event delegation更有效地连接这些事件处理程序。有点像:
on(document.getElementById(gridID), '[data-columnupid]:click', function (event) {
// Inside delegated event handlers registered with dojo/on,
// `this` references the element that matched the selector
var num = this.getAttribute('data-columnupid');
sort(true, num);
});
回应您的第二条评论:您遇到的问题与事件处理没有直接关系;它纯粹与范围在JavaScript中的工作方式有关。
为了更好地说明循环中的变量实际是如何工作的,请记住:
for (var i = 0; i < ...; i++) {
var foo = ...;
...
}
...基本上等同于此,因为JavaScript变量没有块范围:
var i;
var foo;
for (i = 0; i < ...; i++) {
foo = ...;
...
}
也就是说,变量foo
存在于周围函数的范围内,不 for
循环。每次循环时,相同的foo
变量的值都会被修改。
在循环结束后查看foo
的任何代码都会看到循环中分配的最后一个值foo
。您正在通过循环在每次迭代中定义事件处理程序回调,这些回调可以从包含函数的作用域访问foo
,但这些回调实际上只是在用户以后调用方式执行一个动作。 &#34;后来&#34; =循环结束后运行= foo
始终是在上一次迭代中设置的值。