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

时间:2014-12-12 21:42:16

标签: dojo

考虑以下事项:

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

            }

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

1 个答案:

答案 0 :(得分:2)

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

在这种情况下,绝对最简单的修复可能是用sortupnode替换事件处理程序中的sortdownnodethis,它应该引用处理程序触发的元素。但是,您应该能够完全避免此问题,并使用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始终是在上一次迭代中设置的值。