4

AJavascriptでは、要素、たとえば要素が特定の範囲/textRange内に存在するかどうかを確認したいと思います。目的は、ユーザーの現在の選択にリンクが含まれているかどうかを判断することです。リッチテキストエディタコントロールを構築しています。

範囲オブジェクトには、範囲内のすべての要素の最も近い共通の祖先を返すcommonAncestorContainer(W3C)またはparentElement()(Microsoft)メソッドがあります。Aただし、範囲は親の途中で開始または終了する可能性があるため、この共通の祖先には範囲内にない要素も含まれている可能性があるため、この要素の内部で要素を探すことはできません。

これをどのように達成しますか?

4

5 に答える 5

5

selection.containsNodeはどうですか? https://developer.mozilla.org/en/DOM/Selection/containsNode

何かのようなもの:

var selection = window.getSelection();
var range = selection.getRangeAt(0);
var result = $('a', range.commonAncestorContainer).filter(function() {
  return selection.containsNode(this);
});
console.log(result);
于 2011-05-19T08:12:17.350 に答える
3

私はこのような解決策をとることになりました:

        var findinselection = function(tagname, container) {
            var
                i, len, el,
                rng = getrange(),
                comprng,
                selparent;
            if (rng) {
                selparent = rng.commonAncestorContainer || rng.parentElement();
                // Look for an element *around* the selected range
                for (el = selparent; el !== container; el = el.parentNode) {
                    if (el.tagName && el.tagName.toLowerCase() === tagname) {
                        return el;
                    }
                }
                // Look for an element *within* the selected range
                if (!rng.collapsed && (rng.text === undefined || rng.text) &&
                    selparent.getElementsByTagName) {
                    el = selparent.getElementsByTagName(tagname);
                    comprng = document.createRange ?
                        document.createRange() : document.body.createTextRange();
                    for (i = 0, len = el.length; i < len; i++) {

                        // determine if element el[i] is within the range
                        if (document.createRange) { // w3c
                            comprng.selectNodeContents(el[i]);
                            if (rng.compareBoundaryPoints(Range.END_TO_START, comprng) < 0 &&
                                rng.compareBoundaryPoints(Range.START_TO_END, comprng) > 0) {
                                return el[i];
                            }
                        }
                        else { // microsoft
                            comprng.moveToElementText(el[i]);
                            if (rng.compareEndPoints("StartToEnd", comprng) < 0 &&
                                rng.compareEndPoints("EndToStart", comprng) > 0) {
                                return el[i];
                            }
                        }
                    }
                }
            }
        };

getrange()は、現在の選択範囲を範囲オブジェクトとして取得するための私の別の関数です。

使用するには、次のように呼び出します

var link = findselection('a', editor);

ここで、editorはcontenteditable要素、またはdesignmodeiframeの本文です。

于 2011-05-25T04:13:46.940 に答える
2

これは、クロスブラウザを実行するのに少し苦痛です。私のRangyライブラリを使用することもできます。これは、このタスクだけではおそらくやり過ぎですが、より簡単になり、すべての主要なブラウザーで機能します。次のコードは、1つの範囲のみが選択されていることを前提としています。

var sel = rangy.getSelection();
if (sel.rangeCount) {
    var range = sel.getRangeAt(0);
    var links = range.getNodes([1], function(node) {
        return node.tagName.toLowerCase() == "a" && range.containsNode(node);
    });
}
于 2011-05-19T09:45:39.063 に答える
0

IE / Chrome / FFで動作するこのコードを使用しています:(テーブルの行<tr>を選択するために使用しています)

// yourLink is the DOM element you want to check
var selection = window.getSelection().getRangeAt(0)
var node = document.createRange()
node.selectNode(yourLink)
var s2s = selection.compareBoundaryPoints(Range.START_TO_END, node)
var s2e = selection.compareBoundaryPoints(Range.START_TO_START, node)
var e2s = selection.compareBoundaryPoints(Range.END_TO_START, node)
var e2e = selection.compareBoundaryPoints(Range.END_TO_END, node)
if ((s2s != s2e) || (e2s != e2e) || (s2s!=e2e))
    console.log("your node is inside selection")
于 2015-05-07T14:07:52.360 に答える
0

検索された要素の範囲の場合、私が書いたものが役に立ちます。(ただし、その場合のみ!)

最初に、範囲内で見つかったノードを返す関数getNodeFromRange(rangeObject)を作成しました。この関数を使用すると、目的のノードを返す関数findTagInRange(tagName)を簡単に作成できます。

function getNodeFromRange(range) {
    if(range.endContainer.nodeType==Node.ELEMENT_NODE) {
        return range.endContainer;
    }
    if(range.endContainer.nodeType==Node.TEXT_NODE) {
        return range.endContainer.parentNode;
    }
    else {
        // the 'startContainer' it isn't on an Element (<p>, <div>, etc...)
        return;
    }
}

function findTagInRange(tagName, range) {
    var node = getNodeFromRange(range);
    if(node && typeof(node.tagName)!='undefiend' && node.tagName.toLowerCase()==tagName.toLowerCase()) {
        return $(node);
    }
    return;
}

そして、私はそれを次のように使うことができます:

var link = findTagInRange('A', range);

そして、私はあなたがすでに解決した範囲の決定を見ます。:)

于 2019-06-14T08:00:49.937 に答える