【问题标题】:How can I reference an element after I have appended it using javascript not jquery使用javascript而不是jquery附加元素后如何引用它
【发布时间】:2014-04-02 21:27:57
【问题描述】:

我正在做一些基本的javascripting,并正在创建一个由来自xml 的javascript 创建的3 列表。该表是通过通过 javascript 将所有数据附加到行中来创建的。

第一列有一个输入复选框,通过 javascript 创建,如果勾选该复选框,则从该行的第三列获取价格,并将所选行的所有价格相加以得出总价格。

我遇到的问题是我似乎无法参考附加信息来获取相关价格列(第三列)中的信息。

我已经附加了我用来创建正在运行的表的函数和我用来尝试将它添加到不工作的函数。

我找到了以下两篇文章 Getting access to a jquery element that was just appended to the DOMHow do I refer to an appended item in jQuery?,但我只使用 javascript 而不是 jquery,如果可能的话,我想要一个仅使用 javascript 的解决方案。

你能帮忙吗? - 它只是未按预期工作的 calculateBill 函数。

提前谢谢你

function addSection() {
    var section = xmlDoc.getElementsByTagName("section");

    for (i=0; i < section.length; i++) {

        var sectionName = section[i].getAttribute("name");
        var td = document.createElement("td");
        td.setAttribute("colspan", "3");
        td.setAttribute("class","level");
        td.appendChild(document.createTextNode(sectionName));

        var tr = document.createElement("tr");
        tr.appendChild(td);
        tbody.appendChild(tr);

        var server = section.item(i).getElementsByTagName("server");

        for (j=0; j < server.length; j++) { 
            var createTR = document.createElement("tr");
            var createTD = document.createElement("td");
            var createInput = document.createElement("input");
            createInput.setAttribute("type", "checkbox");
            createInput.setAttribute("id", "checkInput");
            createTD.appendChild(createInput);
            createTR.appendChild(createTD);

            var item = server[j].getElementsByTagName("item")[0].innerHTML;
            var createTD2 = document.createElement("td");
            var createText = document.createTextNode(item);
            createTD2.appendChild(createText);
            createTR.appendChild(createTD2);

            var price = server[j].getElementsByTagName("price")[0].innerHTML;
            var createTD3 = document.createElement("td");
            var createText2 = document.createTextNode("£" + price);
            createTD3.appendChild(createText2);
            createTR.appendChild(createTD3);
            tbody.appendChild(createTR);
        }
    }
}

onload = addSection();

function calculateBill() {
    var finalBill = 0.0;
    var checkBox = document.getElementById("checkInput");
    for (i=0; i < checkBox.length; i++) {
        if (checkBox[i].checked) {
            var parentTR = checkBox[i].parentNode;
            var priceTD = parentTR.getElementsByTagName('td')[2];
            finalBill += parseFloat(priceTD.firstChild.data);
        }
    }
    return Math.round(finalBill*100.0)/100.0;
}

var button = document.getElementById("button");
button.onClick=document.forms[0].textTotal.value=calculateBill();

【问题讨论】:

    标签: javascript append


    【解决方案1】:

    当您执行x.appendChild(y) 时,y 是您要附加的 DOM 节点。您可以在添加之前或之后通过 javascript 引用它。如果您只是挂在 DOM 引用上,则不必再次找到它。

    所以,在这段代码中:

            var createInput = document.createElement("input");
            createInput.setAttribute("type", "checkbox");
            createInput.setAttribute("id", "checkInput");
            createTD.appendChild(createInput);
    

    createInput 是输入元素。您可以随时使用 javascript 引用它,无论是在将其插入 DOM 之前还是之后。

    在这段代码中:

            var price = server[j].getElementsByTagName("price")[0].innerHTML;
            var createTD3 = document.createElement("td");
            var createText2 = document.createTextNode("£" + price);
            createTD3.appendChild(createText2);
            createTR.appendChild(createTD3);
            tbody.appendChild(createTR);
    

    您正在创建一个&lt;td&gt; 元素并为其添加价格。 createTD3 是特定的 &lt;td&gt; 元素。


    如果您希望能够在代码块运行很久之后的某个时间找到该元素,那么我建议您给它一个标识 id 或类名,以便您可以使用某种 DOM 查询再次找到它。例如,您可以在上面加上一个类名"price",然后以后可以再次找到它:

            var price = server[j].getElementsByTagName("price")[0].innerHTML;
            var createTD3 = document.createElement("td");
            createTD3.className = "price";
            var createText2 = document.createTextNode("£" + price);
            createTD3.appendChild(createText2);
            createTR.appendChild(createTD3);
            tbody.appendChild(createTR);
    

    然后,您可以再次找到所有价格元素:

    tbody.querySelectorAll(".price");
    

    假设 tbody 是您放置所有这些元素的表(因为这就是您在封闭代码中使用的内容)。如果表本身有一个像id="mainData" 这样的id,那么你可以简单地使用

    document.querySelectorAll("#mainData .price")
    

    获取所有价格元素。


    仅供参考,这是一个方便的函数,它从任何节点开始沿着 DOM 树向上并找到属于特定标记类型的第一个节点:

    function findParent(node, tag) {
        tag = tag.upperCase();
        while (node && node.tagName !== tag) {
            node = node.parentNode;
        }
        return node;    
    }
    
    // example usage:
    var row, priceElement, price;
    var checkboxes = document.querySelectorAll(".checkInput");
    for (var i = 0; i < checkboxes.length; i++) {
        // go up to the parent chain to find out row
        row = findParent(checkboxes[i], "tr");
        // look in this row for the price
        priceElement = row.querySelectorAll(".price")[0];
        // parse the price out of the price element
        price = parseFloat(priceElement.innerHTML.replace(/^[^\d\.]+/, ""));
        // do something here with the price
    }
    

    【讨论】:

    • 我明白你在说什么。我希望做的是找到所选输入字段的标识,向上到父 TR,然后找到该行中的第三个 TD。这有意义还是我这样做是在倒退?
    • @EamonYates - 看看我在答案中添加了什么。最好附加一个已知的类名并使用它来查找它,而不是计算行或列。但是,如果您在表中有一些参考并想找到与该参考对应的价格,那么您的一般概念是正确的。您将父链向上移动到一个共同的父级(通常是表中的一行),然后使用tr.querySelectorAll() 之类的东西在该行中查找您要查找的元素。我强烈建议您在不同的元素上使用类名,以便于查找。
    • 谢谢 jfriend00 我明白你在说什么,也刚刚意识到我的复选框使用的是 ID 而不是类。您认为我的目标是获取将通过选中的输入复选框选择的特定行是正确的。出于某种原因,我的代码似乎无法识别我在我的 javascript 代码中设置的类或 ID,但在我的 html 中识别它。我不知道为什么?
    • @EamonYates - id 在文档中必须是唯一的,因此如果您有多个具有相同 id 的,那将不起作用。有没有办法更具体地谈论您遇到问题的特定代码/HTML,而不是这样的通用对话?我正在考虑以“此 DOM 元素上发生一个事件”开头的描述,然后我想找到这个相关的 DOM 元素,这是生成的 HTML 的样子,这是我正在尝试但不起作用的代码.
    • 我可以尽力而为,如果我不清楚,请随时深入研究。感谢您在这方面的帮助。
    猜你喜欢
    • 2013-08-05
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-03-25
    • 2021-06-20
    • 2012-11-04
    • 1970-01-01
    相关资源
    最近更新 更多