带JSON的Range对象 [英] Range object with JSON

查看:94
本文介绍了带JSON的Range对象的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

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


解决方案

一个简单的解决方法不是序列化并发送 whole 选择对象,而是将开始点和结束点存储为XPath(以及它们的偏移量)。像这样的东西可以做到:

$ $ p $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $对于可选节点,具有名称空间的XML需要更多的代码* /
currentPath = currentPath || ;
switch(node.nodeType){
case 3:
case 4:
return makeXPath(node.parentNode,'text()['+(document.evaluate(' ()',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:''));
案例9:
返回'/'+ currentPath;
默认值:
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);
}
}

函数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
}

没有经过彻底测试,但总体思路就在这里。



来源:


I am writing a Chrome extension and I need to pass in the value that the user has selected on the website to my server. I am using the code window.getSelection() which returns a range object. I am using JSON to pass the range object back to my server but it is not working. I am new to this, but I think the problem lies with the fact that you can only pass in text with JSON, and the range object includes both the DOM structure (which is not text) and the actual text selection (which is text). Am I correct? Is there an alternative?

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

解决方案

A simple workaround is not to serialize and send the entire select object, but rather to store the start and end points as XPaths (along with their offsets). Something like this would do:

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
}

Not thoroughly tested, but the general idea is here.

Sources: This and That

这篇关于带JSON的Range对象的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆