我想让用户点击一个链接,然后它在另一个元素(不是输入)中选择HTML文本。

我所说的“选择”是指通过拖动鼠标选择文本的相同方式。这一直是一个难以研究的问题,因为每个人都在谈论“选择”或“突出”。

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

HTML:

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

JS:

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

我是不是错过了什么显而易见的东西?


当前回答

我喜欢lepe的回答,除了几件事:

浏览器嗅探,不管有没有jQuery都不是最佳选择 干 如果obj的父对象不支持createTextRange,则在IE8中无法工作 Chrome的能力使用setbaseanddextent应该被利用(IMO) 不会选择跨越多个DOM元素(“选定”元素中的元素)的文本。换句话说,如果在包含多个span元素的div上调用selText,它将不会选择每个元素的文本。这对我来说是一个致命伤,YMMV。

这是我想到的,并向麻风病的答案致敬。我相信我会被嘲笑,因为这可能有点笨拙(实际上可能更严重,但我跑题了)。但它有效,避免了浏览器嗅探,这就是重点。

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

就是这样。你看到的一些是为了可读性和/或便利性。在Mac上测试最新版本的Opera, Safari, Chrome, Firefox和IE。也在IE8中测试过。此外,我通常只声明变量,如果/当需要在代码块内,但jslint建议它们都声明在顶部。jslint。

编辑 我忘记了如何将其绑定到操作代码中:

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

干杯

其他回答

这是另一个简单的解决方案,以字符串的形式获得选定的文本,你可以使用这个字符串很容易地追加一个div元素子元素到你的代码:

var text = '';

if (window.getSelection) {
    text = window.getSelection();

} else if (document.getSelection) {
    text = document.getSelection();

} else if (document.selection) {
    text = document.selection.createRange().text;
}

text = text.toString();

这个线程(死链接)包含了非常棒的东西。但由于“安全错误”,我无法在这个页面上使用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); 

PS:-我不能使用jquery选择器返回的对象

   var w=$("div.welovestackoverflow",$("div.sidebar"));
   
   //this throws **security exception**

   r.selectNodeContents(w);

我喜欢lepe的回答,除了几件事:

浏览器嗅探,不管有没有jQuery都不是最佳选择 干 如果obj的父对象不支持createTextRange,则在IE8中无法工作 Chrome的能力使用setbaseanddextent应该被利用(IMO) 不会选择跨越多个DOM元素(“选定”元素中的元素)的文本。换句话说,如果在包含多个span元素的div上调用selText,它将不会选择每个元素的文本。这对我来说是一个致命伤,YMMV。

这是我想到的,并向麻风病的答案致敬。我相信我会被嘲笑,因为这可能有点笨拙(实际上可能更严重,但我跑题了)。但它有效,避免了浏览器嗅探,这就是重点。

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

就是这样。你看到的一些是为了可读性和/或便利性。在Mac上测试最新版本的Opera, Safari, Chrome, Firefox和IE。也在IE8中测试过。此外,我通常只声明变量,如果/当需要在代码块内,但jslint建议它们都声明在顶部。jslint。

编辑 我忘记了如何将其绑定到操作代码中:

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

干杯

麻风病-这对我很有效,谢谢! 我把你的代码放在一个插件文件中,然后与每个语句一起使用,这样你就可以在一个页面上有多个pre标签和多个“Select all”链接,它会挑出正确的pre来突出显示:

<script type="text/javascript" src="../js/jquery.selecttext.js"></script>
<script type="text/javascript">
  $(document).ready(function() { 
        $(".selectText").each(function(indx) {
                $(this).click(function() {                 
                    $('pre').eq(indx).selText().addClass("selected");
                        return false;               
                    });
        });
  });

根据jQuery的select()文档:

触发每个匹配元素的选择事件。这将导致执行绑定到该选择事件的所有函数,并对匹配的元素调用浏览器的默认选择操作。

这就是为什么jQuery select()在这种情况下不起作用的原因。