Reputation: 417592
Here's a simple HTML <table>
with 2 rows, each row having links to move the row up/down:
<table border=1>
<tr>
<td>Row A</td>
<td>
<a href="javascript:void(0)" onclick="up(this)">Up</a>
<a href="javascript:void(0)" onclick="down(this)">Down</a>
</td>
</tr>
<tr>
<td>Row B</td>
<td>
<a href="javascript:void(0)" onclick="up(this)">Up</a>
<a href="javascript:void(0)" onclick="down(this)">Down</a>
</td>
</tr>
</table>
<script>
function up(link) {
var row = link.parentNode.parentNode;
var prevRow = row.previousSibling;
if (prevRow != null) {
row.parentNode.insertBefore(row, prevRow);
}
}
function down(link) {
var row = link.parentNode.parentNode;
var nextRow = row.nextSibling;
if (nextRow != null) {
row.parentNode.insertBefore(nextRow, row);
}
}
</script>
Why is it that clicking on Down
link of the first row does nothing at first (no errors), but works for second click? Similarly clicking on the Up
link of the 2nd row does nothing at first, but starts working afterwards?
Moreover, if I click on a link that cannot be executed (e.g. Up
of the first row or Down
of the last row), then the other link of the same row that should work (Down
of the first row) doesn't work on subsequent click, but works if clicked again?
What should I do / change so that links work on first click as they should be?
Upvotes: 0
Views: 61
Reputation: 511
Because whitespace is also a node previousSibling
/ nextSibling
returns #text
on your first call to any of your functions, after that it fixes itself. So to get it to work the first time change to previousElementSibling
/ nextElementSibling
<table border=1>
<tr>
<td>Row A</td>
<td>
<a href="javascript:void(0)" onclick="up(this)">Up</a>
<a href="javascript:void(0)" onclick="down(this)">Down</a>
</td>
</tr>
<tr>
<td>Row B</td>
<td>
<a href="javascript:void(0)" onclick="up(this)">Up</a>
<a href="javascript:void(0)" onclick="down(this)">Down</a>
</td>
</tr>
</table>
<script>
function up(link) {
var r = link.parentNode.parentNode;
var rp = r.previousElementSibling;
if (rp != null) {
r.parentNode.insertBefore(r, rp);
}
}
function down(link) {
var r = link.parentNode.parentNode;
var rn = r.nextElementSibling;
if (rn != null) {
r.parentNode.insertBefore(rn, r);
}
}
</script>
Upvotes: 3