单击附加到domconstruct.placed的事件,dojo中的节点被错误的处理程序处理

单击附加到domconstruct.placed的事件,dojo中的节点被错误的处理程序处理,dojo,Dojo,考虑以下几点: gridID = datagridID; //column headers domConstruct.place("<div class=\"gridheaderrow\" data-type =\"BolingerGridHeaderRow\" ></div>", gridID, "first"); var node = query("div[data-type=\"Bolinge

考虑以下几点:

 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'>&#x25B2</div>", headernode, "last");
                var sortdown = domConstruct.place("<div id=column'" + i + "' data-columndownid = '" + i + "' data-type='sortdownarrow' style='display:inline; cursor:pointer'>&#x25BC</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);
                });

            }
gridID=datagridID;
//列标题
domConstruct.place(“,gridID,“first”);
var node=query(“div[数据类型=\”BolingerGridRow\“]”,gridID);
var headerNode=query(“div[数据类型=\”BolingerGridHeaderRow\”],gridID);
var cells=query(“div[数据类型=\”BolingerGridCell\”],节点[0]);
对于(变量i=0;i

这段代码在每一列上方都放置了一个小的上下箭头,并将单击事件附加到这些列上,这将调用sort函数。我很确定我会将每个事件向上或向下箭头连接一次。然而,无论我单击处理它的处理程序上的哪个箭头,它都属于最后一列的箭头。为什么会这样?我认为这与将处理程序附加到我刚刚放置的节点有关。想法?

变量在JavaScript中没有块作用域。您希望通过第二个
for
循环的每个迭代都有自己的
sortupnode
sortdownnode
变量,但实际上每次通过循环时,都会重新声明相同的变量,并替换其值。您的
on
处理程序继续引用相同的
sortupnode
sortdownnode
变量,这些变量在运行时将始终引用最后迭代的节点

在这种情况下,最简单的修复方法可能是将事件处理程序中的
sortupnode
sortdownnode
替换为
this
,它应该引用处理程序为其激发的元素。但是,您应该能够完全避免这个问题,并使用更有效的方法连接这些事件处理程序。大致如下:

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 = ...;
    ...
}
(变量i=0;i<…;i++)的
{
var foo=。。。;
...
}
。。。本质上与此等效,因为JavaScript变量没有块作用域:

var i;
var foo;
for (i = 0; i < ...; i++) {
    foo = ...;
    ...
}
vari;
var foo;
对于(i=0;i<…;i++){
foo=。。。;
...
}
也就是说,变量
foo
存在于周围函数的作用域中,而不是
for
循环。同一
foo
变量的值在每次循环中都会被修改


循环运行结束后查看
foo
的任何代码都将看到循环中分配的最后一个值
foo
。您在循环的每个迭代中定义事件处理程序回调,该循环可以从包含函数的作用域访问
foo
,但这些回调实际上只有在用户执行操作时才被调用。“Way later”=在循环完成运行之后=
foo
始终将是它在上一次迭代中设置的值。

之前,我曾经因为c#结束循环变量而感到困惑。有趣的是,我已经写了好几个月的JavaScript,但却没有很快遇到这个问题。我也不明白JavaScript事件是如何工作的。所以你是说如果我将一个事件附加到一个节点变量上,我必须注意不要覆盖该变量并将一个新事件附加到该变量上?我添加到我的响应中,试图对其进行更详细的解释。问题与事件处理无关,而与变量scope.Correct有关。是的,我了解可变范围及其含义。我以前写过一个小编译器!我只是假设javascript会有作用域变量,直到现在才注意到任何相反的证据。现在一切都很好,我是一个更聪明的javascript程序员。非常感谢你,肯。