Replace whole DOM in javascript - javascript

I need to implement undo-redo functionality in my project. But it is very complex and every change affects on many elements. I think saving and restoring whole page will be the best choice. But i have some problems with missing .data() params of DOM elements. I use next functions:
// save
var documentCopy = document.documentElement.cloneNode(true);
// restore
document.replaceChild(
documentCopy,
document.documentElement
);
How I can save and restore whole DOM with saving jQuery.data() of elements?

The trivial thing that I would try is using jQuery's clone instead. Be sure to use it with two true parameters, but be careful as this may be very very slow. Are you sure this is the only way to achieve what you want? Can't you replace a smaller portion of the document?
Note that this doesn't seem to work well with document.documentElement, and that using it with the document's body seems to lose the data on the original elements (say what?). Here's a small test.

Related

fastest search on elements in html

i have a page with many divs on which i need to implement some JavaScript functions. Is there a way to tell the browser to sort all divs by for example id so that I can find quickly an element.I generally don't know how browsers handle searching of elements, is there some sorting or not on major browsers firefox, chrome, ie? How do elements get indexed?
Every browser already holds a such an index on id's and classes for use with, for example, css.
You shouldn't worry about indexing the DOM, it's been done and ready for use.
If you want to hang events on elements, just do so. Either by use of 'document.getElementById(id) or document.getElementsByClassName(class) (that last one might bump into IE-issues)
I think jquery will help you in that case...
or with simple javascript you can getElementById, or getElementsByTagName
the browsers creates a tree like structure named DOM (Document Object Model), with the root being the html tag for example, then it's children, their children's children, etc..
There are functions that let's you access the DOM and find the required elements. But this is done in the browser's inner implementation. You can not change how it handles the page elements, just use the browser's API to locate elements

Is using document.getElementsByTagName() a good idea or bad idea?

Ok so I am wondering which way is the preffered way to access a certain tag.
Is it better to use..
document.getElementById('myDiv').innerHTML
or this way..
document.getElementsByTagName('div')[0].innerHTML
// I use [0] because it is the first div in the body
My guess is that it doesn't matter at all which way i do it.
Absolutely the getElementById is better in that case. It's much faster.
Update
Here is a test about JavaScript selector functions. http://jsperf.com/queryselectorall-vs-getelementbyid/6
There are not many articles about performance of JavaScript selector functions. Instead there are many articles about jQuery selector performance like this or this. jQuery uses native JavaScript selector functions internally, so you can guess from these articles.
They do completely different things. If you want to get a particular element and you always need to get the same element, use an id. If you want to get a particular element based on what place it has in the DOM, then use the it's position in the getElementsByTagName NodeList.
If you want to get a particular element and you get it by index, then your script will be brittle - if you change your DOM structure later, you will need to change your code. If you want to get an element by it's position, then using an ID will require you to add redundant attributes to your markup.
Also, it is important to note that getElementById returns a DOM node, while getElementsByTagName returns a NodeList. To quote MDC on the properties of a NodeList:
NodeList is live, meaning that it updates itself automatically to stay in sync with the DOM tree without having to call document.getElementsByTagName again.
So if you need a particular element, getElementById will be significantly faster.
For readability purposes, it depends on what you're trying to do.
Is your intent to get the first div, which just happens to be named myDiv? if yes, then I think getElementsByTagName is better, as it would more express what you're trying to do.
Or is your intent to get myDiv, which just happens to be the first div? If that's the case, then use getElementById.
All other considerations aside, go with the one that expresses your intent.

Caching / moving markup in the DOM for reuse

Bit of a weird one - bound to see some head scratching and wrinkled noses on here.
Currently developing this scrollable timeline that has users incrementally loading new modules of HTML via AJAX as they pan / scroll, so before long they can end up with quite a bit of markup on the page. As they "zoom" though (i.e. shift the scale of the timeline's X-axis), I'm having to destroy that newly generated markup and establish a new frame of reference into which new modules can be loaded.
Without getting too deep into the how and why of the timeline's inner workings, I'd like to know if there's a way in JavaScript / jQuery to cache or temporarily "move" (not just remove and rewrite) chunks of markup you've already loaded into the DOM.
I have a feeling this is wishful thinking on my part, but if anyone's put some thought into this before, I'd be interested to hear. Thanks in advance.
Instead of using .empty() (which it sounds like is what you're doing), you can use .detach(). The caveat with using .detach() is that you have to store a reference to the detached element(s) so you can, say .append() it later. Like this:
...
var elementCache = [];
...
// later
elementCache.push($('some-selector-here').detach());
...
// later still
$('some-other-selector').append(elementCache.pop());

appendChild in IE6/IE7 does not work with existing elements

I have a div that needs to be moved from one place to another in the DOM. So at the moment I am doing it like so:
flex.utils.get('oPopup_About').appendChild(flex.utils.get('oUpdater_About'));
But, IE, being, well, IE, it doesn't work. It works all other browsers, just not in IE.
I need to do it this way as the element (div) 'oUpdater_About' needs to be reused as it is populated over and over.
So i just need to be able to move the div around the DOM, appendChild will let this happen in all browsers, but, IE.
Thanks in advance!
You have to remove the node first, before you can append it anywhere else.
One node cannot be at two places at the same time.
var node = flex.utils.get('oUpdater_About')
node.parentNode.removeChild(node);
flex.utils.get('oPopup_About').appendChild(node);
make sure to clone the oUpdater_About (with node.cloneNode(true))
this way you get a copy and can reuse the dom-snippet as often as you want (in any browser)
This post tends to suggest that there is indeed a problem with appendChild with respect to this:
http://metadeveloper.blogspot.com/2007/01/ie-7-appendchild-bug.html
Have you tried cloning it, removing it, then inserting the clone instead?
James

How efficient is element.cloneNode(true) (deep clone)?

I'm building the HTML code within an XML DOM object to be used as the contents of the innerHTML of a div element using an XSL template. Traditionally we create a new XML DOM document and add the input parameters as XML Elements for the transform via javascript. This is all very time-consuming as we are basically hand picking the data from another XML document that represents our current account and copying the data into a transient XML DOM document.
What I'd like to do is clone the relevant node of the account document (i.e. customer info) and use it as the basis for the transform. I don't want to use the account document directly as I'd like to be able to add transform specific input, without making changes to the account object.
How efficient is using .cloneNode(true) for a desired node of about typically less than 200 elements from a document of typically 2000+ elements? The target platform is IE6 with no external tools (i.e. ActiveX).
CloneNode is pretty efficient but it will be consuming more memory doing it that way.
Another approach to consider is to use a Template object and a processor, pass your additional/changed data as parameters to the processor and the element that you would have otherwise cloned as the input element. This approach would require fairly significant mods the XSL though.
IE will fail on certain things.
e.g. checked radio/checkboxes will not be checked when you add your copy to the DOM.
Example:
http://webbugtrack.blogspot.com/2008/03/bug-199-cant-clone-form-element-in-ie.html
http://webbugtrack.blogspot.com/2007/08/bug-242-setattribute-doesnt-always-work.html
To see what IE will actually return, try replacing the url with this in the Address Bar of one of your pages, and press enter.
javascript:'<xmp>'+window.document.body.outerHTML+'</xmp>';
If you are happy with the results, great!, but I think you'll end up less than satisfied at what IE returns (both in the DOM, and this "string" value equivelant.
If you don't need form-elements, cloneNode is a real reliable tool ...
-- and in inserting ajax-data it is incredible in efficiency ...
However, as especially IE has a history of having problems with name-attributes, it is inconvenient to address any of these if you insert data ...
-- I don't really understand your XSL(T)-using, to me it sounds like using a gas-station as a (not !-) convenient place to change a 1960 WV to a 2008 Skoda ...
Userely they have some common technology, though it is not used in the same way, computerization in some way is just a minor problem, the major problems is in nearly any other way !o]
Have you got any need for form-elements ?-)

Categories

Resources