用单击鼠标选择所有DIV文本

169

当用户单击DIV时,如何高亮/选定DIV标记的内容...这个想法是所有文本都被高亮/选中,使得用户不需要手动用鼠标突出显示文本并可能错过一些文本?

例如,假设我们有一个以下的DIV:

<div id="selectable">http://example.com/page.htm</div>

当用户点击任何一个URL时,整个URL文本会被突出显示,这样他们就可以轻松地在浏览器中拖动所选文本或通过右键单击复制完整的URL。

谢谢!

15个回答

222

function selectText(containerid) {
    if (document.selection) { // IE
        var range = document.body.createTextRange();
        range.moveToElementText(document.getElementById(containerid));
        range.select();
    } else if (window.getSelection) {
        var range = document.createRange();
        range.selectNode(document.getElementById(containerid));
        window.getSelection().removeAllRanges();
        window.getSelection().addRange(range);
    }
}
<div id="selectable" onclick="selectText('selectable')">http://example.com/page.htm</div>

现在你需要将ID作为参数传递,这里的ID是"selectable",但它更具有全局性,允许你在任何地方多次使用它而不需要像chiborg提到的那样使用jQuery。

8
顺便提一下,您可以轻松地将此转换为jQuery点击事件处理程序,只需将document.getElementById('selectable')替换为this即可。 然后,您可以通过以下方式将功能非侵入性地添加到几个元素,例如容器中的多个div: jQuery('#selectcontainer div').click(selectText); - chiborg
4
此代码可在Chrome、Firefox、Safari(Mac)、Chrome和IE(Windows 9+, 未测试8)上正常运行。但似乎无法在iPad Mini(iOS6)或iPhone 4的Safari上工作,其他iOS或Android设备未确定。 - prototype
1
根据这篇文章,对于Opera浏览器(http://www.quirksmode.org/dom/range_intro.html),查询`if (window.getSelection) {`应该放在最前面。 - prototype
1
这个解决方案似乎在ie11中无法工作。有什么想法为什么会这样? - Swiss Mister
5
在Chrome 36版本以上,这会返回一个错误"不支持不连续的选择"。解决方法是在window.getSelection().addRange(range);之前添加window.getSelection().removeAllRanges(); - nHaskins
显示剩余3条评论

159

更新 2017:

要选择节点内容,请调用:

window.getSelection().selectAllChildren(
    document.getElementById(id)
);

这适用于所有现代浏览器,包括IE9+(在标准模式下)。

可运行示例:

function select(id) {
  window.getSelection()
    .selectAllChildren(
      document.getElementById("target-div") 
    );
}
#outer-div  { padding: 1rem; background-color: #fff0f0; }
#target-div { padding: 1rem; background-color: #f0fff0; }
button      { margin: 1rem; }
<div id="outer-div">
  <div id="target-div">
    Some content for the 
    <br>Target DIV
  </div>
</div>

<button onclick="select(id);">Click to SELECT Contents of #target-div</button>


以下原始答案已过时,因为window.getSelection().addRange(range);已被弃用

原始答案:

以上所有示例均使用:

    var range = document.createRange();
    range.selectNode( ... );

但问题在于它选择的是包括 DIV 标签等在内的节点本身。
为了选择节点的文本,按照 OP 的问题,您需要调用以下方法:
    range.selectNodeContents( ... )

因此,完整的代码片段将是:

    function selectText( containerid ) {

        var node = document.getElementById( containerid );

        if ( document.selection ) {
            var range = document.body.createTextRange();
            range.moveToElementText( node  );
            range.select();
        } else if ( window.getSelection ) {
            var range = document.createRange();
            range.selectNodeContents( node );
            window.getSelection().removeAllRanges();
            window.getSelection().addRange( range );
        }
    }

只要在元素的“click”侦听器内,您也可以使用“this”而不是基于ID获取元素。 - Zach Saucier
1
这就是你们所寻找的答案。 - Christine Cooper

71

这里有一个纯CSS4的解决方案:

.selectable{
    -webkit-touch-callout: all; /* iOS Safari */
    -webkit-user-select: all; /* Safari */
    -khtml-user-select: all; /* Konqueror HTML */
    -moz-user-select: all; /* Firefox */
    -ms-user-select: all; /* Internet Explorer/Edge */
    user-select: all; /* Chrome and Opera */

}

user-select是CSS模块4级规范的一个属性,目前仍然是草案和非标准的CSS属性,但浏览器对它的支持很好——请查看#search=user-select

.selectable{
    -webkit-touch-callout: all; /* iOS Safari */
    -webkit-user-select: all; /* Safari */
    -khtml-user-select: all; /* Konqueror HTML */
    -moz-user-select: all; /* Firefox */
    -ms-user-select: all; /* Internet Explorer/Edge */
    user-select: all; /* Chrome and Opera */

}
<div class="selectable">
click and all this will be selected
</div>

在MDN这里了解更多关于user-select的内容 在w3schools这里进行操作


4
+1 太赞了,太优雅的解决方案!在2017年9月进行测试,在FireFox和Chrome上完美运行但是在Microsoft Edge上不行!?有任何想法为什么会这样以及如何修复吗?谢谢! - Sam
1
Mino,谢谢,这个方法很有效!一次点击就可以选择整个元素。但是这样会使得无法选择文本的子集……你可能是想用-webkit-touch-callout: none;吗?我在使用all时收到了一个警告。不管怎样,这个设置在这里有什么作用呢?@Sam 在2020年,我看到user-select在MS Edge上也可以工作。更明智的头脑可能已经占据了主导地位。 - Bob Stein
如果任何元素的祖先元素设置了draggable属性,这个方法就不起作用。在Firefox和Safari中是如此。在Chrome中它是有效的。 - undefined

13

Neuroxik的回答非常有帮助。我在Chrome上遇到了一个问题,因为当我点击外部div时,它不起作用。我解决了这个问题,只需在添加新范围之前删除旧范围即可:

function selectText(containerid) {
    if (document.selection) {
        var range = document.body.createTextRange();
        range.moveToElementText(document.getElementById(containerid));
        range.select();
    } else if (window.getSelection()) {
        var range = document.createRange();
        range.selectNode(document.getElementById(containerid));
        window.getSelection().removeAllRanges();
        window.getSelection().addRange(range);
    }
}
<div id="selectable" onclick="selectText('selectable')">http://example.com/page.htm</div>

11

对于可编辑内容(不是常规输入),您需要使用selectNodeContents而不是仅使用selectNode。

注意:所有关于“document.selection”和“createTextRange()”的参考都是针对IE 8及以下版本... 如果您尝试执行此类复杂操作,则不太可能需要支持该版本。

function selectElemText(elem) {

    //Create a range (a range is a like the selection but invisible)
    var range = document.createRange();

    // Select the entire contents of the element
    range.selectNodeContents(elem);

    // Don't select, just positioning caret:
    // In front 
    // range.collapse();
    // Behind:
    // range.collapse(false);

    // Get the selection object
    var selection = window.getSelection();

    // Remove any current selections
    selection.removeAllRanges();

    // Make the range you have just created the visible selection
    selection.addRange(range);

}

6
使用文本区域字段,您可以使用以下内容:(通过谷歌)
<form name="select_all">

    <textarea name="text_area" rows="10" cols="80" 
    onClick="javascript:this.form.text_area.focus();this.form.text_area.select();">

    Text Goes Here 

    </textarea>
</form>

这是我观察到大多数网站的做法。他们只是用CSS样式来使其不像一个文本区域。

为什么不直接使用 this.focus();this.select(); 呢? - Taha Paksu

5

这段代码提供了你所需的功能。你需要做的是给那个div添加一个事件,以激活其中的fnSelect函数。一种快速的方法是直接在代码中加入以下内容(虽然不推荐这样做,而且也可能不起作用):

document.getElementById("selectable").onclick(function(){
    fnSelect("selectable");
});

显然,假设已经包含了链接到的片段。

5
我发现将这个函数封装成 jQuery 插件很有用:
$.fn.selectText = function () {
    return $(this).each(function (index, el) {
        if (document.selection) {
            var range = document.body.createTextRange();
            range.moveToElementText(el);
            range.select();
        } else if (window.getSelection) {
            var range = document.createRange();
            range.selectNode(el);
            window.getSelection().addRange(range);
        }
    });
}

因此,它成为了一个可重复使用的解决方案。然后你可以这样做:
<div onclick="$(this).selectText()">http://example.com/page.htm</div>

它会在div中选择测试。


1
请记得像Josillo的代码一样调用window.getSelection().removeAllRanges(); 另外:我建议将window.getSelection放在第一选项,因为这是HTML5标准,而document.selection是旧版IE对于IE8及更早版本的回退。 - Jan Aagaard

4

尝试这个,还可以添加到oncontextmenu中,这样可以快速访问扩展程序,以此方式输入。

<div onclick='window.getSelection().selectAllChildren(this)' id="selectable">http://example.com/page.htm</div>


3
尼科·雷: 这个简单的解决方案怎么样? :)
`<input style="background-color:white; border:1px white solid;" onclick="this.select();" id="selectable" value="http://example.com/page.htm">`

.....

Code before:

<textarea rows="20" class="codearea" style="padding:5px;" readonly="readonly">

以下是代码:

<textarea rows="20" class="codearea" style="padding:5px;" readonly="readonly" onclick="this.select();" id="selectable">

在我的代码中,仅有这部分onclick="this.select();" id="selectable"是有效的。一次鼠标点击即可选择代码框中的所有内容。

感谢Niko Lay的帮助!


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接