我正在撰写Chrome扩展程序,我需要将用户在网站上选择的值传递给我的服务器。我正在使用代码window.getSelection()返回一个范围对象。我正在使用JSON将范围对象传递回我的服务器,但它无法正常工作。我是新手,但我认为问题在于你只能用JSON传入文本,而范围对象包括DOM结构(不是文本)和实际文本选择(文本) 。我对么?还有其他选择吗?
var selection = window.getSelection();
$.getJSON(url, {data:selection}, function(moot) {
alert("done");
});
答案 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
}
没有经过彻底的测试,但总体思路就在这里。
答案 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()
将合并所有选择而不使用分隔符