【问题标题】:Any clever ways to serialize an HTML element? - Javascript任何巧妙的方法来序列化 HTML 元素? - Javascript
【发布时间】:2011-03-20 04:45:31
【问题描述】:

我正在尝试存储 HTML 标记的引用以供以后重用。

例如如果我单击一个 div 并在 Javascript 中保存指向该 div 的指针,是否有一种方法可以序列化这样的指针?所以我可以反序列化它并在 Web 应用程序的另一个实例中使用指针?


我能想到的方法只有以下几种:

  • 使用 id 或 name 属性

  • 为该元素创建一个 CSS 选择器

还有其他想法吗? =)

【问题讨论】:

    标签: javascript html css dom serialization


    【解决方案1】:

    您可以尝试为元素生成 XPath 字符串 - 字符串越复杂,标识符就越准确和便携。

    例如,一个简单的仅元素 XPath 查询字符串不会很独特,并且可能会再次出现:

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

    考虑所有属性可能有点过头了

    '//html/body[@onclick="somereallylongjavascript" and class="nosidebar"]/div[@id="wrapper" and @class="posts"]/div[@class="entry" and @id="firstentry"]/p[@class="first"]/strong'
    但是您可能会通过限制某些属性(可能只是 ID)找到一个不错的中间立场:
    '//html/body/div[@id="wrapper"]/div[@id="firstentry"]/p/strong'

    您可以在所有浏览器中本地检索 XPath。有W3C方法:

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

    (ns函数纯粹是你需要application/xhtml+xml支持)

    IE 方法更简单,但灵活性较差:

    var myElement=document.selectSingleNode(XPathString);

    当然,创建 XPath 字符串是一个不同的问题 - 有多种选择,不幸的是没有原生的。 XPather 是一个 moz 附加组件,它提供了一个执行此操作的接口 - 它的源代码是 MPL 版并且相对简单,但可能超出您的需要。有多种较短的脚本可以提供更简单的解决方案。

    编辑: Justin Johnson 提供了一个指向 SO 答案的链接,其中包含一个非常短的 XPath 生成函数。这有点简单,它使用奇怪的 id 表示法(id(blah) 而不是 [@id="blah"])并且不会 toLowerCase() 它的 tagNames 可能会损害便携性,但除此之外,它看起来非常适合您的需求。

    【讨论】:

    • 谢谢!!这实际上是我所想的一个版本。这是一个很好的答复,我非常感谢你!!我想我可能会勾选这个 =)
    【解决方案2】:

    您到底想保存什么?您究竟在哪里重复使用它?

    一个 DOM 元素将非常特定于在该页面上呈现的特定浏览器——只需点击刷新就会给你一个全新的 DOM 元素。那么,您需要保存和重新创建它吗?

    【讨论】:

      【解决方案3】:

      元素的innerHTML怎么样?

      【讨论】:

      • 它可能是一个空元素,也可能是一个重复的元素。这也将非常低效,因为它需要每次都在整个文档中搜索字符串。
      • 嗯,我不知道究竟他想做什么,但这确实符合序列化一个HTML元素,他问的——当然,“重用”“指针”本身是没有问题的。从我在这里看到的答案来看,似乎许多人将他的问题解释为“序列化对元素的引用”,而不是“序列化元素本身”。
      • 他要求能够“反序列化并用作指针”,因此它显然是一个参考。他还给出了使用 ID 或“CSS 选择器”的示例——两者都是参考。
      • 谢谢大家 =) 我猜 innerHTML 将是尝试序列化指针的准确方法。我开始认为我可以使用标签面额存储页面的树结构,然后为每个元素存储某种选择器。
      【解决方案4】:

      唯一合乎逻辑的方法是使用 id。

      通常根据数据库值为所有重要元素分配 id 并不难。

      【讨论】:

      • 问题是不是每个可点击的元素都保证一个 id。所以我认为基于公共属性构建一个 css 选择器会更有效。例如类 href src 标签 ...
      • 我会限制用户只能从具有逻辑项的元素中进行选择。我开始了解您的问题 - 您正在构建必须与通用 html 一起使用的工具。
      • @RadiantHex 如果不​​使用一些 hackish 算法或繁重的 JS 库,您将无法在 javascript 中检索 CSS 选择器 - 效率都不高。另一方面,XPath 在每个浏览器中都受到原生支持,而且速度非常快。
      【解决方案5】:

      根据您提出问题的方式,我认为这是不可能的。 “Web 应用程序的另一个实例”到底是什么意思?由于 JavaScript 将在客户端运行,因此您将无法在客户端之间共享数据。但是,您可能想要执行诸如从数据库存储/读取之类的操作。你能描述更多你想要实现的功能吗?

      【讨论】:

        【解决方案6】:

        XPath 似乎是最合适的;但是,仅当页面结构在该节点之前是(相对)静态的。以下是一些参考资料和代码:

        Method for getting the xpath of an arbitrary node 及示例使用

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

        产量

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

        MDC XPath documentation

        【讨论】:

          【解决方案7】:

          看起来 JSON.stringify(yourDivReference) 和 JSON.parse(serializedObjectString) 可能会满足您的需求。

          更新:实际上,JSON 方法不喜欢 DOM 中的循环引用。有关详细信息,请参阅此问题:How to serialize DOM node to JSON even if there are circular references?

          不过,我同意 Sergey 的观点,即使用 ID 似乎是一种更好的方法。

          【讨论】:

            【解决方案8】:

            另一个想法 - 根据一些规则为所有元素生成自己的自定义 ID:

            1. 元素 id 从父 id 开始。 -> customid = "body/item"
            2. 如果正常的 id 可用,请使用它。如果没有,请使用元素类型。比在当前子树中添加顺序。

            所以,如果 id 未知,您将得到类似“body-0/item-0”的内容,或者“body-0/div-4”。

            当您尝试使用您的“自定义 ID”并且页面将被更改时,您将有机会找到最接近的元素,将所有元素自定义 ID 与存储的“自定义 ID”进行比较。

            【讨论】:

              【解决方案9】:

              我尝试过这样的事情:

              {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!" }
              ]}
              

              似乎可以正常工作,尽管使用所有大括号很容易迷失方向。

              编辑 - 也许我完全误解了你想要什么......如果你想序列化那个元素的句柄,就像 getElementById 返回的一样,你最好只使用 id。

              【讨论】:

                猜你喜欢
                • 1970-01-01
                • 1970-01-01
                • 1970-01-01
                • 1970-01-01
                • 2016-04-19
                • 2010-09-12
                • 1970-01-01
                • 1970-01-01
                • 1970-01-01
                相关资源
                最近更新 更多