5

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!

clockworked247
  • 347
  • 3
  • 13
  • 3
    perhaps you should state the actual problem you are trying to solve... – Mitch Wheat Mar 20 '11 at 01:05
  • 1
    Agree with Mitch Wheat. Why are you trying to do such a thing? You are mixing presentation concerns (the ID of a DOM object) into your data storage layer. It's generally inadvisable to do so. – anon Mar 20 '11 at 01:12
  • This is a very situational question as @mitch and @anon are eluding to. Providing a specific example will help a lot. – Bryan Downing Mar 20 '11 at 01:24
  • @mitch and @anon - The second sentence of the post describes exactly what I'm looking to do "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." Perhaps you should read more carefully. The "why" of the question is irrelevant as this is exactly what I am attempting to accomplish. – clockworked247 Mar 21 '11 at 17:26
  • @clockworked247 : actually, that's your perceived solution to a problem you haven't stated. " The "why" of the question is irrelevant as this is exactly what I am attempting to accomplish" - with experience, you'll learn that the 'why?' is very important. More important certainly than remarks such as "Perhaps you should read more carefully" – Mitch Wheat Mar 22 '11 at 00:38
  • @mitch - Would it have helped if I put "How can I" in front of that statement? It would then read "How do I use JavaScript to identify a DOM element on a page, then store it's reference in a database or cookie for later retrieval?" If I was to be more specific I'd add that the "reference" would need to be some sort of unique identifier allowing me to look up the DOM element with this identifier. I think I explained that pretty well in the full text, my apologies if I did not. – clockworked247 Mar 22 '11 at 00:48

2 Answers2

3

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).

Nik Kalyani
  • 916
  • 5
  • 10
  • Hey Nik, this seems like an absolutely ideal solution to my problem! Thanks so much! – clockworked247 Mar 21 '11 at 19:07
  • Hey Nik, I found a flaw in the solution you posted. If I were to have two elements in a page with the same content, then this method would not work. For instance, if there were two of the same image within a page, the contents would be the same and therefore return the same hash. XPath or some relation to it's sibilings or parent on the page could become a part of that hash, maybe... and help create a more accurate hash. Any thoughts? – clockworked247 Mar 22 '11 at 00:53
  • I guess the XPath would work as it's explicit location within the DOM and if they changed the page at all, the paths to those elements would break. Then in that case I could use your method to attempt to intelligently re-bind the hashID to it's new XPath location. – clockworked247 Mar 22 '11 at 01:22
  • Another approach might be to always use both, the content and the attributes to get the hash. Of course if you had two elements like
  • Item
  • , it would still have the same issue. – Nik Kalyani Mar 22 '11 at 17:30
  • Thank you so much, this is a great approach and you are definitely a master of JavaScript! – Darren Jul 19 '12 at 03:10