选择元素中的文本(类似于用鼠标突出显示)

Jas*_*son 408 javascript jquery

我希望让用户单击一个链接,然后在另一个元素(不是输入)中选择HTML文本.

通过"选择",我的意思与通过将鼠标拖过它来选择文本的方式相同.这是一个研究的熊,因为每个人都在谈论其他术语中的"选择"或"突出".

这可能吗?我的代码到目前为止:

HTML:

<a href="javascript:" onclick="SelectText('xhtml-code')">Select Code</a>
<code id="xhtml-code">Some Code here </code>
Run Code Online (Sandbox Code Playgroud)

JS:

function SelectText(element) {
    $("#" + element).select();
}
Run Code Online (Sandbox Code Playgroud)

我错过了一些明显的东西吗?

Jas*_*son 589

简单的Javascript

function selectText(node) {
    node = document.getElementById(node);

    if (document.body.createTextRange) {
        const range = document.body.createTextRange();
        range.moveToElementText(node);
        range.select();
    } else if (window.getSelection) {
        const selection = window.getSelection();
        const range = document.createRange();
        range.selectNodeContents(node);
        selection.removeAllRanges();
        selection.addRange(range);
    } else {
        console.warn("Could not select text in node: Unsupported browser.");
    }
}

const clickable = document.querySelector('.click-me');
clickable.addEventListener('click', () => selectText('target'));
Run Code Online (Sandbox Code Playgroud)
<div id="target"><p>Some text goes here!</p><p>Moar text!</p></div>
<p class="click-me">Click me!</p>
Run Code Online (Sandbox Code Playgroud)

这是一个工作演示.对于那些寻找jQuery插件的人来说,我也做了其中一个.


jQuery(原始答案)

我在这个帖子中找到了解决方案.我能够修改给定的信息并将其与一些jQuery混合,以创建一个非常棒的函数来选择任何元素中的文本,无论浏览器如何:

function SelectText(element) {
    var text = document.getElementById(element);
    if ($.browser.msie) {
        var range = document.body.createTextRange();
        range.moveToElementText(text);
        range.select();
    } else if ($.browser.mozilla || $.browser.opera) {
        var selection = window.getSelection();
        var range = document.createRange();
        range.selectNodeContents(text);
        selection.removeAllRanges();
        selection.addRange(range);
    } else if ($.browser.safari) {
        var selection = window.getSelection();
        selection.setBaseAndExtent(text, 0, text, 1);
    }
}
Run Code Online (Sandbox Code Playgroud)

  • 是的,似乎有人最近对此进行了编辑。固定 (2认同)
  • jQuery 解决方案给了我未捕获的类型错误:无法读取未定义的属性“msie” (2认同)
  • jquery解决方案源自下面VillageIdiot的回答。精彩的线索现在变成了死链接。位腐烂:-( (2认同)

Tim*_*own 123

这是一个没有浏览器嗅探并且不依赖于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);
Run Code Online (Sandbox Code Playgroud)


lep*_*epe 18

Jason的代码不能用于iframe中的元素(因为范围与窗口和文档不同).我修复了这个问题并修改了它,以便用作任何其他jQuery插件(可链接):

示例1:单击选择<code>标记内的所有文本并添加"selected"类:

$(function() {
    $("code").click(function() {
        $(this).selText().addClass("selected");
    });
});
Run Code Online (Sandbox Code Playgroud)

示例2:单击按钮,选择Iframe中的元素:

$(function() {
    $("button").click(function() {
        $("iframe").contents().find("#selectme").selText();
    });
});
Run Code Online (Sandbox Code Playgroud)

注意:请记住,iframe源应驻留在同一个域中以防止出现安全性错误.

jQuery插件:

jQuery.fn.selText = function() {
    var obj = this[0];
    if ($.browser.msie) {
        var range = obj.offsetParent.createTextRange();
        range.moveToElementText(obj);
        range.select();
    } else if ($.browser.mozilla || $.browser.opera) {
        var selection = obj.ownerDocument.defaultView.getSelection();
        var range = obj.ownerDocument.createRange();
        range.selectNodeContents(obj);
        selection.removeAllRanges();
        selection.addRange(range);
    } else if ($.browser.safari) {
        var selection = obj.ownerDocument.defaultView.getSelection();
        selection.setBaseAndExtent(obj, 0, obj, 1);
    }
    return this;
}
Run Code Online (Sandbox Code Playgroud)

我在IE8,Firefox,Opera,Safari,Chrome(当前版本)中进行了测试.我不确定它是否适用于较旧的IE版本(真诚的我不在乎).

  • $ .browser现已弃用/删除 - 这需要重写 (3认同)
  • @JamesMcCormack:是的.我不确定重写它是否值得,因为这里发布的其他解决方案不涉及$ .browser. (2认同)

The*_*iot 15

这个主题非常精彩.但由于"安全错误",我无法使用FF 3.5b99 + FireBug在此页面上正确执行此操作.

Yipee!我可以用这段代码选择整个右侧边栏,希望它可以帮助你:

    var r = document.createRange();
    var w=document.getElementById("sidebar");  
    r.selectNodeContents(w);  
    var sel=window.getSelection(); 
    sel.removeAllRanges(); 
    sel.addRange(r); 
Run Code Online (Sandbox Code Playgroud)

PS: - 我无法使用jquery选择器返回的对象

   var w=$("div.welovestackoverflow",$("div.sidebar"));

   //this throws **security exception**

   r.selectNodeContents(w);
Run Code Online (Sandbox Code Playgroud)

  • 你需要从jQuery中获取元素,因为你正在尝试选择一个jQuery对象:var w = $("div.welovestackoverflow",$("div.sidebar")).get(0); (2认同)

Aus*_*ton 6

我正在寻找相同的东西,我的解决方案是这样的:

$('#el-id').focus().select();
Run Code Online (Sandbox Code Playgroud)

  • 但是你可以在textarea元素上使用它 - 这是我googled到达这里的问题.我没有完全阅读这个问题. (4认同)
  • 你不能在非输入上使用`focus()`,这就是这个问题. (3认同)

Wol*_*ack 6

您可以使用以下函数选择任何元素的内容:

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);
    }
};
Run Code Online (Sandbox Code Playgroud)

可以按如下方式调用此函数:

$('#selectme').selectText();
Run Code Online (Sandbox Code Playgroud)


Kim*_*ho6 5

适用于 Chrome 的更新版本:

function SelectText(element) {
    var doc = document;
    var text = doc.getElementById(element);    
    if (doc.body.createTextRange) { // ms
        var range = doc.body.createTextRange();
        range.moveToElementText(text);
        range.select();
    } else if (window.getSelection) {
        var selection = window.getSelection();
        var range = doc.createRange();
        range.selectNodeContents(text);
        selection.removeAllRanges();
        selection.addRange(range);

    }
}

$(function() {
    $('p').click(function() {
        SelectText("selectme");

    });
});
Run Code Online (Sandbox Code Playgroud)

http://jsfiddle.net/KcX6A/326/


Mad*_*aks 5

除了一些事情,我喜欢lepe的答案:

  1. 浏览器嗅探,jQuery或no不是最佳选择
  2. 如果obj的父级不支持createTextRange,则在IE8中不起作用
  3. 应该利用Chrome使用setBaseAndExtent的能力(IMO)
  4. 不会选择跨越多个DOM元素的文本("selected"元素中的元素).换句话说,如果在包含多个span元素的div上调用selText,则不会选择每个元素的文本.对我来说这是一个交易破坏者,YMMV.

这就是我想出来的,并点了一下lepe的灵感回答.我相信我会被嘲笑,因为这可能有点笨拙(实际上可能更多但我离题了).但它有效并避免浏览器嗅探,这就是重点.

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;
}
Run Code Online (Sandbox Code Playgroud)

而已.您看到的一些内容是为了便于阅读和/或方便.在最新版本的Opera,Safari,Chrome,Firefox和IE上测试了Mac.也在IE8中测试过.此外,我通常只在代码块中需要/当需要时声明变量,但jslint建议将它们全部声明为top.好的jslint.

编辑 我忘了包含如何将其与op的代码联系起来:

function SelectText(element) {
    $("#" + element).selectText();
}
Run Code Online (Sandbox Code Playgroud)

干杯