简体   繁体   中英

How can I reference an element after I have appended it using javascript not jquery

I am doing some basic javascripting and am creating a 3 column table created by javascript sourced from an xml. The table is created by appending all the data in rows via javascript.

The first column has an input checkbox, created via javascript, that if ticked fetches a price from the third column on that row and adds all the prices of the rows selected to give a price total.

The problem I am having is I don't seem to be able to reference the appended information to obtain the information in the related price column (third column).

I have attached both the function I am using to create the table which is working and the function I am using to try and add it up which isnt working.

I found the following two articles Getting access to a jquery element that was just appended to the DOM and How do I refer to an appended item in jQuery? but I am using only javascript not jquery and would like a javascript only solution if possible.

Can you help? - its just the calculateBill function that isn't working as expected.

Thank you in advance

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();

When you do x.appendChild(y) , y is the DOM node that you are appending. You can reference it via javascript either before or after appending it. You don't have to find it again if you just hang on to the DOM reference.

So, in this piece of code:

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

createInput is the input element. You can reference it with javascript at any time, either before or after you've inserted it in the DOM.

In this piece of code:

        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);

You're creating a <td> element and putting a price into it. createTD3 is that particular <td> element.


If you want to be able to find that element sometime in the future long after the block of code has run, then I'd suggest you give it an identifying id or class name such that you can use some sort of DOM query to find it again. For example, you could put a class name on it "price" and then be able to find it again later:

        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);

Then, you could find all the price elements again with:

tbody.querySelectorAll(".price");

Assuming tbody is the table where you put all these elements (since that's what you're using in your enclosed code). If the table itself had an id on it like id="mainData" , then you could simply use

document.querySelectorAll("#mainData .price")

to get all the price elements.


FYI, here's a handy function that goes up the DOM tree starting from any node and finds the first node that is of a particular tag type:

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
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM