Javascript无法读取属性';价值';空的

Javascript无法读取属性';价值';空的,javascript,html,arrays,Javascript,Html,Arrays,晚安 我遇到了一个Javascript代码段的问题,该代码段可以在JSFIDLE中工作,但不能在实际的HTML中工作 我有一个要点,当调用以下行时,它为什么不起作用: while (list.firstChild) { 此时,list的值仍然为null。所以在这一点上它可能会崩溃和燃烧 然而,为什么它在小提琴中起作用 我知道我可以通过在列表前面添加一个项目来解决这个问题,以避免使其为空,但是,我更好奇的是为什么会出现这种差异(JSFIDLE和html有什么不同)以及如何恢复JSFIDLE功能

晚安

我遇到了一个Javascript代码段的问题,该代码段可以在JSFIDLE中工作,但不能在实际的HTML中工作

我有一个要点,当调用以下行时,它为什么不起作用:

while (list.firstChild) {
此时,list的值仍然为null。所以在这一点上它可能会崩溃和燃烧

然而,为什么它在小提琴中起作用

我知道我可以通过在列表前面添加一个项目来解决这个问题,以避免使其为空,但是,我更好奇的是为什么会出现这种差异(JSFIDLE和html有什么不同)以及如何恢复JSFIDLE功能

这件作品的小提琴

My Test.html不起作用

<script>
var list = document.getElementById('deliveryIdArray');
var names = [];

window.changeText2 = function() {
    var deliveryIdentification = document.getElementById('deliveryIdentification').value;
    names.push(deliveryIdentification);//simply add new name to array;
    //array changed re-render list
    renderList();
}

window.renderList = function(){
    while (list.firstChild) {
        list.removeChild(list.firstChild);
    }
    //create each li again
    for(var i=0;i<names.length;i++){
        var entry = document.createElement('li');
        entry.appendChild(document.createTextNode(names[i]));
        var removeButton = document.createElement('button');
        removeButton.appendChild(document.createTextNode("X"));
        removeButton.setAttribute('onClick','removeName('+i+')');
        entry.appendChild(removeButton);
        list.appendChild(entry);
    }
}


window.removeName = function(nameindex){
    names.splice(nameindex,1);
    //array changed re-render list
    renderList();
}

window.getDeliveries = function(){
    return names;
}
</script>

<html>
    <body>
        <b>Number </b>
        <input id = "deliveryIdentification" name = "deliveryIdentification" type = "text" size = "16" maxlength = "30">

        <!-- Array Area Creation -->
        <input type='button' onclick='changeText2()' value='Add' />

        <ol id="deliveryIdArray">
        </ol>
    </body>
</html>

var list=document.getElementById('deliveryArray');
变量名称=[];
window.changeText2=函数(){
var deliveryIdentification=document.getElementById('deliveryIdentification')。值;
name.push(deliveryIdentification);//只需将新名称添加到数组中;
//数组已更改重新渲染列表
renderList();
}
window.renderList=函数(){
while(list.firstChild){
list.removeChild(list.firstChild);
}
//重新创建每个li
对于(var i=0;i

你的html格式不好。你也可以最后对javascript进行编码,或者你需要
窗口。onLoad
函数来确保加载了塔尔
文档

<html>
    <body>
        <b>Number </b>
        <input id = "deliveryIdentification" name = "deliveryIdentification" type = "text" size = "16" maxlength = "30">

        <!-- Array Area Creation -->
        <input type='button' onclick='changeText2()' value='Add' />

        <ol id="deliveryIdArray">
        </ol>
    </body>
    <script>
        var list = document.getElementById('deliveryIdArray');
        var names = [];

        window.changeText2 = function() {
            var deliveryIdentification = document.getElementById('deliveryIdentification').value;
            names.push(deliveryIdentification);//simply add new name to array;
            //array changed re-render list
            renderList();
        }

        window.renderList = function(){
            while (list.firstChild) {
                list.removeChild(list.firstChild);
            }
            //create each li again
            for(var i=0;i<names.length;i++){
                var entry = document.createElement('li');
                entry.appendChild(document.createTextNode(names[i]));
                var removeButton = document.createElement('button');
                removeButton.appendChild(document.createTextNode("X"));
                removeButton.setAttribute('onClick','removeName('+i+')');
                entry.appendChild(removeButton);
                list.appendChild(entry);
            }
        }


        window.removeName = function(nameindex){
            names.splice(nameindex,1);
            //array changed re-render list
            renderList();
        }

        window.getDeliveries = function(){
            return names;
        }
    </script>
</html>


您的html格式不好。您也可以在最后对javascript进行编码,或者您需要使用
窗口。onLoad
功能确保加载了文档

<html>
    <body>
        <b>Number </b>
        <input id = "deliveryIdentification" name = "deliveryIdentification" type = "text" size = "16" maxlength = "30">

        <!-- Array Area Creation -->
        <input type='button' onclick='changeText2()' value='Add' />

        <ol id="deliveryIdArray">
        </ol>
    </body>
    <script>
        var list = document.getElementById('deliveryIdArray');
        var names = [];

        window.changeText2 = function() {
            var deliveryIdentification = document.getElementById('deliveryIdentification').value;
            names.push(deliveryIdentification);//simply add new name to array;
            //array changed re-render list
            renderList();
        }

        window.renderList = function(){
            while (list.firstChild) {
                list.removeChild(list.firstChild);
            }
            //create each li again
            for(var i=0;i<names.length;i++){
                var entry = document.createElement('li');
                entry.appendChild(document.createTextNode(names[i]));
                var removeButton = document.createElement('button');
                removeButton.appendChild(document.createTextNode("X"));
                removeButton.setAttribute('onClick','removeName('+i+')');
                entry.appendChild(removeButton);
                list.appendChild(entry);
            }
        }


        window.removeName = function(nameindex){
            names.splice(nameindex,1);
            //array changed re-render list
            renderList();
        }

        window.getDeliveries = function(){
            return names;
        }
    </script>
</html>


如果您查看JSFIDLE页面的左侧,您将看到第二个下拉列表设置为“onLoad”

这意味着您的JavaScript在onload事件触发之前不会执行

但是,当您将其作为HTML页面包含时,JavaScript会立即执行。这会中断,因为DOM尚未就绪,因此getElement函数不会返回您期望的值

通过将下拉列表的值更改为“no wrap-in-head”并重新运行,可以在JSFIDLE中重现该问题

关于如何连接JavaScript以在加载DOM后运行,已经有很多讨论

您还可以使用document ready事件,而不是onload事件(它等待图像之类的东西加载),这样做的好处是JavaScipt可能会执行得更快


如果您查看JSFIDLE页面的左侧,您将看到第二个下拉列表设置为“onLoad”

这意味着您的JavaScript在onload事件触发之前不会执行

但是,当您将其作为HTML页面包含时,JavaScript会立即执行。这会中断,因为DOM尚未就绪,因此getElement函数不会返回您期望的值

通过将下拉列表的值更改为“no wrap-in-head”并重新运行,可以在JSFIDLE中重现该问题

关于如何连接JavaScript以在加载DOM后运行,已经有很多讨论

您还可以使用document ready事件,而不是onload事件(它等待图像之类的东西加载),这样做的好处是JavaScipt可能会执行得更快


有一个脚本错误:

Unable to get value of the property 'firstChild': object is null or undefined 
将列表放在
窗口中。renderList
函数将解决此问题

window.renderList = function(){

var list = document.getElementById('deliveryIdArray');

    while (list.firstChild) {
        list.removeChild(list.firstChild);
    }
    //create each li again
    for(var i=0;i<names.length;i++){
        var entry = document.createElement('li');
        entry.appendChild(document.createTextNode(names[i]));
        var removeButton = document.createElement('button');
        removeButton.appendChild(document.createTextNode("X"));
        removeButton.setAttribute('onClick','removeName('+i+')');
        entry.appendChild(removeButton);
        list.appendChild(entry);
    }
}
window.renderList=function(){
var list=document.getElementById('deliveryArray');
while(list.firstChild){
list.removeChild(list.firstChild);
}
//重新创建每个li

对于(var i=0;i存在脚本错误:

Unable to get value of the property 'firstChild': object is null or undefined 
将列表放在
窗口中。renderList
函数将解决此问题

window.renderList = function(){

var list = document.getElementById('deliveryIdArray');

    while (list.firstChild) {
        list.removeChild(list.firstChild);
    }
    //create each li again
    for(var i=0;i<names.length;i++){
        var entry = document.createElement('li');
        entry.appendChild(document.createTextNode(names[i]));
        var removeButton = document.createElement('button');
        removeButton.appendChild(document.createTextNode("X"));
        removeButton.setAttribute('onClick','removeName('+i+')');
        entry.appendChild(removeButton);
        list.appendChild(entry);
    }
}
window.renderList=function(){
var list=document.getElementById('deliveryArray');
while(list.firstChild){
list.removeChild(list.firstChild);
}
//重新创建每个li

对于(var i=0;i这是一个有趣的问题

虽然这是我第一次看到人们把脚本标签放在html标签上

我的web浏览器引擎(webkit)从上到下呈现html

目前,脚本引擎execute
var list=document.getElementById('deliveryDarray');
dom树中不存在dom元素deliveryDarray,因此它找不到该元素

将脚本标记放在文件底部后,您可以看到示例正在愉快地运行

这就是为什么在js习语中,人们喜欢将js放在html文件的底部,
或者您需要在DOMContentLoad事件中连接处理程序,或者使用jquery方式$(function(){};

这是一个有趣的问题

虽然这是我第一次看到人们把脚本标签放在html标签上

我的web浏览器引擎(webkit)从上到下呈现html

目前,脚本引擎execute
var list=document.getElementById('deliveryDarray');
dom树中不存在dom元素deliveryDarray,因此它找不到该元素

将脚本标记放在文件底部后,您可以看到示例正在愉快地运行

这就是为什么在js习语中,人们喜欢将js放在html文件的底部,
或者您需要在DOMContentLoad事件中连接处理程序,或者使用jquery方式$(function(){});

尝试将脚本移动到body标记的末尾,以供初学者使用。如果必须猜测,我会假设JSFIDLE会自动在HTML之后添加脚本标记(这允许在javascript出现之前加载HTML)或者它有某种
window.onload=function(){…}
包装javascript,它做同样的事情。JSFIDLE默认使用DOM就绪处理程序,因此如果它在FIDLE中工作,但在您的站点中不工作,那么您就可以