まず、あなたが言ったように、選択を取得します
var sel = document.getSelection();
これには、選択したノードに関する詳細も含まれていますが、さらに実行したい場合は、これを範囲に変換します(.rangeCount > 1
ここでループしたい場合)。
var range = sel.getRangeAt(0);
次に、 DOM ツリーを使用range.commonAncestorContainer
してrange.startContainer
ウォークスルーし、 に到達するまで実行しますrange.endContainer
。
これらのノードはすべて選択されている必要があります。
以下は、選択されたすべての (最上位の) ノードを返し、オプションで、選択されたすべてのノードにコールバックを適用するコードです。
function selectedNodes(callback, context) {
var sel = document.getSelection(),
range = sel.getRangeAt(0),
indices = [],
nextNode = function nextNode(e) {
if (e.childNodes.length > 0) return e.childNodes[0];
while(!e.nextSibling && e.parentNode) e = e.parentNode;
return e.nextSibling;
},
e = range.startContainer;
if (callback) {
callback.call(context, e);
while(e !== range.endContainer) {
e = nextNode(e);
callback.call(context, e);
}
e = range.startContainer;
}
if (e === range.commonAncestorContainer) return [e];
else {
while (e !== range.commonAncestorContainer) {
indices[0] = Array.prototype.indexOf.call(e.parentNode.childNodes, e);
e = e.parentNode;
}
e = range.endContainer;
while (e !== range.commonAncestorContainer) {
indices[1] = Array.prototype.indexOf.call(e.parentNode.childNodes, e);
e = e.parentNode;
}
return Array.prototype.slice.call(e.childNodes, indices[0], indices[1]+1);
}
}
/*
selectedNodes(console.log, console);
node1
..
nodeN
[node1, .., nodeM] // only top-level
*/