Selecting text in an element (akin to highlighting with your mouse)

后端 未结 16 1631
孤街浪徒
孤街浪徒 2020-11-21 05:58

I would like to have users click a link, then it selects the HTML text in another element (not an input).

By \"select\" I mean the same way you would select

相关标签:
16条回答
  • 2020-11-21 06:15

    You can use the following function to select content of any element:

    jQuery.fn.selectText = function(){
        this.find('input').each(function() {
            if($(this).prev().length == 0 || !$(this).prev().hasClass('p_copy')) { 
                $('<p class="p_copy" style="position: absolute; z-index: -1;"></p>').insertBefore($(this));
            }
            $(this).prev().html($(this).val());
        });
        var doc = document;
        var element = this[0];
        console.log(this, element);
        if (doc.body.createTextRange) {
            var range = document.body.createTextRange();
            range.moveToElementText(element);
            range.select();
        } else if (window.getSelection) {
            var selection = window.getSelection();        
            var range = document.createRange();
            range.selectNodeContents(element);
            selection.removeAllRanges();
            selection.addRange(range);
        }
    };
    

    This function can be called as follows:

    $('#selectme').selectText();
    
    0 讨论(0)
  • 2020-11-21 06:16

    This thread (dead now) contains really wonderful stuff. But I'm not able to do it right on this page using FF 3.5b99 + FireBug due to "Security Error".

    Yipee!! I was able to select whole right hand sidebar with this code hope it helps you:

        var r = document.createRange();
        var w=document.getElementById("sidebar");  
        r.selectNodeContents(w);  
        var sel=window.getSelection(); 
        sel.removeAllRanges(); 
        sel.addRange(r); 
    

    PS:- I was not able to use objects returned by jquery selectors like

       var w=$("div.welovestackoverflow",$("div.sidebar"));
       
       //this throws **security exception**
    
       r.selectNodeContents(w);
    
    0 讨论(0)
  • 2020-11-21 06:17

    Here's a version with no browser sniffing and no reliance on jQuery:

    function selectElementText(el, win) {
        win = win || window;
        var doc = win.document, sel, range;
        if (win.getSelection && doc.createRange) {
            sel = win.getSelection();
            range = doc.createRange();
            range.selectNodeContents(el);
            sel.removeAllRanges();
            sel.addRange(range);
        } else if (doc.body.createTextRange) {
            range = doc.body.createTextRange();
            range.moveToElementText(el);
            range.select();
        }
    }
    
    selectElementText(document.getElementById("someElement"));
    selectElementText(elementInIframe, iframe.contentWindow);
    
    0 讨论(0)
  • 2020-11-21 06:18

    Tim's method works perfectly for my case - selecting the text in a div for both IE and FF after I replaced the following statement:

    range.moveToElementText(text);
    

    with the following:

    range.moveToElementText(el);
    

    The text in the div is selected by clicking it with the following jQuery function:

    $(function () {
        $("#divFoo").click(function () {
            selectElementText(document.getElementById("divFoo"));
        })
    });
    
    0 讨论(0)
  • 2020-11-21 06:23

    I liked lepe's answer except for a few things:

    1. Browser-sniffing, jQuery or no isn't optimal
    2. DRY
    3. Doesn't work in IE8 if obj's parent doesn't support createTextRange
    4. Chrome's ability to use setBaseAndExtent should be leveraged (IMO)
    5. Will not select text spanning across multiple DOM elements (elements within the "selected" element). In other words if you call selText on a div containing multiple span elements, it will not select the text of each of those elements. That was a deal-breaker for me, YMMV.

    Here's what I came up with, with a nod to lepe's answer for inspiration. I'm sure I'll be ridiculed as this is perhaps a bit heavy-handed (and actually could be moreso but I digress). But it works and avoids browser-sniffing and that's the point.

    selectText:function(){
    
        var range,
            selection,
            obj = this[0],
            type = {
                func:'function',
                obj:'object'
            },
            // Convenience
            is = function(type, o){
                return typeof o === type;
            };
    
        if(is(type.obj, obj.ownerDocument)
            && is(type.obj, obj.ownerDocument.defaultView)
            && is(type.func, obj.ownerDocument.defaultView.getSelection)){
    
            selection = obj.ownerDocument.defaultView.getSelection();
    
            if(is(type.func, selection.setBaseAndExtent)){
                // Chrome, Safari - nice and easy
                selection.setBaseAndExtent(obj, 0, obj, $(obj).contents().size());
            }
            else if(is(type.func, obj.ownerDocument.createRange)){
    
                range = obj.ownerDocument.createRange();
    
                if(is(type.func, range.selectNodeContents)
                    && is(type.func, selection.removeAllRanges)
                    && is(type.func, selection.addRange)){
                    // Mozilla
                    range.selectNodeContents(obj);
                    selection.removeAllRanges();
                    selection.addRange(range);
                }
            }
        }
        else if(is(type.obj, document.body) && is(type.obj, document.body.createTextRange)) {
    
            range = document.body.createTextRange();
    
            if(is(type.obj, range.moveToElementText) && is(type.obj, range.select)){
                // IE most likely
                range.moveToElementText(obj);
                range.select();
            }
        }
    
        // Chainable
        return this;
    }
    

    That's it. Some of what you see is the for readability and/or convenience. Tested on Mac in latest versions of Opera, Safari, Chrome, Firefox and IE. Also tested in IE8. Also I typically only declare variables if/when needed inside code blocks but jslint suggested they all be declared up top. Ok jslint.

    Edit I forgot to include how to tie this in to the op's code:

    function SelectText(element) {
        $("#" + element).selectText();
    }
    

    Cheers

    0 讨论(0)
  • 2020-11-21 06:23

    Have a look at the Selection object (Gecko engine) and the TextRange object (Trident engine.) I don't know about any JavaScript frameworks that have cross-browser support for this implemented, but I've never looked for it either, so it's possible that even jQuery has it.

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