使用JSON的Range对象

时间:2012-01-31 03:45:34

标签: javascript google-chrome-extension

我正在撰写Chrome扩展程序,我需要将用户在网站上选择的值传递给我的服务器。我正在使用代码window.getSelection()返回一个范围对象。我正在使用JSON将范围对象传递回我的服务器,但它无法正常工作。我是新手,但我认为问题在于你只能用JSON传入文本,而范围对象包括DOM结构(不是文本)和实际文本选择(文本) 。我对么?还有其他选择吗?

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

3 个答案:

答案 0 :(得分:4)

一个简单的解决方法不是序列化和发送整个选择对象,而是将起点和终点存储为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

答案 1 :(得分:0)

你试过window.getSelection().toString()吗?这应该只是文本值。

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

修改

您还可以尝试使用anchorNode和focusNode属性来抓取选择开始和停止的节点。如果你真的需要原始html,你可以做一些像focusNode.parentNode.outerHTML来获取整个块(看起来你不能直接在focus或anchorNodes上做outerHTML)。

即:

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

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

答案 2 :(得分:0)

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

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('<separator>')

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