1

私がサイト用に書いたコンテンツ管理システムは、ブックマークレットを使用して記事を投稿します。ブックマークレットは、ページ上の選択された領域を document.getSelection() で読み取ります。しかし、場合によっては、リンクやその他の HTML フォーマットを取得するために、選択した領域の基になる HTML コードも読み取ると非常に便利です。

選択した領域を生成する生の HTML にアクセスするための jQuery プラグインまたはその他の Javascript 手法を知っている人はいますか?

4

1 に答える 1

3

まず、あなたが言ったように、選択を取得します

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
*/
于 2012-12-02T02:47:08.437 に答える