在一个元素中选择文本(类似于用鼠标突出显示)

问题描述:

我想让用户点击一个链接,然后选择另一个元素中的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(); 
} 

我缺少的东西公然明显?

我已经找到了为此,感谢TheVillageIdiot发现的this thread。我能够修改给出的信息,并将其与位的jQuery,以创造一个完全真棒功能选择在任何元素中的文本,无论浏览器:

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

EDIT(11年9月28日) :

这已经有一段时间,因为这个答案进行了更新,我已经学到了很多东西作为一个开发者,因为我提出和回答这个问题。它也比我想象的要多得多。我想提供比原来的我张贴,一个不依靠过时jQuery方法,或在jQuery的一切,对于这个问题更好的解决方案。你可以使用jQuery来帮助你吗?当然,但如果没有jQuery并使用功能检测代替浏览器嗅探,您可以实现相同的结果,为什么不呢?所以,下面是我的更新答案:

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>

这里是一个更新working demo。对于那些正在寻找jQuery插件的人,我制作了one of those too(再次更新)。

已更新(1/10/2012)对于webkit,Per Tim Down的建议,setBaseAndExtent()不需要。

修订版(2014年9月19日)嵌入式代码段

+0

注意:这与jQuery 1.3.2一起工作...不确定它是否能在1.4.x中工作 – Jason 2010-02-05 23:09:50

+0

在Firefox中与jQuery 1.4.3不兼容。 – Cerin 2011-04-06 15:41:01

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

select() jQuery的文档:

触发每一个匹配元素的选择的事件。这会导致所有的已绑定到要执行的是select事件的功能,并调用匹配元素(S)在浏览器的默认选择的动作。

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

+4

我不想突出显示与CSS样式的文本。我希望文本被选中。 – Jason 2009-06-12 07:00:13

thread包含真的很奇妙的东西。但由于“安全错误”,我无法使用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.welove*",$("div.sidebar")); 

    //this throws **security exception** 

    r.selectNodeContents(w); 
+2

您需要从jQuery获取元素,因为您试图选择一个jQuery对象:var w = $(“div.welove*”,$(“div.sidebar”))。get(0); – Blixt 2009-06-12 07:33:55

+0

不起作用...我得到一个错误“对象不支持这种方法”,它突出了第一行。我做了一些挖掘,发现有一个“document.body.createTextRange()”,但然后“selectNodeContents”不起作用....这是在IE – Jason 2009-06-12 15:22:19

+0

我读到你找到的线程...惊人的...我能够根据适用于所有浏览器的信息创建一个功能。 非常感谢!我的解决方案发布 – Jason 2009-06-12 15:37:40

Jason的代码不能被用于在iframe内的元件(如范围从窗口和文档不同)。我固定的问题,我改性它以便被用作任何其他jQuery插件(环连接):

实施例1:所有文本选择内部<代码>与单点击代码,并添加类“中选择了”:

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

例2:在按一下按钮,选择的元素在iFrame中:

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

我在IE8,Firefox,歌剧,Safari浏览器,Chrome浏览器(当前版本)进行了测试。我不确定它是否适用于较旧的IE版本(我真的不在乎)。

这里有没有浏览器嗅探一个版本,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); 
+2

谢谢蒂姆,我不得不添加el.focus();到函数的顶部。也许只有当某些浏览器中的某些元素被点击触发功能时才需要它。对我来说,FF 3.6 – Luckyrat 2010-09-08 14:24:30

+29

-1中的一个按钮元素,还不够jQuery。 – Cerin 2011-04-06 15:30:43

添的方法完全适用于我的情况 - 选择文本在IE和FF一个div后,我更换了以下声明:

range.moveToElementText(text); 

下列要求:

range.moveToElementText(el); 

中日文字e div通过点击以下jQuery功能进行选择:

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

啊是的。感谢您的发现。我编辑了我的答案。 – 2010-08-23 08:09:17

lepe - 这对我很好,谢谢! 我把你的代码的插件文件,然后用每个语句中使用它结合,所以你可以有多个预标签和多个“全选”一个页面上的链接,并挑选出正确的预突出:

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

我正在寻找同样的事情,我的解决办法是这样的:

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

这里是让所选择的字符串形式的文字另一个简单的解决方案,可以方便地使用这个字符串附加一个div元素的孩子我n要你的代码:

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

的更新版本,在铬工作:

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. 浏览器嗅探,jQuery或不是最优
  2. DRY
  3. 不IE8中工作如果obj的家长不支持的createTextRange
  4. Chrome的使用setBaseAndExtent能力应该加以利用(IMO)
  5. 将不会选择文本跨多个DOM元素跨越(内要素“选定”元素)。换句话说,如果您在包含多个跨度元素的div上调用selText,那么将选择而不是选择每个元素的文本。对我来说,这对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; 
} 

就是这样。你看到的一些是为了可读性和/或便利性。在Mac,Opera,Safari,Chrome,Firefox和IE等最新版本中进行测试。还在IE8中测试过。另外,我通常只在代码块内部/需要时声明变量,但jslint建议将它们全部声明为最高。好的jslint。

编辑 我忘了,包括如何对运算的代码配合这样的:

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

干杯

新增jQuery.browser.webkit到“否则,如果” Chrome浏览器。无法在Chrome 23中使用此工作。

请如下选择<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); 
     } 
    }); 
}); 

我的具体使用情况是选择一个可编辑span元素,其中,据我所见,没有任何这里的答案里面描述的一个文本范围。

的主要区别是,你必须Text类型的节点传递到Range对象,如所描述in the documentation of Range.setStart()

如果的StartNode是类型文本,注释,或的CDATASection的节点, 然后startOffset是从 startNode开始的字符数。对于其他节点类型,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); 

其他相关文章:
Range
Selection
Document.createRange()
Window.getSelection()

您可以使用下面的函数来选择任何元素的内容:

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

对于任何一个标签可以通过这种短期和简单的代码选择标签内的所有文本。它会突出显示黄色的整个标签区域,并在其中单击选择文本。

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