【问题标题】:Why does onclick's handling function not work as expected?为什么onclick的处理功能没有按预期工作?
【发布时间】:2011-12-26 07:49:43
【问题描述】:

我有以下一小段代码:

var instance = this;
window.onload = function () {
    for (var i = 0; i < array.length; ++i) {
        var currentDivId= array[i];
        var currentDiv = document.getElementById(currentDivId);

        try {
            if (!currentDiv) {
                throw 'Div id not found: ' + currentDivId;
            }
            var image = document.createElement('img');
            image.src = 'img.jpg';
            image.onclick = function() {
                instance.doSomething(currentDivId);
            };

            currentDiv.appendChild(image);
        }
        catch(e) {
            console.warn('oops');
        }
    }
};

此代码传递了一个 div 的 id 数组。它的作用是,它在每个 div 处呈现图像并设置它们的 onclick 属性。

假设我有一个字符串数组:['abc', 'xyz']

我希望代码在&lt;div id="abc"&gt;&lt;/div&gt; 中放置一个图像,在&lt;div id="xyz"&gt;&lt;/div&gt; 中放置另一个图像。

当您单击第一张图片时,应使用参数'abc' 调用instance.doSomething 函数,反之亦然。

但是代码没有按预期工作。它总是使用数组中的最后一个参数调用instance.doSomething,在本例中为'xyz'

我是 JS 的新手,但对它的内部工作原理还没有完全掌握。这里出了什么问题,我该如何解决?

任何帮助表示赞赏。谢谢。

【问题讨论】:

  • 我认为你必须在for循环中写i++而不是++i

标签: javascript dom javascript-events


【解决方案1】:
image.onclick = function() {
    instance.doSomething(this.parentNode.id);
};

应该这样做。由于我们知道图片在我们想要获取的 div 中,因此只需向上移动一个 dom 元素并获取其 id。

【讨论】:

    【解决方案2】:

    欢迎来到 Javascript 范围问题的精彩世界。就目前而言,JS 将您的 onclick 代码视为“当单击此对象时,在单击发生时获取存储在 currentDivID 变量中的值并将其传递给 doSomething 函数”。

    您应该做的是将参数基于图像对象本身。每个 DOM 对象都知道它在 DOM 树中的位置,因此在单击它时,onclick 代码应该使用 DOM 遍历操作来确定它在哪个 div 中并动态检索其 ID。这样您就不必担心绑定变量和范围问题...只需找出哪个 div 包含您的图像并在运行时获取 ID。

    【讨论】:

    • 好的,但是这种方法不会花费一些时间,至少是日志(页面大小)时间吗?没有什么比这更容易/更快了?如果没有,我如何让我的图像弄清楚它包含在哪个 div 中:)
    • 解析树实际上是一个非常快速的操作。每个节点都有一个 .parentNode 属性,您可以跟随这些父节点回到树的顶部。日志(页面深度)将是最坏的情况。而且由于您将图像直接插入到 div 中,因此您可能最终只需要去 img.parentNode 即可获取图像所在的 div,所以 O(1)。
    【解决方案3】:

    试试:

    image.onclick = (function() {
      var currentD = currentDivId;
      return function() { 
          instance.doSomething(currentD);
      }
    })();
    

    希望对你有帮助

    【讨论】:

    • 不幸的是,它不起作用。按钮不再响应。
    • @Murat - 这应该可以。您提到您是 JS 新手,所以 (function(){})() 语法对您来说可能是新的,但请确保您匹配所有括号。也许 Sudhir 可以添加一些关于 为什么 它起作用的解释......
    猜你喜欢
    • 2023-01-11
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-12-26
    • 2014-08-04
    • 2021-01-03
    • 2018-11-08
    • 1970-01-01
    相关资源
    最近更新 更多