【问题标题】:Javascript increment variable to update table cells onclickJavascript增量变量以更新表格单元格onclick
【发布时间】:2012-09-12 13:54:39
【问题描述】:

我有一个页面,用户在其中输入颜色,然后我调用 onClick 方法来更改表格中各个单元格的颜色。但是,当我单击任何单元格时,只有最后一个单元格(在本例中为 cell3)会改变颜色。我做错了什么?

我得到错误:

消息:'document.getElementById(...)' 为 null 或不是对象
线路:24
字符:4
代码:0

我的代码是:

    <html>

    <body>
    <input type='text' id='userInput' value='yellow' />

    <table border="1"> 
        <tr>
            <td id="1">cell1
            </td>
        </tr>
        <tr>
            <td id="2">cell2
            </td>
        </tr>
        <tr>
            <td id="3">cell3
            </td>
        </tr>

    </table>

    <script type="text/javascript">
    for(var i = 1; i <= 3; i++){
        document.getElementById(i).onclick = function(){
        var newColor = document.getElementById('userInput').value;
            document.getElementById(i).style.backgroundColor = newColor;
        }
    }
    </script> 
    </body>

    </html>

【问题讨论】:

    标签: javascript html html-table onclick


    【解决方案1】:

    将您的 HTML 更改为:ID 必须以字母字符开头。不能以数字开头。

    <table border="1"> 
        <tr>
            <td id="td1">cell1
            </td>
        </tr>
        <tr>
            <td id="td2">cell2
            </td>
        </tr>
        <tr>
            <td id="td3">cell3
            </td>
        </tr>
    
    </table>
    

    这是一个非常常见的 Javascript 问题:所有代码共享 i 的值,即循环结束时的 3。您可以通过使用另一个辅助函数来解决它,如下所示:

    function changeIt(i) {
      // This inner function now has its own private copy of 'i'
      return function() {
        var newColor = document.getElementById('userInput').value;
          document.getElementById("td" + i).style.backgroundColor = newColor;
      }
    }
    
    for(var i = 1; i <= 3; i++){
        document.getElementById(i).onclick = changeIt(i);
    }
    

    也可以使用匿名函数来编写,但它们更难阅读。

    【讨论】:

    • 我正要投票,但是你的代码没有解决问题,你必须把document.getElementById(i).onclick = function() { changeIt(i); }替换成document.getElementById(i).onclick = changeIt(i);
    • 变量范围和字母字符 id 的优点。不过,我更喜欢使用this
    • @StuartWakefield -- 是的,我确实有点搞砸了。谢谢你的收获。
    • @EricLennartsson -- this 会是更好的选择,但那样我们就失去了阻止未来问题的机会。
    【解决方案2】:

    首先,你的 for 循环是错误的。试试:

    for(var i = 1; i <= 3; i++) {
       //code
    }
    

    其次,您可以使用this,而不是每次在循环中检索元素:

    this.style.backgroundColor = document.getElementById('userInput').value;
    

    【讨论】:

    • 已更新为使用 this 关键字,这将使您的代码正常工作。此外,就像 Jeremy 指出的那样,您不应该以数字开头的元素 id。
    【解决方案3】:

    Jeremy 的答案很接近,但仍然存在一个问题,即 changeIt 直到单击元素才被调用,此时 i 的值仍然为 3。使用 Jeremy 对 HTML 的更新,正确的脚本可以写成...

    function createChangeColorHandler(n) {
      return function() {
        var newColor = document.getElementById('userInput').value;
        document.getElementById("td" + n).style.backgroundColor = newColor;
      }
    }
    
    for(var i = 1; i <= 3; i++) {
      // We pass i to the function createChangeColorHandler by value
      // at the time of this pass of the loop rather than referencing 
      // the variable directly after the loop has finished
      document.getElementById(i).onclick = createChangeColorHandler(i);
    }
    

    作为匿名函数...

    for(var i = 1; i <= 3; i++) {
      // We pass i to the function createChangeColorHandler by value
      // at the time of this pass of the loop rather than referencing 
      // the variable directly after the loop has finished
      document.getElementById(i).onclick = (function(n) {
        return function() {
          var newColor = document.getElementById('userInput').value;
          document.getElementById("td" + n).style.backgroundColor = newColor;
        }
      })(i);
    }
    

    编辑杰里米的答案现在是正确的

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2019-11-08
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2017-06-03
      • 2020-04-25
      相关资源
      最近更新 更多