1

I would like to insert new <tr> after every existing <tr>. My function :

var element = document.querySelector('tr.cart-item');
var newElement = document.createElement('tr');
newElement.className = "tr-spacer";
var elementParent = element.parentNode;
elementParent.insertBefore(newElement, element.nextSibling);

but it insert <tr> only after first <tr>, is it possible insert <tr> after every existing <tr>? I also tried querySelectorAll or insertRow but it does not seem to work. Thanks you

Gore
  • 163
  • 2
  • 16
  • 1
    Use `.querySelectorAll()` instead of `.querySelector()` ? – Pointy Jul 06 '18 at 13:42
  • 1
    This sounds like [an X/Y problem](https://meta.stackexchange.com/questions/66377/what-is-the-xy-problem). Whatever you want to do with "spacer" `tr`s, you probably want to do with CSS instead. :-) – T.J. Crowder Jul 06 '18 at 13:43

3 Answers3

1

It works just fine with querySelectorAll. You didn't show your code trying to use that, but you'd have a loop:

var list = document.querySelectorAll('tr.cart-item');
for (var i = 0; i < list.length; ++i) {
    var element = list[i];
    var newElement = document.createElement('tr');
    newElement.className = "tr-spacer";
    element.parentNode.insertBefore(newElement, element.nextSibling);
}

or on modern browsers (or with a polyfill, which is trivial; more in this answer):

document.querySelectorAll('tr.cart-item').forEach(function(element) {
    var newElement = document.createElement('tr');
    newElement.className = "tr-spacer";
    element.parentNode.insertBefore(newElement, element.nextSibling);
});

or (again, modern browsers):

for (const element of document.querySelectorAll('tr.cart-item') {
    const newElement = document.createElement('tr');
    newElement.className = "tr-spacer";
    element.parentNode.insertBefore(newElement, element.nextSibling);
}
T.J. Crowder
  • 1,031,962
  • 187
  • 1,923
  • 1,875
1

You'll have to loop through your <tr> tags.

First select them all using querySelectorAll instead of querySelector.

Then loop through them and add a new one after each.


As @T.J. Crowder pointed out in the comments, notice how there's an added step to check if the current <tr> has a next sibling by checking if nextElementSibling is truthy.

let lines = document.querySelectorAll('tr');

for(let line of lines){
  let newLine = document.createElement('tr');
  newLine.innerText = 'Inserted';
  if(line.nextElementSibling) line.parentNode.insertBefore(newLine, line.nextElementSibling);
}
<table>
<tr><td>1</td></tr>
<tr><td>2</td></tr>
<tr><td>3</td></tr>
<tr><td>4</td></tr>
</table>
Zenoo
  • 12,670
  • 4
  • 45
  • 69
0

You need to get all elements matching selector using querySelectorAll and then either in naked for loop or using Array.prototype.forEach create ad insert new tr after each element:

[].forEach.call(document.querySelectorAll('tr.cart-item'), function (element) {
  var newElement = document.createElement('tr');
  newElement.className = "tr-spacer";
  element.parentNode.insertBefore(newElement, element.nextSibling);
});
<table>
  <tr class="cart-item">
    <td>First</td>
  </tr>
  <tr class="cart-item">
    <td>Second</td>
  </tr>
  <tr class="cart-item">
    <td>Third</td>
  </tr>
</table>
Andrzej Smyk
  • 1,684
  • 11
  • 21