【问题标题】:'appendChild' of undefined未定义的'appendChild'
【发布时间】:2020-03-18 23:19:43
【问题描述】:

所以我尝试按照教程使用 THREE.js 实现太阳能系统,但是我收到以下错误:

无法读取未定义的属性“appendChild”

这是我当前的代码:

<html>
    <head>
        <meta charset ="utf8">
        <title> Solar System Project </title>
        <script src = "three.min.js"></script>
    </head>

    <body>


        <script>

            // Standard Variables / To be changed later.
            var scene, camera, render, container;
            var W,H;

            // On load function...
            window.onload = function() {
                container = document.createElement('div');
                document.body.appendChild(container);

                W = parseInt(window.innerWidth);
                H = parseInt(window.innerHeight);

            }

            camera = new THREE.PerspectiveCamera(45, W/H, 1, 10000);
            camera.position.z = 4300;
            scene = new THREE.Scene();

            //Sun
            var sun, gun_geom, sun_mat;

            sun_geom = new THREE.SphereGeometry(430, 30,30);
            sun_mat = new THREE.MeshNormalMaterial();
            sun = new THREE.Mesh(sun_geom,sun_mat);
            scene.add(sun);


            // Earth
            var earth, earth_geom, earth_mat;

            earth_geom = new THREE.SphereGeometry(50, 20,20);
            earth_mat = new THREE.MeshNormalMaterial();
            earth = new THREE.Mesh(earth_geom,earth_mat);
            earth.position.x = 2000;
            scene.add(earth);

            render = new THREE.WebGLRenderer();
            render.setSize(W,H);
            container.appendChild(render.domElement);

            var t = 0;

            animate();


            function animate(){
                requestAnimationFrame(animate);

                sun.rotation.y+=0.001;
                earth.position.x = Math.sin(t*0.1) * 2000;
                earth.position.z = Math.cos(t*0.1) * 1700;

                t+= Math.PI/180*2;

                reneder.render(scene, camera);
            }

        </script>



    </body>
</html>

错误发生在第 49 行。

我已经尝试将它移到我的加载函数中,但这只会产生更多错误。

谢谢。

【问题讨论】:

  • 您在您的onload 回调container 之外调用container.appendChild() 尚未设置。如果出现错误,可能是因为您没有使用它移动场景设置代码
  • 代码的基本缩进会告诉你你的问题......

标签: javascript html three.js


【解决方案1】:

你有两个小问题:

  • 为简单起见,在 onload 函数运行之前,您尝试将 appendChild 放入容器中的所有内容都应该在 onload 内。

  • 您在 animate 函数中拼错了 render

这个例子有两个修复:

<html>
  <head>
    <meta charset ="utf8">
    <title> Solar System Project </title>
    <script src = "https://cdnjs.cloudflare.com/ajax/libs/three.js/109/three.min.js"></script>
  </head>
  
  <body>
    
    
    <script>
      
      // Standard Variables / To be changed later.
      var scene, camera, render, container;
      var W,H;
      
      // On load function...
      window.onload = function() {
        container = document.createElement('div');
        document.body.appendChild(container);
        
        W = parseInt(window.innerWidth);
        H = parseInt(window.innerHeight);
        
        
        
        camera = new THREE.PerspectiveCamera(45, W/H, 1, 10000);
        camera.position.z = 4300;
        scene = new THREE.Scene();
        
        //Sun
        var sun, gun_geom, sun_mat;
        sun_geom = new THREE.SphereGeometry(430, 30,30);
        sun_mat = new THREE.MeshNormalMaterial();
        sun = new THREE.Mesh(sun_geom,sun_mat);
        scene.add(sun);
        
        
        // Earth
        var earth, earth_geom, earth_mat;
        earth_geom = new THREE.SphereGeometry(50, 20,20);
        earth_mat = new THREE.MeshNormalMaterial();
        earth = new THREE.Mesh(earth_geom,earth_mat);
        earth.position.x = 2000;
        scene.add(earth);
        
        render = new THREE.WebGLRenderer();
        render.setSize(W,H);
        container.appendChild(render.domElement);
        var t = 0;
        animate();
        
        function animate(){
          requestAnimationFrame(animate);
          
          sun.rotation.y+=0.001;
          earth.position.x = Math.sin(t*0.1) * 2000;
          earth.position.z = Math.cos(t*0.1) * 1700;
          
          t+= Math.PI/180*2;
          
          // `render` now spelled correctly
          render.render(scene, camera);
        }
        
        // everything now within `onload`
      }
        
        
    </script>
    
    
    
  </body>
</html>

【讨论】:

  • 非常感谢!即使 VSC 没有找到那个拼写错误的单词,您是如何找到它的? 0_0
  • 我刚刚使用了 chrome 开发工具 - 修复了 onload 之后,我得到了 Uncaught ReferenceError: reneder is not defined
【解决方案2】:

使用window.onload 的理由为零。这是10-15年前遗留下来的。您会注意到not a single example on the three.js site 站点使用了 window.onload,而threejsfundamentals.org 上的任何示例也没有。

很难让人们停止使用过时的网络内容,因为有很多使用旧方法的例子。在这一点上,我可能已经有 10 年没有使用过onload 了。您不会在任何现代教程中看到它。

重要的是,您的脚本访问的任何 HTML 都会在访问之前出现。

删除 onload 行(或将它们注释掉)它就可以正常工作(除了将render 拼写为reneder 的一个错误。

<html>
    <head>
        <meta charset ="utf8">
        <title> Solar System Project </title>
        <script src = "https://cdn.jsdelivr.net/npm/three@0.110.0/build/three.min.js"></script>
    </head>

    <body>


        <script>

            // Standard Variables / To be changed later.
            var scene, camera, render, container;
            var W,H;

            // On load function...
        //    window.onload = function() {
                container = document.createElement('div');
                document.body.appendChild(container);

                W = parseInt(window.innerWidth);
                H = parseInt(window.innerHeight);

        //    }

            camera = new THREE.PerspectiveCamera(45, W/H, 1, 10000);
            camera.position.z = 4300;
            scene = new THREE.Scene();

            //Sun
            var sun, gun_geom, sun_mat;

            sun_geom = new THREE.SphereGeometry(430, 30,30);
            sun_mat = new THREE.MeshNormalMaterial();
            sun = new THREE.Mesh(sun_geom,sun_mat);
            scene.add(sun);


            // Earth
            var earth, earth_geom, earth_mat;

            earth_geom = new THREE.SphereGeometry(50, 20,20);
            earth_mat = new THREE.MeshNormalMaterial();
            earth = new THREE.Mesh(earth_geom,earth_mat);
            earth.position.x = 2000;
            scene.add(earth);

            render = new THREE.WebGLRenderer();
            render.setSize(W,H);
            container.appendChild(render.domElement);

            var t = 0;

            animate();


            function animate(){
                requestAnimationFrame(animate);

                sun.rotation.y+=0.001;
                earth.position.x = Math.sin(t*0.1) * 2000;
                earth.position.z = Math.cos(t*0.1) * 1700;

                t+= Math.PI/180*2;

                render.render(scene, camera);
            }

        </script>



    </body>
</html>

【讨论】:

  • 哈哈,谢谢你的建议。刚刚意识到我所遵循的教程有点过时了。感谢您的帮助!
【解决方案3】:
window.onload = function() {

    W = parseInt(window.innerWidth);
    H = parseInt(window.innerHeight);

    }

    container = document.createElement('div');
    document.body.appendChild(container);
    camera = new THREE.PerspectiveCamera(45, W/H, 1, 10000);

让您的容器负载脱离 on load 功能。

【讨论】:

  • 感谢您的帮助!
  • 没问题! @LifeOfJona
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2017-01-04
  • 2012-07-15
  • 1970-01-01
  • 2013-06-29
  • 2015-01-26
  • 1970-01-01
相关资源
最近更新 更多