Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Adding complex HTML dynamically to div using Javascript

I have a webpage that list a lot of elements (movies to be specific), the HTML structure of every item is in some way large and complicated (divs, images, links, CSS class, etc).

Firstly I load 100 elements and the user have the option of load the next 100 (this is made using infinite scroll): by now, I make a AJAX petition requesting the another 100 elements and it responds with a HTML text (with all of them loaded) and I just append it to the document.

But, now I don't want to respond with the HTML text, instead of that I want to respond with the 100 elements data in a JSON (I can do that), then, my question is: Which is the best way to add these elements to the document using Javascript?

I know that I can loop over the JSON array and construct every element, but as I said, it's a large HTML structure and I don't really want to create divs and then attach it to another div,set CSS classes, etc with Javascript, because it might get disordered,messy and very large...So, there's a way in javascript to achieve this maybe using something like templates? How can I do that? I just want to get a clean and better code.

The structure of every movie is like this (can I use it like a template?):

 <div data-section="movies" data-movie_id="myid" id="movie-id" class="movie anotherclass">
        <img src="myImageUrl">
        <div class="aCSSclass">
            <div class="aCSSclass">
                <div class="aCSSclass"></div>
                <div class="aCSSclass">
                    <div class="aCSSclass">
                        Movie title
                    </div>

                    <div class="details form-group">
                        <a class="aCSSclass" href="myHref">Details</a>
                        <button onclick="SomeFunction" class="aCSSclass">My button</button>
                        <div class="aCSSclass"><span class="icon star"></span><span class="aCSSclass"></span><span class="aCSSclass"></span><span class="aCSSclass"></span><span class="aCSSclass"></span></div>
                    </div>
                </div>
            </div>
        </div>
    </div>
like image 816
Sredny M Casanova Avatar asked Sep 12 '25 02:09

Sredny M Casanova


1 Answers

The answer is to make a template and then copy the node using cloneNode(). Append all the cloned nodes to a documentFragment to save time on drawing and finally append it to the page.

An approach to this:

var movies = {"movie1" : { "title" : "Die Hard", "imageurl" : "example.com/image.jpg", "details" : "http://example.com", "func" : "functionname" },
             "movie2" : { "title" : "Die Hard 2", "imageurl" : "example.com/image.jpg", "details" : "http://example.com", "func" : "functionname" },
             "movie3" : { "title" : "Die Hard With 3", "imageurl" : "example.com/image.jpg", "details" : "http://example.com", "func" : "functionname" }
             };

function functionname()
{
  alert("NYI");
}

var keys = Object.keys(movies); //get the keys.
var docFrag = document.createDocumentFragment();
for (var i = 0; i < keys.length; i++)
{
  var tempNode = document.querySelector("div[data-type='template']").cloneNode(true); //true for deep clone
  tempNode.querySelector("div.title").textContent = movies[keys[i]].title;
  tempNode.querySelector("img").src = movies[keys[i]].imageurl;
  tempNode.querySelector("button").onclick = window[movies[keys[i]].func];
  tempNode.querySelector("a").href = movies[keys[i]].details;
  tempNode.style.display = "block";
  docFrag.appendChild(tempNode);

}
document.body.appendChild(docFrag);
delete docFrag;
<!-- template --> 
<div style="display: none" data-type="template" data-section="movies" data-movie_id="myid" id="movie-id" class="movie anotherclass">
        <img src="myImageUrl">
        <div class="aCSSclass">
            <div class="aCSSclass">
                <div class="aCSSclass"></div>
                <div class="aCSSclass">
                    <div class="aCSSclass title">
                        Movie title
                    </div>

                    <div class="details form-group">
                        <a class="aCSSclass" href="myHref">Details</a>
                        <button onclick="SomeFunction" class="aCSSclass">My button</button>
                        <div class="aCSSclass"><span class="icon star"></span><span class="aCSSclass"></span><span class="aCSSclass"></span><span class="aCSSclass"></span><span class="aCSSclass"></span></div>
                    </div>
                </div>
            </div>
        </div>
    </div>

This is just an example, not based upon your actual JSON. However you can easily clone a template and then fill in the values.

Use

  • document.querySelector
  • document.querySelectorAll
  • document.createDocumentFragment
  • Element.cloneNode(bool)
like image 78
Mouser Avatar answered Sep 13 '25 14:09

Mouser