When I released the panorama.js library earlier this month I mentioned it was written to NOT depend on jQuery. Eliminating my need to depend on jQuery is an overall goal of mine. The primary reason is the pursuit of better app performance and a shift to focusing on mobile. Up to this point jQuery has grown extremely large for two reasons, backward compatibility with browsers like Internet Explorer 7 and a large set of utility functions. That will change to a large degree with the pending jQuery 2.0 release as they remove many legacy browsers support. And don't get me wrong I am a big jQuery fanboy, but I am finding it easier and easier to accomplish tasks without jQuery and my applications are better.
Something jQuery has been extremely useful to me is inserting large chunks of DOM or HTML into a web page's DOM tree. Way back when I first started using jQuery this involved several lines to build a string of structured HTML elements and content. But eventually I found, or the jQuery team added I am not sure which is true at this point, the ability to pass in a markup string to jQuery that could then be inserted using one of the manipulation methods like appendTo, before, after, prepend, etc. You can find these and other DOM manipulation methods in the jQuery API documentation.
As I am getting closer to 'finishing' my Single Page Application libraries I am quickly purging jQuery dependencies. One task I needed to accomplish was manipulating the DOM as I inserted and removed DOM nodes for each view. Traditionally I used the jQuery techniques described above, so I needed to figure out how to do this using the browser's native APIs. Fortunately this much easier than it seems.
Somewhere in the past year I read and article or two about using the document.CreateDocumentFragment method. This is a pretty useful tool because it allows you to create a section of markup, or DocumentFragment, and manipulate it before it is inserted in the page's DOM. This is extremely helpful because most manipulations of DOM elements cause the browser to reflow and repaint the layout, which you want to reduce to a minimum.
Normally when using CreateDocumentFragment you would use the document.CreateElement and other manipulation methods to build and complete the fragment. But I knew there had to be a better way. I started by rummaging through the jQuery source and while I could understand what they were doing, it just seemed like way too much code to accomplish a specific task. One thing you learn when writing an abstraction library like jQuery is you need to architect methods to account for numerous scenarios, many of which are what I call edge cases that just take up a lot of CPU cycles when not actually needed.
So I went on a safari to find a better way to leverage DocumentFragments. Thanks to a StackOverflow question and answer I had my method. The answer was exactly what I needed and extremely concise. It consisted of a single helper method, called create that accepts a single string parameter, which of course is the HTML you want to insert in the DOM.
The big problem this function solves that I wanted to overcome is not adding a wrapping element around the desired markup. You can't just add a string of markup to a fragment, you have to add an HTML node. The function actually creates a wrapping DIV element and adds the markup string to it using the DIV's innerHTML property. At this point you have a valid DIV element with child elements, assuming the string you passes has HTML in it.
varfrag = document.createDocumentFragment(),
temp = document.createElement(
temp.innerHTML = htmlStr;
Now you need to add the DIV's childNodes to the DocumentFragment. We don't want the DIV we created so instead the function loops through the DIV's childNodes and adds them to the DocumentFragment. Now the HTML string you want to add to the page's DOM structure should be a valid node/nodeList that can be added to the DOM as you intended.
The function returns the DocumentFragment and it can be added using one of the node methods like appendChild.
// You can use native DOM methods to insert the fragment:
I created a jsFiddle to demonstrate how to accomplish all this.
Like I said one of the reasons why I am learning to use the browser's native APIs is they are much more performant than using jQuery. So I created a simple little test to compare the two techniques on jsPerf. As you can see the native technique is 10s of thousands of times faster than using jQuery.
So I hope you find this technique useful. You don't have to be scared of backward compatibility issues because the CreateDocumentFragment function has been around since Internet Explorer 6.