skip to Main Content
var fragment = [];

function create1() {
  for (var i = 0; i < 5; i++) {
    x = document.createElement('div');
    x.className = "di";
    x.textContent = 'Change background color';
    fragment[i] = document.createDocumentFragment();
    console.log(fragment[i]);
    fragment[i].append(x.cloneNode(true));
  }

  document.body.append(fragment);
}
create1();
.di {
  border: solid green 2px;
  margin-right: 65em;
  margin-top: 4px;
}

I created an array of document fragment but I am unable to render them to the HTML DOM properly, please help

3

Answers


  1. Your fragment variable is an array, not a document node. You must spread the argument in the append call –

    var fragment = [];
    
    function create1() {
      for (var i = 0; i < 5; i++) {
        x = document.createElement('div');
        x.className = "di";
        x.textContent = 'Change background color';
        fragment[i] = document.createDocumentFragment();
        fragment[i].append(x);
      }
      
      document.body.append(...fragment) // ✅ spread fragment
    }
    
    create1();
    .di {
      border: solid green 2px;
      margin-right: 65em;
      margin-top: 4px;
    }

    But don’t stop there –

    ❌ leaked global variable x
    ❌ unnecessary global fragment
    ❌ functions don’t take arguments or return values
    ❌ poor function composition, separate concerns

    function div(className = "", textContent = "") { // ✅ parameters
      const e = document.createElement("div")
      e.className = className
      e.textContent = textContent
      return e // ✅ use return value 
    }
    
    function fragment(...children) { // ✅ separate concerns
      const e = document.createDocumentFragment()
      e.append(...children)
      return e // ✅
    }
    
    function create(count = 0) { // ✅ use function parameters
      const fragments = [] // ✅ localize variables to functions
      for (let i = 0; i < count; i++) {
        fragments.push(
          fragment(div("di", "change background color"))
        )
      }
      return fragments // ✅ use return values
    }
    
    document.body.append(...create(3)) // ✅ functions are flexible
    .di {
      border: solid green 2px;
      margin-right: 65em;
      margin-top: 4px;
    }

    I agree with @EmielZuurbier. It doesn’t make sense to use fragments that contain a single child. It would be better to either append each div to the body directly or append all divs to a fragment and finally append the single fragment to the body. Here’s what that would look like –

    function div(className = "", textContent = "") {
      const e = document.createElement("div")
      e.className = className
      e.textContent = textContent
      return e
    }
    
    function fragment(...children) { 
      const e = document.createDocumentFragment()
      e.append(...children)
      return e
    }
    
    function create(count = 0) {
      const divs = [] // ✅ array of divs
      for (let i = 0; i < count; i++) {
        divs.push(
          div("di", "change background color")
        )
      }
      return fragment(...divs) // ✅ return single fragment
    }
    
    document.body.append(create(3)) // ✅ append single fragment
    .di {
      border: solid green 2px;
      margin-right: 65em;
      margin-top: 4px;
    }
    Login or Signup to reply.
  2. It doesn’t make a lot of sense to create a DocumentFragment per element: a DocumentFragment can be very useful to collect multiple elements into a single group to append them all at once. Otherwise you could just append the element to the body directly without using the document fragment and get the same result. See the result below.

    function create1() {
      const fragment = document.createDocumentFragment();
      const x = document.createElement('div');
      x.className = "di";
      x.textContent = 'Change background color';
        
      for (let i = 0; i < 5; i++) {
        fragment.append(x.cloneNode(true));
      }
    
      document.body.append(fragment);
    }
    
    create1();
    .di {
      border: solid green 2px;
      margin-right: 65em;
      margin-top: 4px;
    }
    Login or Signup to reply.
  3. I’m not sure you’ll need an array here. Here’s a utility function creating and appending [n] elements (using a shorter syntax for element creation) to document.body.

    function create1(n) {
      const elem = Object.assign(
        document.createElement(`div`),
        { className: `di`, textContent: `change background color` } );
      const elems = Array.from({length: n}, _ => elem.cloneNode(true));  
      document.body.append(...elems);
    }
    create1(5);
    .di {
      border: solid green 2px;
      max-width: 200px;
      margin-top: 4px;
    }
    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search