在元素中select文本(类似于用鼠标突出显示)

我想让用户点击一个链接,然后在另一个元素( 不是input)中selectHTML文本。

通过“select”我的意思是你将通过拖动鼠标select文本相同的方式。 这是一个研究的熊,因为每个人都在谈论“select”或“突出”的其他条款。

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

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

我错过了明显的东西吗?

我find了一个解决scheme,感谢TheVillageIdiot发现的这个线程 。 我可以修改给定的信息,并将其与一些jQuery混合,创build一个完全真棒函数来select任何元素中的文本,而不pipe浏览器:

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

编辑(9/28/11):

自从这个答案被更新之后已经有一段时间了,自从我问及回答这个问题以来,我从开发者那里学到了很多东西。 它也得到了比我想象的更多的关注。 我想提供一个更好的解决scheme,比我发布的原始的,一个不依赖于jQuery的方法,或jQuery的所有事情。 你可以使用jQuery来帮助你吗? 当然,但是如果你可以在没有jQuery的情况下实现相同的结果,并且使用function检测而不是浏览器嗅探,为什么不呢? 所以下面是我更新的答案:

 function SelectText(element) { var doc = document , text = doc.getElementById(element) , range, selection ; if (doc.body.createTextRange) { range = document.body.createTextRange(); range.moveToElementText(text); range.select(); } else if (window.getSelection) { selection = window.getSelection(); range = document.createRange(); range.selectNodeContents(text); selection.removeAllRanges(); selection.addRange(range); } } document.onclick = function(e) { if (e.target.className === 'click') { SelectText('selectme'); } }; 
 <div id="selectme"><p>Some text goes here!</p><p>Moar text!</p></div> <p class="click">Click me!</p> 

这里有一个没有浏览器嗅探,不依赖于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); 

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

示例1:通过单击select<code>标签内的所有文本,并添加“selected”类:

 $(function() { $("code").click(function() { $(this).selText().addClass("selected"); }); }); 

例2:点击button,在Iframe中select一个元素:

 $(function() { $("button").click(function() { $("iframe").contents().find("#selectme").selText(); }); }); 

注意:请记住,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; } 

我testing了IE8,Firefox,Opera,Safari,Chrome(当前版本)。 我不确定它是否适用于较旧的IE版本(真诚我不在乎)。

这个线程包含真正美妙的东西。 但是由于“安全错误”,我无法使用FF 3.5b99 + FireBug在此页面上正确执行此操作。

Yipee! 我能够select这个代码的整个右手侧栏希望它可以帮助你:

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

PS: – 我无法使用由jqueryselect器返回的对象

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

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

 $('#el-id').focus().select(); 

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

  1. 浏览器嗅探,jQuery或否是不是最佳的
  2. 如果obj的父类不支持createTextRange,则在IE8中不起作用
  3. Chrome能够使用setBaseAndExtent (IMO)
  4. 不会select横跨多个DOM元素的文本(“selected”元素中的元素)。 换句话说,如果在包含多个span元素的div上调用selText ,它将不会select每个元素的文本。 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; } 

而已。 你看到的一些是为了可读性和/或便利性。 最新版本的Opera,Safari,Chrome,Firefox和IE在Mac上进行testing。 也在IE8中testing。 此外,我通常只声明variables,如果/当需要在代码块内,但jslintbuild议他们都宣布最高。 好的jslint。

编辑我忘了包括如何将此代码绑定到操作代码:

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

干杯

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

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

你可以使用下面的函数来select任何元素的内容:

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

这个函数可以被调用如下:

 $('#selectme').selectText(); 

lepe – 这对我很好,谢谢! 我把你的代码放在一个插件文件中,然后将它与每个语句结合使用,这样你就可以在一个页面上有多个预标签和多个“全选”链接,并挑选出正确的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; }); }); }); 

看看Selection对象 (Gecko引擎)和TextRange对象 (Trident引擎)。我不知道任何具有跨浏览器支持的JavaScript框架,但是我从来没有去寻找它,所以甚至有可能jQuery有它。

蒂姆的方法完全适合我的情况 – 在replace下面的语句之后,为IE和FFselectdiv中的文本:

 range.moveToElementText(text); 

具体如下:

 range.moveToElementText(el); 

div中的文本是通过点击以下jQuery函数来select的:

 $(function () { $("#divFoo").click(function () { selectElementText(document.getElementById("divFoo")); }) }); 

这里是另一个简单的解决scheme,以string的forms获取选定的文本,你可以使用这个string很容易地附加一个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(); 

为Chrome添加jQuery.browser.webkit到“else if”。 无法在Chrome 23中正常工作。

在下面制作这个脚本,用于select具有class="code"<pre>标记中的内容。

 jQuery( document ).ready(function() { jQuery('pre.code').attr('title', 'Click to select all'); jQuery( '#divFoo' ).click( function() { var refNode = jQuery( this )[0]; if ( jQuery.browser.msie ) { var range = document.body.createTextRange(); range.moveToElementText( refNode ); range.select(); } else if ( jQuery.browser.mozilla || jQuery.browser.opera || jQuery.browser.webkit ) { var selection = refNode.ownerDocument.defaultView.getSelection(); console.log(selection); var range = refNode.ownerDocument.createRange(); range.selectNodeContents( refNode ); selection.removeAllRanges(); selection.addRange( range ); } else if ( jQuery.browser.safari ) { var selection = refNode.ownerDocument.defaultView.getSelection(); selection.setBaseAndExtent( refNode, 0, refNode, 1 ); } } ); } ); 

根据select()的jQuery文档:

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

有你的解释,为什么jQuery select()在这种情况下不起作用。

我特别的用例是在一个可编辑的span元素中select一个文本范围,就我所知,这里没有任何回答。

主要区别在于您必须将types为Text的节点传递给Range对象,如Range.setStart()的文档中所述 :

如果startNode是Text,Comment或CDATASectiontypes的节点,则startOffset是从startNode开始的字符数。 对于其他节点types,startOffset是startNode开始之间的子节点数量。

Text节点是span元素的第一个子节点,所以要获取它,请访问span元素的childNodes[0] 。 其余与大多数其他答案相同。

这里有一个代码示例:

 var startIndex = 1; var endIndex = 5; var element = document.getElementById("spanId"); var textNode = element.childNodes[0]; var range = document.createRange(); range.setStart(textNode, startIndex); range.setEnd(textNode, endIndex); var selection = window.getSelection(); selection.removeAllRanges(); selection.addRange(range); 

其他相关文件:
范围
select
Document.createRange()
Window.getSelection()