Selecting text in an element (akin to highlighting with your mouse)
我希望用户单击链接,然后在另一个元素(而不是输入)中选择HTML文本。
"选择"是指您将鼠标拖到文本上方来选择文本的方式。 这一直是研究的负担,因为每个人都用其他术语谈论"选择"或"突出显示"。
这可能吗? 到目前为止,我的代码:
HTML:
1 2 | Select Code <code id="xhtml-code">Some Code here </wyn> |
JS:
1 2 3 | function SelectText(element) { $("#" + element).select(); } |
我是否明显遗漏了一些东西?
纯Javascript
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 | 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')); |
1 2 3 4 5 6 7 | <p> Some text goes here! </p><p> Moar text! </p> <p class="click-me">Click me! </p> |
这是一个工作示例。对于那些正在寻找jQuery插件的人,我也做了其中之一。
jQuery(原始答案)
我在此线程中找到了解决方案。我能够修改给定的信息,并将其与一些jQuery混合在一起,以创建一个功能强大的函数来选择任何元素中的文本,而与浏览器无关:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 | 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); } } |
这是一个没有浏览器嗅探并且不依赖jQuery的版本:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 | 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:只需单击一下,即可选择
1 2 3 4 5 | $(function() { $("code").click(function() { $(this).selText().addClass("selected"); }); }); |
示例2:单击按钮时,在iframe中选择一个元素:
1 2 3 4 5 | $(function() { $("button").click(function() { $("iframe").contents().find("#selectme").selText(); }); }); |
注意:请记住,iframe源应位于同一域中,以防止出现安全错误。
jQuery插件:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 | 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; } |
我在IE8,Firefox,Opera,Safari,Chrome(当前版本)中对其进行了测试。我不确定它是否适用于较旧的IE版本(因为我不在乎)。
这个线程包含了很多很棒的东西。但是由于"安全错误",我无法使用FF 3.5b99 + FireBug在此页面上正确执行此操作。
pe!我可以使用此代码选择整个右侧边栏,希望它对您有所帮助:
1 2 3 4 5 6 | var r = document.createRange(); var w=document.getElementById("sidebar"); r.selectNodeContents(w); var sel=window.getSelection(); sel.removeAllRanges(); sel.addRange(r); |
PS:-我无法使用jquery选择器返回的对象,例如
1 2 3 4 5 | var w=$("div.welovestackoverflow",$("div.sidebar")); //this throws **security exception** r.selectNodeContents(w); |
我在寻找相同的东西,我的解决方案是这样的:
1 | $('#el-id').focus().select(); |
您可以使用以下功能选择任何元素的内容:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 | 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); } }; |
该函数可以如下调用:
1 | $('#selectme').selectText(); |
除了以下几点,我喜欢lepe的回答:
这就是我想出的,点头表示lepe会得到灵感。我敢肯定我会被嘲笑的,因为这也许有点笨拙(实际上可能会更多,但是我离题了)。但这有效并且避免了浏览器嗅探,这就是重点。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 | 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。
编辑
我忘了包括如何将其绑定到操作码中:
1 2 3 | function SelectText(element) { $("#" + element).selectText(); } |
干杯
适用于chrome的更新版本:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 | 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/
对于任何标签,都可以通过此简短代码选择该标签内的所有文本。它将用黄色突出显示整个标签区域,并单击一下即可选择其中的文本。
1 2 3 4 5 6 7 8 9 | document.onclick = function(event) { var range, selection; event.target.style.backgroundColor = 'yellow'; selection = window.getSelection(); range = document.createRange(); range.selectNodeContents(event.target); selection.removeAllRanges(); selection.addRange(range); }; |
lepe-很好,谢谢!
我将您的代码放在插件文件中,然后将其与每个语句结合使用,这样您就可以在一个页面上具有多个pre标签和多个"全选"链接,并且可以选择正确的pre来突出显示:
1 2 3 4 5 6 7 8 9 10 | <script type="text/javascript" src="../js/jquery.selecttext.js"> <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都有可能。
这是另一个以字符串形式获取所选文本的简单解决方案,您可以轻松地使用此字符串将div元素子代添加到代码中:
1 2 3 4 5 6 7 8 9 10 11 12 13 | 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(); |
我的特殊用例是在一个可编辑的span元素内选择一个文本范围,据我所知,此处的任何答案都未描述。
主要区别在于,您必须将
If the startNode is a Node of type Text, Comment, or CDATASection,
then startOffset is the number of characters from the start of
startNode. For other Node types, startOffset is the number of child
nodes between the start of the startNode.
这里是一个代码示例:
1 2 3 4 5 6 7 8 9 10 11 12 | 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); |
其他相关文件:
范围
选拔
Document.createRange()
Window.getSelection()
Tim的方法非常适合我的情况-在替换以下语句后,为IE和FF选择div中的文本:
1 | range.moveToElementText(text); |
具有以下内容:
1 | range.moveToElementText(el); |
通过使用以下jQuery函数单击以选择div中的文本:
1 2 3 4 5 | $(function () { $("#divFoo").click(function () { selectElementText(document.getElementById("divFoo")); }) }); |
在Chrome的"否则"中添加了
在下面制作此脚本,以选择具有
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 | 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 ); } } ); } ); |
根据
Trigger the select event of each matched element. This causes all of the functions that have been bound to that select event to be executed, and calls the browser's default select action on the matching element(s).
有您的解释为什么jQuery