skip to Main Content

I’m trying to insert <hr> between first and second .field-container. Both share the same parent so, element1.parentNode.insertBefore(element2, ...) should work. It’s not working and I’m getting an error instead.

(function() {
    let containers = document.querySelectorAll('.field-container');
    let hr = document.createElement('hr');
    containers[0].parentNode.insertBefore(containers[1], hr);
})();
 

<div>
    <div class="field-container">
        <input placeholder="Field 1" type="text">
        <span></span>
    </div>
    <div class="field-container">
        <input placeholder="Field 2" type="text">
        <span></span>
    </div>
</div>

By appending hr first to the parent element then trying to insert it between both containers fixes the error but the insertion happens at the end, not between.

(function() {
    let containers = document.querySelectorAll('.field-container');
    let hr = document.createElement('hr');
    containers[0].parentNode.appendChild(hr);
    containers[0].parentNode.insertBefore(containers[1], hr);
})();
 

<div>
    <div class="field-container">
        <input placeholder="Field 1" type="text">
        <span></span>
    </div>
    <div class="field-container">
        <input placeholder="Field 2" type="text">
        <span></span>
    </div>
</div>

3

Answers


  1. insertBefore(newNode, referenceNode)
    Since you need the hr before containers[1]
    your newNode or node to be inserted is the hr and the referenceNode or node before which newNode is inserted is the containers[1]

    (function() {
        let containers = document.querySelectorAll('.field-container');
        let hr = document.createElement('hr');
        // containers[0].parentNode.appendChild(hr); this not needed
        containers[0].parentNode.insertBefore(hr, containers[1]);
    })();
    <div>
        <div class="field-container">
            <input placeholder="Field 1" type="text">
            <span></span>
        </div>
        <div class="field-container">
            <input placeholder="Field 2" type="text">
            <span></span>
        </div>
    </div>
    Login or Signup to reply.
  2. Comments

    1. The problem is that this code backwards. Instead of insertBefore(containers[1], hr) do this insertBefore(hr, containers[1])
    2. Another problem is that you are moving a single <hr> instead of inserting two <hr> elements
    3. Below is a cleaner example

    JS

    (function() {
        const [ firstChild, secondChild ] = document.querySelectorAll('.field-container');
        const parent = firstChild.parentElement;
        parent.appendChild( document.createElement('hr') )
        parent.insertBefore( document.createElement('hr'), secondChild );
    })();
    
    Login or Signup to reply.
  3. You does not need any complex js for this, just use CSS

    :root{
      --margin:15px;
    }
    .field-container{
      margin:var(--margin);
      position:relative;
      width:min-content;
    }
    
    .field-container:not(:last-child)::after{
      content:'';
      position:absolute;
      bottom: calc(var(--margin)* -1 / 2);
      left:0;
      width:100%;
      border-bottom:2px solid grey;
    }
    <div class='main'>
        <div class="field-container">
            <input placeholder="Field 1" type="text">
            <span></span>
        </div>
        <div class="field-container">
            <input placeholder="Field 2" type="text">
            <span></span>
        </div>
    </div>
    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search