我的功能有什么问题

时间:2017-03-05 01:52:42

标签: javascript jquery html

我不知道为什么这不起作用。函数调用底部  displayWorld();如果您提交该行,然后在控制台中的console.log工作。但是,如果我在代码中调用该函数就会中断。

抱歉这里错误

  

未捕获的TypeError:无法设置null的属性“innerHTML”       在displayWorld(index.html:40)       在index.html:43

HTML

<!DOCTYPE html>
<html>
<head>
    <title>Pacman Demo</title>
    <meta charset="utf-8">
  <link rel="stylesheet" type="text/css" href="style.css"></style>
  <script type="text/javascript" src='http://code.jquery.com/jquery-1.10.2.min.js'></script> 
  <script type="text/javascript">

  var world = [
              [2,2,2,2,2,2,2,2,2,2],
              [2,1,1,2,1,1,1,1,1,2],
              [2,1,1,2,1,2,2,2,1,2],
              [2,1,1,1,1,1,2,1,1,2],
              [2,1,1,1,1,1,2,1,1,2],
              [2,1,1,1,1,1,2,1,1,2],
              [2,1,1,1,1,1,2,1,1,2],
              [2,1,1,1,1,1,1,1,1,2],
              [2,2,2,2,2,2,2,2,2,2],

            ];


            function displayWorld(){
                var output = '';

                for(var i=0; i<world.length; i++){
                    output += "\n<div class='row'>";
                    for(var j=0; j<world[i].length; j++){
                        if(world[i][j] == 2)
                            output += "\n\t<div class='brick'></div>";
                        else if(world[i][j] == 1)
                            output += "\n\t<div class='coin'></div>";
                        if(world[i][j] == 0)
                            output += "<\n\tdiv class='empty'></div>";
                    }
                    output += "\n</div>";
                }
                console.log(output);
                document.getElementById('world').innerHTML = output;
            }

     displayWorld();      <----- this piece here
  </script>


    </style>
</head>
<body>

    <div id='world'></div>


</body>
</html>

CSS

/*CSS reset settings here*/
*{
 margin: 0px;
 padding: 0px;
}

body{
    background-color: black ;
}
div.row div{
    width: 20px;
    height: 20px;
    display: inline-block;
}

div.brick {
    background-color: blue;

}

div.coin{
    background: url(coin.gif);
    background-repeat: no-repeat;
    background-position: center;

}

div.packman{
    background: url(mrpacman.gif);
    background-repeat: no-repeat;
    background-position: center;

}

div.empty{


}

2 个答案:

答案 0 :(得分:2)

我认为它是因为你在创建div标签之前加载js文件,把脚本放在正文的末尾并且应该修复它

答案 1 :(得分:1)

要完全理解为什么会发生这种情况,您应该了解HTML + CSS + JS模型的工作原理。我描述了整页加载和执行逻辑,因为它可以帮助您理解类似的问题。如果您只对当前错误感兴趣,请跳至第3点。

  1. 在构建CSSOM之前不执行JavaScript(以防止FOUC)。
  2. CSSOM是在读取和解析<head>之后构建的。 这就是您需要将所有样式集和<style>标记放在<head>中的原因。如果将它们放在<body>中,则可以在正文中<style>之前的内容上使用FOUC,因为它首先在没有这些规则的情况下进行渲染。
  3. <script>标签会在出现后立即按外观顺序读取和执行。已经从<head>加载的内容会在<body>标记添加到DOM之前按照遇到的顺序执行。 <script>内的<body>代码会在符合DOM时生成,{strong> ,但在添加页面的其余部分(以下内容)之前到DOM
  4. 这意味着您的<script>代码会在<div id="world"></div>和您的脚本中创建DOM之前执行,并尝试使用此行添加内容...

    document.getElementById('world').innerHTML = output;
    

    ...导致错误,因为此时document.getElementById('world')返回nullnull没有innerHTML属性。

    要解决此问题,您应该将您的脚本放在<body> div之后的#world中:

    &#13;
    &#13;
    *{
     margin: 0px;
     padding: 0px;
    }
    
    body{
        background-color: black ;
    }
    div.row div{
        width: 20px;
        height: 20px;
        display: inline-block;
    }
    
    div.brick {
        background-color: blue;
    
    }
    
    div.coin{
        background: url(coin.gif);
        background-repeat: no-repeat;
        background-position: center;
    
    }
    
    div.packman{
        background: url(mrpacman.gif);
        background-repeat: no-repeat;
        background-position: center;
    
    }
    
    div.empty{
    
    }
    &#13;
    <div id="world"></div>
    <script type="text/javascript">
      var world = [
        [2, 2, 2, 2, 2, 2, 2, 2, 2, 2],
        [2, 1, 1, 2, 1, 1, 1, 1, 1, 2],
        [2, 1, 1, 2, 1, 2, 2, 2, 1, 2],
        [2, 1, 1, 1, 1, 1, 2, 1, 1, 2],
        [2, 1, 1, 1, 1, 1, 2, 1, 1, 2],
        [2, 1, 1, 1, 1, 1, 2, 1, 1, 2],
        [2, 1, 1, 1, 1, 1, 2, 1, 1, 2],
        [2, 1, 1, 1, 1, 1, 1, 1, 1, 2],
        [2, 2, 2, 2, 2, 2, 2, 2, 2, 2],
    
    ];
    
    function displayWorld() {
        var output = '';
    
        for (var i = 0; i < world.length; i++) {
            output += "\n<div class='row'>";
            for (var j = 0; j < world[i].length; j++) {
                if (world[i][j] == 2)
                    output += "\n\t<div class='brick'></div>";
                else if (world[i][j] == 1)
                    output += "\n\t<div class='coin'></div>";
                if (world[i][j] == 0)
                    output += "<\n\tdiv class='empty'></div>";
            }
            output += "\n</div>";
        }
        document.getElementById('world').innerHTML = output;
    }
    
    displayWorld();
      </script>
    &#13;
    &#13;
    &#13;

    作为替代方案,您可以通过将脚本包装在

    中来延迟执行脚本
    window.onload = function() {
      // your script here...
    }
    

    这会延迟执行脚本,直到load触发window事件,一旦遇到</html>DOM完成,就会发生这种情况。

    注意:您的脚本不包含任何jQuery代码,由于您的示例不需要,我将其删除。