clockworked247
clockworked247

Reputation: 347

Storage and retrieval of DOM element

Wondering if anyone out there has ran into this before....

I'd like to use JavaScript to identify a DOM element on a page, then store it's reference in a database or cookie for later retrieval.

To get specific, what I'm looking to do is create a UI so that when the user CLICKs an element on a page, JavaScript fires the click event, passing the instance of the DOM element clicked on.

easy so far, right?

So what I want to do is store the "identity" of this DOM element, say in a database, so when I later return to this page, I can pull out all stored DOM element identities and get access to them in the page once more.

So this is quite simple if this DOM element has a unique ID. Just store the ID, then when the page comes back up, we just do a getElementByID and we've got our DOM element again.

The problem is that not everything in the DOM has a unique identifier, so there the problem lies.

I had some bad ideas initially, like iterating through the entire DOM and incrementing them with unique class names (dom-01, dom-02, etc) and this would give me an identifier. But this would cause a lot of initial overhead and if the page ever changed, the order of the DOM elements wouldn't be the same, so we wouldn't get back the correct DOM elemet.

I'mve never tried it, but another thought was to serialize the DOM element, stick it in the DB, and then on reload parse to an object, and use that object to find my original DOM element. I've never done that before, so how I can actually compare the restored (parsed) object to the one in the DOM is a big unknown.

Specifics on the serialization solution or any other original ideas for accomplishing this are welcome!!

Thanks in advance everyone!

Upvotes: 5

Views: 3031

Answers (2)

Nik Kalyani
Nik Kalyani

Reputation: 916

Here's a jsFiddle solution attempt: http://jsfiddle.net/techbubble/pJgyu/7720/

The approach I took was to compute a simple hash of the HTML content of the target element, or if no such content is present, a hash of the aggregated attributes and values of the element. I have a getElementHash() function that returns a string in the format: TAG:[H | A]:Hash (the H or A indicates if the HTML content or attributes were used to calculate the hash). This produces a unique key for any element on the page that either has HTML content or has at least one attribute (miniscule risk of duplication possible).

For retrieving an element with a previously saved key, I created a getElementByHash() function. It uses the tag that is extracted from the key in a jQuery selector. For each element returned, the HTML content or attributes hash is computed (based on the value "H" or "A" specified in the key) to see if it matches the hash in the key. If there is a match, the search ends and the element is returned.

This approach is impervious to the element being moved around on the page as long as its HTML content (or attributes) remain unchanged. It does not produce a key for elements that have neither any HTML content nor any attributes (which makes them pretty useless anyway).

Upvotes: 3

Dan Beam
Dan Beam

Reputation: 3927

If you want to keep the location of the node in the DOM, why not just keep an XPath of it? XPath allows you to keep an exact location of a node in a document, as long as that location doesn't change. For instance, you can say something like

//div[@id="xpath_is"]/span[class="cool"]/a[4]

Meaning the 4th <a> tag within a <span class="cool"> within a <div id="xpath_is">

http://www.w3.org/TR/xpath/
http://www.w3schools.com/xpath/default.asp

You can get the XPath of an attribute by Inspecting it with Firebug and right clicking on the node and selecting "Copy XPath". I'm not sure how easy it is to get it from a DOM Node (there are ways, but not sure how many baked implementations there are lying around). It'd be relatively easy to simply look for an ancestor (by traversing upward with .parentNode and building one) and adding .classNames and .ids as you go - but I'm too lazy to write this right now, ;).

Upvotes: 2

Related Questions