Range object with JSON

青春壹個敷衍的年華 提交于 2019-12-21 05:37:09

问题


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");
});

回答1:


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




回答2:


If you need to send the user selections in your page

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");
});

Note: instead of toString(), you can use join('<separator>') as well based on your need

Using window.getSelection().toString() would combine all selections without separator




回答3:


Have you tried window.getSelection().toString()? That should get just the text value by itself.

MDN is currently down, but you might want to check out the DOMSelection documentation there: https://developer.mozilla.org/En/DOM/Selection

EDIT

You could also try using the anchorNode and focusNode properties to grab the nodes in which the selection starts and stops. If you really need the raw html, you could do something like focusNode.parentNode.outerHTML to get the whole block (it looks like you can't do outerHTML on the focus or anchorNodes directly).

ie:

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

and then parse it on the other side. You could also peel out other information from the nodes so that you don't have to pass the whole html strings over the wire.



来源:https://stackoverflow.com/questions/9074091/range-object-with-json

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!