4

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>
6
  • Look into the document fragment. Commented Jan 3, 2017 at 15:42
  • 1
    You can either generate all manually (using dom), clone a previous movie and change the data accordingly (jquery .clone()) or use a template library like handlebars Commented Jan 3, 2017 at 15:43
  • @juvian I like that way (cloning) in this way I can only put the structure hidden and the copy->fill it-> append it Thank you! Commented Jan 3, 2017 at 15:50
  • Can you post the javascript part? do you use innerHTML? Commented Jan 3, 2017 at 15:52
  • @pdem the Javascript part is only a ajax petition, then I receive the HTML and append it to the correspondant div.But now I want to receive a JSON not a HTML. By now it's the only thing that I have, nothing specific of the project Commented Jan 3, 2017 at 16:01

1 Answer 1

6

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)
Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.