【问题标题】:Using xpath to restore a DOM range in JavaScript在 JavaScript 中使用 xpath 恢复 DOM 范围
【发布时间】:2011-09-05 21:04:27
【问题描述】:

我正在尝试掌握保存(序列化)和恢复(反序列化)DOM 选择或范围的最佳方法。这里有一篇关于对范围对象进行字符串化的帖子,但坦率地说,它并没有真正起作用。

情景是一本使用 Adob​​e Air 的 Webkit 视图的交互式教科书。我有静态(内置)html 内容,用户可以突出显示和添加书签(注释)。这种机制一切正常,但我需要能够存储和恢复这些注释。我宁愿不存储 DOM 的修改版本,而是使用静态版本,然后重新应用我存储在 SQLite DB 中的用户注释以及其他所需的元数据。 DOM 操作对我来说相当新,到目前为止,我尝试序列化 DOM::range 的尝试都失败了。但我意识到,我似乎真的只需要开始和结束容器以及开始和结束偏移量。然后我可以使用 document.createRange() 重新创建范围。

我可以使用的指导是序列化开始和结束容器的最佳方法。我的第一个想法是 xpath,但到目前为止,我的尝试都失败了。查看 DOM::Range 的 Mozilla 文档似乎很简单,但是创建一个可靠的 xpath 来恢复范围对我来说并不是很容易。

【问题讨论】:

    标签: javascript dom actionscript xpath webkit


    【解决方案1】:

    HTML

    <div>
        <div id="container" style="background-color: red;">
            <p id="paraText">Text</p>
        </div>
    </div>
    

    JavaScript

    function serialize(node) {
        if (typeof XMLSerializer != "undefined") {  // Firefox, etc.
            return (new XMLSerializer()).serializeToString(node);
        }
        else if (node.xml) {  // IE
            return node.xml;
        }
    };
    
    function parseXMLString(xml) {
        if (typeof DOMParser != "undefined") {  // Firefox, etc.
           var dp = new DOMParser();
           return dp.parseFromString(xml, "application/xml");
        }
        else if (typeof ActiveXObject != "undefined") {  // IE
            var doc = XML.newDocument();
            doc.loadXML(xml);
            return doc;
        }
    };
    
    var contextNode = document.getElementById('container');
    var xmlString = serialize(contextNode);
    var doc = parseXMLString(xmlString);
    
    // Get elements from document using XPath
    var xpathResult = doc.evaluate('//.', doc.firstChild, null, XPathResult.FIRST_ORDERED_NODE_TYPE, null);
    
    // Insert elements back into document (I used replace in order to show that the document is actually changed)
    contextNode.parentNode.replaceChild(xpathResult.singleNodeValue.firstChild, contextNode);
    

    【讨论】:

      【解决方案2】:

      碰巧,我已经为我的Rangy 库编写了一个解决方案。 Serializer module 使用类似 XPath 的语法来序列化和反序列化范围和选择 (demo)。

      我还编写了一个尚未公开发布的荧光笔模块。我会整理一下,一会儿放个demo。

      更新

      Highlighter demo is now available。经过一些更多的测试,它将在Rangy的下一个版本中发布。

      【讨论】:

      • 这是一个很大的帮助,感谢您分享 Rangy 库。希望我能在几个月前看到这个。
      • 有什么办法可以读取python中的序列化结果。换句话说,如果我想将序列化的范围发送到 python 后端进行处理?
      • @AlexRothberg:您的 Python 需要访问与 JavaScript 相同的 DOM,以便以任何有意义的方式重建范围。假设你有这个(大假设),反序列化非常简单。
      • 在这种情况下,html 是静态的。是否有关于如何序列化范围的文档?
      • @AlexRothberg:您仍然需要将 HTML 解析为 DOM 表示。我刚刚添加了有关序列化结构的文档:code.google.com/p/rangy/wiki/SerializerModule
      【解决方案3】:

      Rangy 库的 Serialiazer 模块的一个主要问题是它不是跨浏览器一致的,例如存储在一个浏览器上的选择无法在不同的浏览器系列(Gecko 和 IE)上恢复

      【讨论】:

        猜你喜欢
        • 2017-01-26
        • 1970-01-01
        • 2014-10-15
        • 2018-03-24
        • 1970-01-01
        • 2012-08-09
        • 1970-01-01
        • 1970-01-01
        • 2012-08-02
        相关资源
        最近更新 更多