如何知道选择中是否有链接元素

tho*_*ter 4 javascript dom range selection textrange

在Javascript中,我想确定一个元素,比如一个A元素,是否存在于给定的范围/ textRange中.目的是确定用户的当前选择是否包含链接.我正在构建一个富文本编辑器控件.

range对象具有commonAncestorContainer(W3C)或parentElement()(Microsoft)方法,该方法返回范围内所有元素的最接近的公共anscestor.但是,在元素内部查找元素是A行不通的,因为这个共同的祖先也可能包含不在范围内的元素,因为范围可以从父节点开始或结束.

你会如何实现这一目标?

sha*_*nny 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);
Run Code Online (Sandbox Code Playgroud)


tho*_*ter 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];
                            }
                        }
                    }
                }
            }
        };
Run Code Online (Sandbox Code Playgroud)

其中 getrange() 是我的另一个函数,用于将当前选择作为范围对象获取。

要使用,请像这样称呼它

var link = findselection('a', editor);
Run Code Online (Sandbox Code Playgroud)

其中编辑器是可内容编辑的元素,或设计模式 iframe 中的主体。