简体   繁体   中英

can't understand why parentNode.removeChild doesn't work

I am new at this and i am trying to understand few stuff. well, this is my HTML code:

 var counter = 0; function addMore() { counter++; var newFields = document.getElementById('dupDiv').cloneNode(true); newFields.id = 'dupDiv' + counter; newFields.name = 'dupDiv' + counter; newFields.style.display = 'block'; var insertHere = document.getElementById('writeroot'); insertHere.parentNode.insertBefore(newFields, insertHere); document.getElementById('test').value = newFields.name; } window.onload = addMore(); 
 <table id="mainTable" style="width: 700" align="center" dir="rtl"> <tr> <td align="right" colspan="2"> <form method="post" name="f1"> <table align="right" width="600px"> <tbody id="dupDiv" style="display:none;"> <tr> <td class="a1"><input type="text" value="pp" /></td> </tr> <tr> <td class="a1"> <input type="button" onclick="this.parentNode.parentNode.removeChild(this.parentNode);" value="DELETE" /> </td> </tr> </tbody> <span id="writeroot"></span> <tr> <td class="a1"> <input type="button" onclick="addMore()" value="ADD MORE" /> </td> </tr> </table> </form> </td> </tr> </table> 

As you can see, the code is working but it deletes only the button. And i want it to delete all the tbody that is created. ( I mean that i want to delete the specific tbody that the button was clicked at)

And if it is possible i would like an explanation about parentNode in my code and to what element its connected every time.

**This is not the whole code so some element may be missing

Your click handler appears to be this:

onclick="this.parentNode.parentNode.removeChild(this.parentNode);"

this will be the button that was clicked.

this.parentNode will be the containing <td> .

this.parentNode.parentNode will the containing <tr> .

So you're getting the containing row and telling that row to remove the containing <td> . That's what your code instructs the browser to do.

If what you're trying to do is to delete the containing <tbody> element, you need to go up the hierarchy further to get to the actual <tbody> element and to the <table> element itself.

var tbody = this.parentNode.parentNode.parentNode;
tbody.parentNode.removeChild(tbody);

Whenever I see the need for reaching up the parent hierarchy like this with multiple .parentNode references, the code looks brittle to me (it could break easily if slight changes were made to the HTML). For example this code would make if the <input> tag was simply enclosed in a <div> just to facilitate formatting or layout. As such, I try to avoid this type of code. In this case, you could use a small utility function that looks up the parent hierarchy for a parent type of parent and then that would continue to work even if minor changes were made to the HTML. This is probably how I could write this code:

// search up the parent chain for a particular tag type
function closestParentTag(start, tag) {
    var found;
    tag = tag.toLowerCase();
    while (start && start !== document.documentElement && !(found = start.tagName.toLowerCase() === tag)) {
        start = start.parentNode;
    }
    return found ? start : null;
}


function removeCurrentBody(elem) {
    var tbody = closestParentTag(elem, "tbody");
    if (tbody) {
        tbody.parentNode.removeChild(tbody);
    }
}

Also, change:

window.onload = addMore();

to:

window.onload = addMore;

The way you had it was calling the function immediately. Instead, you want to assign a function reference so it can be called LATER.

When, in your code, you refer to a function by named only without parens after it such as:

var foo = addMore;

That is assigning a function reference to the variable foo . You can think of it like a pointer to the function addMore . Nothing is called right now. You've just assigned a pointer to the function to another variable. This is how you pass or assign functions so they can be called later by some other agent.

When, in your code you have parens after a function name, that function is executed immediately.

 var foo = addMore();

This executes addMore() immediately and assigns the return result from that function to the variable foo .

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