【问题标题】:Range object with JSON带有 JSON 的范围对象
【发布时间】:2012-02-07 04:06:37
【问题描述】:

我正在编写一个 Chrome 扩展程序,我需要将用户在网站上选择的值传递给我的服务器。我正在使用返回范围对象的代码 window.getSelection()。我正在使用 JSON 将范围对象传递回我的服务器,但它不起作用。我对此并不陌生,但我认为问题在于您只能使用 JSON 传入文本,并且范围对象包括 DOM 结构(不是文本)和实际的文本选择(即文本) .我对么?有替代方案吗?

var selection = window.getSelection();
$.getJSON(url, {data:selection}, function(moot) {
    alert("done");
});

【问题讨论】:

    标签: javascript google-chrome-extension


    【解决方案1】:

    一个简单的解决方法不是序列化和发送 整个 选择对象,而是将起点和终点存储为 XPath(连同它们的偏移量)。这样的事情会做:

    function makeXPath (node, currentPath) {
      /* this should suffice in HTML documents for selectable nodes, XML with namespaces needs more code */
      currentPath = currentPath || '';
      switch (node.nodeType) {
        case 3:
        case 4:
          return makeXPath(node.parentNode, 'text()[' + (document.evaluate('preceding-sibling::text()', node, null, XPathResult.ORDERED_NODE_SNAPSHOT_TYPE, null).snapshotLength + 1) + ']');
        case 1:
          return makeXPath(node.parentNode, node.nodeName + '[' + (document.evaluate('preceding-sibling::' + node.nodeName, node, null, XPathResult.ORDERED_NODE_SNAPSHOT_TYPE, null).snapshotLength + 1) + ']' + (currentPath ? '/' + currentPath : ''));
        case 9:
          return '/' + currentPath;
        default:
          return '';
      }
    }
    
    function restoreSelection () {
          var selection = window.getSelection();
          selection.removeAllRanges();
          var range = document.createRange();
          range.setStart(document.evaluate(selectionDetails[0], document, null, XPathResult.FIRST_ORDERED_NODE_TYPE, null).singleNodeValue, Number(selectionDetails[1]));
          range.setEnd(document.evaluate(selectionDetails[2], document, null, XPathResult.FIRST_ORDERED_NODE_TYPE, null).singleNodeValue, Number(selectionDetails[3]));
          selection.addRange(range);
      }
    }
    
    function getSelection() {
       var selection = window.getSelection();
       var range = selection.getRangeAt(0);
       var selectObj = { 
          'startXPath': makeXPath(range.startContainer), 
          'startOffset': range.startOffset, 
          'endXPath': makeXPath(range.endContainer), 
          'endOffset': range.endOffset 
       }
    
       return selectObj
    }
    

    没有经过全面测试,但大致思路就在这里。

    来源:ThisThat

    【讨论】:

      【解决方案2】:

      如果您需要在页面中发送用户选择

      var selection = window.getSelection();  
      
      for(i=0;i<selection.rangeCount;i++) 
      a[i]=selection.getRangeAt(i);
      
      $.getJSON(url, {data:a.toString()}, function(moot) {
         alert("done");
      });
      

      注意:除了toString(),您也可以根据需要使用join('&lt;separator&gt;')

      使用window.getSelection().toString() 将组合所有选择而不使用分隔符

      【讨论】:

        【解决方案3】:

        你试过window.getSelection().toString()吗?那应该只获得文本值本身。

        MDN 目前已关闭,但您可能想查看那里的 DOMSelection 文档:https://developer.mozilla.org/En/DOM/Selection

        编辑

        您还可以尝试使用 anchorNode 和 focusNode 属性来获取选择开始和停止的节点。如果您真的需要原始 html,您可以执行 focusNode.parentNode.outerHTML 之类的操作来获取整个块(看起来您不能直接在焦点或锚节点上执行 outerHTML)。

        即:

        var selection = window.getSelection();
        var payload = {
            selectedText: selection.toString(),
            startHTML: selection.anchorNode.parentNode.outerHTML,
            endHTML: selection.focusNode.parentNode.outerHTML
        }
        

        然后在另一边解析它。您还可以从节点中剥离其他信息,这样您就不必通过网络传递整个 html 字符串。

        【讨论】:

        • 我还没有尝试过 .toString() 。我一会儿试试。我担心的是我需要保留 DOM 结构,因为我稍后会使用选择。
        • 我尝试了 .toString() ,它确实只返回了文本值本身:) 我需要的也是 DOM 结构。这样做的原因是因为我需要显示用户稍后突出显示的文本,而我想出的唯一方法是使用 DOM 结构定位文本。
        • 您也可以尝试使用 anchorNode 和 focusNode 属性。我会更新答案。
        猜你喜欢
        • 2013-08-12
        • 2012-10-22
        • 2019-05-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2013-10-21
        • 2023-02-15
        相关资源
        最近更新 更多