What's faster DOM Insertion or Manipulation? - javascript

Am I better to move a node I sent down form the server or to insert it?
I'm using jQuery (1.4) but would like to know for both jQuery and JS in general. In this case the node is small with only one child. But what if it were a large list?
What
large list 1 = 200 li nodes
large list 2 = 1000 li nodes
Example:
Insertion:
<div id="wrap">
<div id="box></div>
</div>
$('#box').before($('<ul id="list"><li>...</ul>'));
vs
Manipulation:
<div id="wrap">
<div id="box></div>
</div>
<ul id="list"><li>...</ul>
$('#list').insertBefore($('#box'));

The client is going to spend a lot more time rendering your new items than it will actually putting them into the DOM. I would recommend you remove the #list from the DOM entirely, add the items to it, and then put it back into the DOM. At least for large data sets.
Even then, the repaint could be slow, especially on IE with complex CSS.

The two are the same. If you look at the source, you can see that 'insertBefore' is merely mapped to 'before'.
REF for 'insertBefore': http://gist.github.com/277432#LID4389
REF for 'before': http://gist.github.com/277432#LID4088

One way to improve performance would be to provide a context for the insertion.
When doing $('#list').insertBefore($('#box')); , you should provide the context node if you have it, rather than research the entire tree. Something similar to
var myWapper = getWrapperFromEventOrWhereEverYouMightHaveIt();
//more code doing fancy things here
$(myWrapper, '#list').insertBefore($('#box'));

If your entire list is updated when you get data from the server then you should have a structure that resembles something like this:
<div id="wrap">
<ul id="list"></ul>
<div id="box></div>
</div>
Then you can have all the nodes sent as just a list of li elements and then do something like so:
$("list")[0].innerHTML = xhr.responseText // response text is of form
//<li>item</li><li>item</li>... etc
Tests have shown that innerHTML is faster then append, insert (before and after) etc.
http://www.quirksmode.org/dom/innerhtml.html

Related

Selenium : I have a webpage where two elements have same Xpath, even index doesn't separate them apart

They both get identified when the index is [1], and for index [2] nothing gets identified. The only thing which separates them is that the first popup has display:none, and the other popup has display:block, but they do not get a play in deciding this particular fields because Xpath, because these fields are fetched from some different source.
Alas, these divs even though they have same elements, they have a document attribute so, the Xpath for these don't start with this div, but after the part of the document. I have racked my brain all I could, I could give you a vague idea of how the code looks like below.
The code looks like:
<div name='some-name' style="display:none;">
...
<!document>
<div id='some-id'>
....
<button name='some-name-2'>some-button-name</button>
....
</div>
...
</div>
<div name='some-name' style="display:block;">
...
<!document>
<div is='some-id'>
....
<button name='some-name-2'>some-button-name</button>
....
</div>
...
</div>
So both of their Xpath looks something like:
[id='some-id']/...../button
Giving ([id='some-id']/...../button)[1] fetches both the elements.
Giving ([id='some-id']/...../button)[2] fetches none of them.
Update
I had two iframes in this case, and since I had to switch between them, it was not getting detected. Thanks, I fixed this.
The way your Xpath reads is to find the element with id='some-id' and then find the first or second button within that. If you change it so that the [1] and [2] are placed after the [id='some-id'] rather than at the end of the path you can choose to find the first or second [id='some-id'], and then the button within that element.
Unless the two elements are actually one element, then there will always be XPath expressions that select one and not the other. In fact, there are an infinite number of such expressions. The trick is in finding a good XPath expression, and that depends on how much of the page content is fixed, and how much is variable (if the data is completely fixed, then you don't even need to read it, because you already know everything about it).
I think your inference that the subscripts [1] and [2] don't work is incorrect. It would be useful to know what expressions you actually used, because what you have written in your post:
([id='some-id']/...../button)[1]
is not a valid XPath expression at all.

What's the most efficient way of selecting all html tags that have a specific data-[propriety] regardless of value?

I'm trying to add some kind of on the fly configuration for my require js modules. I declared some html tags like this:
<header data-module='js/views/header'>
</header>
<section data-module='js/views/homepage' data-hash='/'>
</section>
<section data-module='js/views/statistics' data-hash='/statistics'>
</section>
<footer data-module='js/views/footer'>
</footer>
And the jQuery query I use in order to get all elements that have data-module set to something different than null is:
var $viewModules = $('[data-module]');
Is there a more efficient way fo selecting those elements? I never used the data selector in jQuery. Thanks.
Since you don't really have a common tagName or className to use to further reduce the search, your current way would be the most efficient way of doing it.
var $viewModules = $('[data-module]');
This is a hard one, however, seeing you asked about efficiency, using find() on the document seems slightly faster, by up to 10%.
var $viewModules = $(document).find('[data-module]');
See Test-Results
If I had to take a guess to why it is faster I'd say somehow find is optimized behind the scenes but that is just a guess.

Implement HTML5 localStorage

I am aware of the basics of using the HTML5 localStorage using the localStorage.getItem/setItem.
But I am trying to understand how to implement the same on my dynamic page. So here is the scenario:
I have a dynamic page (myPage.jsp) which on initial load calls a Java method (that outputs the HTML string) as below;
<div id="mainContainer">
<div id="parent1"><span>Parent 1</span></div><ul id="child1"></ul>
<div id="parent2"><span>Parent 2</span></div><ul id="child2"></ul>
<div id="parent3"><span>Parent 3</span></div><ul id="child3"></ul>
</div>
Here the number of parent div's are dyanamic based on some logic.
Now on click on any of the parent divs, a Java method is called again (that again outputs the HTML string) for the child innerHTML.
The HTML returned (on click of say Parent 2) is as follows;
<li class="listEle">Child content 1</li>
<li class="listEle">Child content 2</li>
Here the number of "li" elements are dynamic for each parent.
Actually the above HTML is just appended to the mainContainer....So the overall HTML code looks like
<div id="mainContainer">
<div id="parent1"><span>Parent 1</span></div><ul id="child1"></ul>
<div id="parent2"><span>Parent 2</span></div><ul id="child2"><li class="childLi">Child content 1</li><li class="childLi">Child content 2</li></ul>
<div id="parent3"><span>Parent 3</span></div><ul id="child3"></ul>
</div>
Now my question is I want to use localStorage for 2 things:
Storing the initial HTML code (mainContainer) without any child content; AND
Storing the child HTML code as well (which is within the mainContainer)
I am looking at the various ways in which I can do this. I am open to all ideas that you can think of. Just need to consider that all things are dynamic (number of parent divs/child li's, etc)...So need to know how I can handle that dynamic content.
You can store anything you like in localStorage provided the item stored is turned into a string, no problem in your case, and the total storage doesn't exceed 5Mb per site.
You approach could something like this.
When the page loads (use jQuery) check if the base HTML template is there
If not use jQuery to load it and store it in localStorage
use a jQuery selector to select the appropriate element in the current page. This could be the element. And use $(...).html(stored html template); to display the base html.
If you need to insert dynamic values use something like John Resig MicroTemplating to insert variables.

Renumbering divs with Dojo

I found a thread on S.O. similar to what I need here. jQuery removing an element and renumbering remaining elements
The above uses jQuery which we don't use so I'm not sure how to translate this idea of div renumbering to Dojo.
I inherited a massive web project that makes extensive use of Dojo 1.5. I totally dig what I understand of it so far but I have a question.
We have a page with numbered divs that I am successfully able to remove and delete the divs from. What I am needing though are divs in sequential order. Here's an example of what I need to re-div
<div id="filter_9_values_2_div">
<div id="filter_9_values_1_div">
<div id="filter_9_values_4_div">
Ideally in my javascript routine where I delete a div, I'd like to rename these in order so they look like this....
<div id="filter_9_values_1_div">
<div id="filter_9_values_2_div">
<div id="filter_9_values_3_div">
Does anyone have any idea how I would pull this off? I know how to successfully add a new div and make it unique but the idea of rewriting the divs is a complete mystery to me. As always many thanks in advance for the help. Janie.
dojo.query('div').forEach(function(el, index){
dojo.attr(el, "id", "filter_9_values_" + (index + 1) + "_div");
});
You might want to use something more specific as a query rather then using just "div" and if you needed more generic ID rather then having the "filter_9_values_..._div" you'd have to use regexp or split to build the string you want but this should give you the basic idea how to iterate over a collection of DOM elements and perform any action on them you could imagine.

Updating HTML via JSON/AJAX

I've been using JSON to handle AJAX functionality in my rails applications ever since I heard about it, because using RJS/rendering HTML "felt" wrong because it violated MVC. The first AJAX-heavy project I worked on ended up with 20-30 controller actions tied directly to specific UI-behaviors and my view code spread over controller actions, partials and rjs files. Using JSON allows you to keep view specific code in the view, and only talk to view agnostic/RESTful controller actions via AJAX to get needed data.
The one headache I've found from using pure JSON is that you have to 'render' HTML via JS, which in the case of AJAX that has to update DOM-heavy elements, can be a real pain. I end up with long string building code like
// ...ajax
success: function(records){
$(records).each(function(record){
var html = ('<div id="blah">' + record.attr +
etc +
')
})
}
where etc is 10-15 lines of dynamically constructing HTML based on record data. Besides of the annoyance, a more serious draw back to this approach is the duplication of the HTML structure (in the template and in the JS).* Is there a better practice for this approach?
(My motivation for finally reaching out is I am now tasked with updating HTML so complex it required two nested loops of Ruby code to render in the first place. Duplicating that in Javascript seems insane.)
One thing I've considered is loading static partial files directly from the file system, but this seems a bit much.
I like the idea of templating. In my experience it can really clean up that messy string manipulation!
There are many solutions, for example, check out John Resig's (creator of jQuery):
http://ejohn.org/blog/javascript-micro-templating/
I would go with creating an HTML structure that contains placeholders for the elements you'll need to update via AJAX. How much structure it applies will depend on what you're updating; if you know the number of elements you'll have ahead of time, it would be something to the effect of
<div id="article1">
<div id="article1Headline"></div>
<div id="article1Copy"></div>
<div id="article1AuthorInfo"></div>
</div>
<div id="article2">
<div id="article2Headline"></div>
<div id="article2Copy"></div>
<div id="article2AuthorInfo"></div>
</div>
You then write code that references the id of each element directly, and inserts into the .innerHTML property (or whatever syntactically more sugary way jquery has of doing same thing). IMHO, it's not really so terrible to have to assign the contents of each element, the part that you don't want to have to sprinkle through your AJAX functions is the HTML structure itself; in your app the content is volatile anyway.
However, it looks like you might have a list of an unknown number of elements, in that case it may be that you'd need to just put in a placeholder:
<div id="articleList"></div>
In that case I don't really see a way to avoid building the HTML structure in the javascript calls, but a reasonable amount of decomposition of your javascript should help that:
function addArticle( headline, copy, authorInfo, i ){
createDiv( "article" + i + "Headline", headline );
createDiv( "article" + i + "Copy", copy);
createDiv( "article" + i + "AuthorInfo", authorInfo );
}
(not working code of course, but you get the idea,)
You could use the load function in jQuery;
This loads the content of a page into a div like this:
$('#content').load("content/" + this.href.split('#')[1] + ".html", '', checkResponse);
Just make a dynamic view and you are good to go...
Just happened to find exactly what I was looking for: Jaml

Categories