开发者问题收集

document.getElementById() - 未定义

2014-02-17
43845

我尝试通过 addRow() 函数调用在表 id="main-table-body" 中添加行,但遇到了 document.getElementById() 检索到 undefined 的问题。

浏览 Stackoverflow 时,我发现了几个类似的问题,但建议的解决方案对我而言不起作用。我猜问题在于函数执行时尚未创建 html 文档。但即使我将脚本放在 body 标签下方,也没有任何反应。如果您能告诉我该怎么做,我将不胜感激。

HTML:

<html>
<head>
    <meta http-equiv="content-type" content="text/html" charset="utf-8">
    <title>Billing system</title>
    <link rel="stylesheet" href="css/style.css" type="text/css">
    <script src="scripts.js"></script>
</head>
<body>

    <div id="header">
        <table id="contractor-info">
            <tbody>
                <tr><td>Contractor</td><td></td></tr>
                <tr><td>Contract No</td><td></td></tr>
                <tr><td>Balance</td><td></td></tr>
                <tr><td>Orders in progress</td><td></td></tr>
            </tbody>
        </table>
    </div>

    <div id="sidebar">
        <div id="sidebar-buttons">
            <input type="button" id="add-contractor" value="Add contractor"><br>
            <input type="button" id="remove-contractor" value="Remove contractor"><br>
            <input type="button" id="edit-contractor" value="Edit contractor"><br>
        </div>
        <div id="sidebar-list">
            <form>
                <select size="50">
                    <option>Contractor #1</option>
                    <option>Contractor #2</option>
                    <option>Contractor #3</option>
                </select>
            </form>
        </div>
    </div>

    <div id="content">
        <input type="button" name="add-order" value="Add order">
        <input type="submit" name="submit-order" value="Submit changes">
        <input type="button" name="add-payment" value="Add payment">
        <input type="submit" name="submit-payment" value="Submit changes">
        <table id="main-table" contenteditable="true">
            <thead>
                <tr>
                    <th>Contract No</th>
                    <th>Order No</th>
                    <th>Order date</th>
                    <th>Order Amount</th>
                    <th>Invoice No</th>
                    <th>Invoice date</th>
                    <th>Invoice amount</th>
                    <th>Cleared</th>
                </tr>
            </thead>
            <tbody id="main-table-body">
                <tr>

                </tr>
            </tbody>
        </table>
        <table id="payments-table">
            <thead>
                <tr>
                    <th>Amount</th>
                    <th>Date of payment</th>
                    <th>Details</th>
                </tr>
            </thead>
            <tbody id="payments-table-body">

            </tbody>
        </table>
    </div>


</body>

<script>
    addRow();
</script>
</html>

JS:

var contentButtons = document.getElementById('content');
var parentElementMainTable = document.getElementById('main-table-body');

contentButtons.onclick = function(event) {
    var event = event || window.event;
    var target = event.target || event.srcElement;
    if(target.getAttribute('name') == 'add-order') {
        addRow();
    }
}

function addRow() {
    var tr = document.createElement('TR');
    tr.innerHTML = '<tr> \
        <td></td> \
        <td></td> \
        <td></td> \
        <td></td> \
        <td></td> \
        <td></td> \
        <td></td> \
        <td></td> \
        </tr>';
    parentElementMainTable.appendChild(tr);
}
3个回答

我认为您必须在 onload 函数中分配值,以确保元素已加载。我还修改了您的 HTML,在按钮上添加 ID,并在结束标记之前添加最后的 /(如果有一天您添加了 XHTML 文档类型):

<input type="button" name="add-order" value="Add order" />

以及 JS 代码:

// List of global variables
var parentElementMainTable = null;
var addOrderBtn = null

// Equivalent to <body onload="yourFunction();">
window.onload = function(){
    // Init globals
    parentElementMainTable = document.getElementById('main-table-body');
    addOrderBtn = document.getElementById("add-order");

    // Add the onclick function to add rows in table
    addOrderBtn.onclick = function(){
        addRow();
    }
}

// Add a row in table
function addRow() {
    var tr = document.createElement('TR');
    tr.innerHTML = '<td></td> \
        <td /> \
        <td /> \
        <td /> \
        <td /> \
        <td /> \
        <td /> \
        <td />';
    parentElementMainTable.appendChild(tr);
}

不要忘记:innerHTML 表示您正在编写的标记内的所有标记。您正在 TR 中附加 TD。无需在 innerHTML 中编写 TR。

编辑:如果您想继续使用 DOM,请尝试使用此 addRow 函数而不是另一个函数(从 DOM createElement 开始,尝试继续使用它):

// Add a row in table
function addRow() {
    // Create the row element
    var tr = document.createElement("tr");

    // Loops on the number of columns in your thead
    // Then creates and append new cell in row
    for (var i = 0; i < parentElementMainTable.offsetParent.tHead.rows[0].cells.length; i++) {
        var td = document.createElement("td");
        tr.appendChild(td);
    }

    // Append the final row to the table
    parentElementMainTable.appendChild(tr);
}
aviel
2014-02-17

我敢打赌,当您创建 parentElementMainTable 时,DOM 尚未准备好,因此当您尝试调用“addRows”时,parentElementMainTable 未定义。

您可以尝试从现有位置删除此变量,然后将其添加到“onclick”方法中吗?

var parentElementMainTable = document.getElementById('main-table-body');

然后您的 addRow 函数将执行以下操作:

function addRow() {
    var tr = document.createElement('TR');
    tr.innerHTML = '<tr> \
        <td></td> \
        <td></td> \
        <td></td> \
        <td></td> \
        <td></td> \
        <td></td> \
        <td></td> \
        <td></td> \
        </tr>';
    document.getElementById('main-table-body').appendChild(tr);
}
Matt
2014-02-17

假设您的代码最初结构如下(编辑之前,我已将其移回 body 内并添加了 script 标记。):

<script>
    addRow();
</script>
<script>
    var contentButtons = document.getElementById('content');
    var parentElementMainTable = document.getElementById('main-table-body');

    contentButtons.onclick = function(event) {...};
    function addRow() {...};
</script>
</body>
</html>

内联脚本按出现顺序执行。当您在自己的 script 标记内调用 addRow() 时,该函数在存在之前被调用,因此出现错误。

实际上,错误消息告诉您“ addRow 未定义。 ”(根据浏览器的不同,也可能是“ addRow 不是函数。 ”)

最简单的修复方法是删除 addRow() 后的结束-开始脚本标记对,这样函数和变量声明将被提升,并且调用即使在“错误”的位置也能正常工作。

但是,最好完全删除第一个 script ,并将 addRow() 移至代码末尾。

另请注意我在您问题下方的帖子中的评论中关于 tr s 的 innerHTML 的内容。

Teemu
2014-02-17