一次单击即可选择所有DIV文本


136

当用户单击DIV时如何突出显示/选择DIV标签的内容...这个想法是所有文本都被突出显示/选择,因此用户不需要用鼠标手动突出显示文本错过了一点文字?

例如,假设我们有一个DIV,如下所示:

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

...当用户单击该URL中的任何URL时,整个URL文本将突出显示,以便他们可以轻松地在浏览器中拖动选定的文本,或者单击鼠标右键复制整个URL。

谢谢!

Answers:


194

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是“可选的”,但是它更具全局性,允许您多次在任何地方使用它,而不必像chiborg所提到的那样使用jQuery。


8
顺便说一句,你可以很容易地变成一个jQuery的单击事件处理程序替换这document.getElementById('selectable')this。然后,您可以毫不jQuery('#selectcontainer div').click(selectText);
费力

3
在Chrome,FF,Safari(Mac)和Chrome和IE(未测试Windows 9 +,8)上,此功能正常运行。但它似乎无法在iPad Mini(iOS6)或iPhone 4的Safari上运行,不确定其他iOS或Android。
2013年

1
根据这篇文章,查询if (window.getSelection) {应该首先针对Opera(quirksmode.org/dom/range_intro.html
原型

1
此解决方案似乎在ie11中不起作用。知道为什么吗?
瑞士先生2014年

5
在Chrome版本36+中,这将返回错误“不支持不连续的选择”。解决方案是window.getSelection().removeAllRanges();window.getSelection().addRange(range);
nHaskins

122

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

您也可以使用this代替基于ID的元素,只要它在元素的click侦听器中即可。
Zach Saucier '18

44

有纯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

在MDN上用户选择阅读更多内容,并在w3scools中在此处使用


3
+1很棒的优雅解决方案!测试于2017年9月,它在FireFox和Chrome上可以完美运行,但不在MICROSOFT EDGE中!!有什么想法为什么不解决以及如何解决呢?谢谢!
山姆

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>

9

对于内容可编辑的内容(不是常规输入),您需要使用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

使用文本区域字段,您可以使用此字段:(通过Google)

<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();
塔哈·帕克苏

5

该代码片段提供了您所需的功能。您需要做的是在该div中添加一个事件,该事件将在其中激活fnSelect。您完全不应该这样做并且可能不起作用的快速hack看起来像这样:

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
记住要调用window.getSelection()。removeAllRanges(); 就像Josillo的代码一样。另外:我建议将window.getSelect作为第一个选项,因为这是HTML5标准和document.selection是IE8和更早版本的旧IE后备。
Jan Aagaard 2014年

3

这个简单的解决方案怎么样?:)

<input style="background-color:white; border:1px white solid;" onclick="this.select();" id="selectable" value="http://example.com/page.htm">

当然,它不是像您提到的div-construction,但仍然对我有用。


1
简洁的解决方案,但这不考虑输入或textarea字段以外的元素中的文本。
JoePC

3

Niko Lay:这个简单的解决方案怎么样?:)

`<input style="background-color:white; border:1px white solid;" onclick="this.select();" id="selectable" value="http://example.com/page.htm">`

.....

之前的代码:

<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!


0
$.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);
        }
    });
}

上述答案在Chrome中不起作用,因为addRange删除了之前添加的范围。除了使用CSS进行伪选择外,我没有找到任何解决方案。


对于某人来说,这段代码可能对我测试和发现它在最新版本的Chrome中都有用:$ .fn.selectText = function(){return $(this).each(function(index,el){if(document。选择){var range = document.body.createTextRange(); range.moveToElementText(el); range.select();} if if(window.getSelection){var range = document.createRange(); range.selectNode(el ); window.getSelection()。removeAllRanges(); window.getSelection()。addRange(range);}}));}
Haider Abbas's

0

通过将css属性的user-select设置为all可以轻松实现。像这样:

div.anyClass {
  user-select: all;
}

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.