How to know if there is a link element within the selection

后端 未结 5 1551
心在旅途
心在旅途 2021-01-06 03:46

In Javascript, I\'d like determine whether an element, say an A element, exists inside a given range/textRange. The aim is to determine if the user\'s current

相关标签:
5条回答
  • 2021-01-06 03:54

    This is a bit of a pain in the bum to do cross-browser. You could use my Rangy library, which is probably overkill for just this task but does make it more straightforward and works in all major browsers. The following code assumes only one Range is selected:

    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);
        });
    }
    
    0 讨论(0)
  • 2021-01-06 04:05

    I'm using this code that works with IE / Chrome / FF: (I'm using it to select rows <tr> in a table)

    // 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")
    
    0 讨论(0)
  • 2021-01-06 04:09

    In the case of the range on the searched element, what I wrote is useful. (But only for that case!)

    First I wrote a function that returns the Node found in the range: getNodeFromRange(rangeObject). Using this function it was already easy to write the function that returns the desired Node: 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;
    }
    

    And then I can use it as follows:

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

    And I see the determination of the range you've already solved. :)

    0 讨论(0)
  • 2021-01-06 04:18

    How about selection.containsNode? https://developer.mozilla.org/en/DOM/Selection/containsNode

    something like:

    var selection = window.getSelection();
    var range = selection.getRangeAt(0);
    var result = $('a', range.commonAncestorContainer).filter(function() {
      return selection.containsNode(this);
    });
    console.log(result);
    
    0 讨论(0)
  • 2021-01-06 04:18

    I ended up going with a solution like this:

            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];
                                }
                            }
                        }
                    }
                }
            };
    

    Where getrange() is another function of mine to get the current selection as a range object.

    To use, call it like

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

    Where editor is the contenteditable element, or body in a designmode iframe.

    0 讨论(0)
提交回复
热议问题