开发者

Any clever ways to serialize an HTML element? - Javascript

I'm trying to store a reference of an HTML tag for later reuse.

e.g. If I click on a div and save a pointer to that div wit开发者_开发技巧hin Javascript, will there be a way I could serialize such pointer? So I could de-serialize it and use the pointer in another instance of the web application?


Only methods I can think of are the following:

  • Use id or name attributes

  • Create a CSS selector for that element

Any other ideas guys? =)


You could try generating an XPath string for the element - the more complex the string, the more accurate and portable an identifier it will be.

For example, a simple element-only XPath query string would not be very unique, and likely to re-occur:

'//html/body/div/div/p/strong'

Factoring in all attributes might be overkill

'//html/body[@onclick="somereallylongjavascript" and class="nosidebar"]/div[@id="wrapper" and @class="posts"]/div[@class="entry" and @id="firstentry"]/p[@class="first"]/strong'
But you could probably find a nice middle-ground by limiting to certain attributes, maybe just to IDs:

'//html/body/div[@id="wrapper"]/div[@id="firstentry"]/p/strong'

You can retrieve XPath natively in all browsers. There's the W3C method:


var myElement=document.evaluate(
  XPathstring,
  document,
  function(ns){return{'html':'http://www.w3.org/1999/xhtml','':null}[ns];},
  9,
  null
).singleNodeValue;

(the ns function is purely if you need application/xhtml+xml support)

The IE method is more simplistic but less flexible:

var myElement=document.selectSingleNode(XPathString);

Creating the XPath string is a different issue of course - there are various options, none native unfortunately. XPather is a moz add-on that provides an interface that does this - its source is MPL-ed and relatively simple but is probably more than you need. There are various shorter scripts available that provide simpler solutions.

Edit: Justin Johnson has provided a link to an SO answer containing a VERY short XPath-generating function. It's a bit simplistic, it uses odd id notation (id(blah) instead of [@id="blah"]) and doesn't toLowerCase() its tagNames which could impair portability, but other than that it looks perfect for your needs.


What exactly are you trying to save? And where exactly are you re-using it?

A DOM element would be very specific to that particular browser rendering on that page -- Just hitting refresh will give you an whole new DOM element. So, what about it do you need to save & recreate?


How about the innerHTML of the element?


Only logical way is to use id.

It is ussually not hard to assign id to all important elements based on database values.


Based on the way you worded your question, I don't think that would be possible. What exactly do you mean by "another instance of the web application"? Since JavaScript will be running on the client side, you won't be able to share data between clients. However, you might want to do something like store/read from a database. Can you describe more of the functionality you are trying to achieve?


XPath seems to be the most appropriate; however, only if the page structure is (relatively) static up to that node. Here are some references and code:

Method for getting the xpath of an arbitrary node and example use

getPathTo($("a")[4]):

yields

"id("hlinks-custom")/A[2]"

MDC XPath documentation


It looks like JSON.stringify( yourDivReference ) and JSON.parse( serializedObjectString ) might do what you're looking for.

UPDATE: Actually, the JSON methods don't like the circular references in the DOM. See this question for more details: How to serialize DOM node to JSON even if there are circular references?

I do, however, agree with Sergey that using the ID seems like a better way to go.


Another idea - to generate own custom id's for all elements based on some rules:

  1. element id starts from parent id. -> customid = "body/item"
  2. If normal id is available use it. if not, use element type. Than add order in current subtree.

so, you will get something like "body-0/item-0" for example above or "body-0/div-4" if id is not known.

When you will try to use your "custom id" and page will be changed, you will have a chance to find closest element, comparing all elements custom id to stored "custom id".


I've tried something like this:

{tag:"div", style:"float:left;", "class":"fancy", inner:[
  {tag:"a", href:"http://google.com", inner:"A link to google!" },
  {tag:"a", href:"http://yahoo.com", inner:"A link to yahoo!" }
]}

Seems to work okay, although it's easy to get lost with all the curly brackets.

edit - maybe I completely misunderstood what you want... if you want to serialize a handle to that element, like what would be returned by getElementById, you might as well just use the id.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜