2009-06-12 74 views
349

我想讓用戶點擊一個鏈接,然後選擇另一個元素中的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(); 
} 

我缺少的東西公然明顯?

回答

515

我已經找到了爲此,感謝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

2

看看Selection object(Gecko引擎)和TextRange object(Trident引擎)。我不知道任何支持跨瀏覽器支持的JavaScript框架,但我從來沒有找過它,所以甚至有可能jQuery擁有它。

0

select() jQuery的文檔:

觸發每一個匹配元素的選擇的事件。這會導致所有的已綁定到要執行的是select事件的功能,並調用匹配元素(S)在瀏覽器的默認選擇的動作。

有你的解釋爲什麼jQuery select()不會在這種情況下工作。

+4

我不想突出顯示與CSS樣式的文本。我希望文本被選中。 – Jason 2009-06-12 07:00:13

12

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.welovestackoverflow",$("div.sidebar")); 

    //this throws **security exception** 

    r.selectNodeContents(w); 
+2

您需要從jQuery獲取元素,因爲您試圖選擇一個jQuery對象:var w = $(「div.welovestackoverflow」,$(「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

16

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版本(我真的不在乎)。

104

這裏有沒有瀏覽器嗅探一個版本,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

1

添的方法完全適用於我的情況 - 選擇文本在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

3

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

5

我正在尋找同樣的事情,我的解決辦法是這樣的:

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

這裏是讓所選擇的字符串形式的文字另一個簡單的解決方案,可以方便地使用這個字符串附加一個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(); 
4

的更新版本,在鉻工作:

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/

5

我喜歡萊佩的答案,除了幾件事情:

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

乾杯

0

新增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); 
     } 
    }); 
}); 
0

我的具體使用情況是選擇一個可編輯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()

4

您可以使用下面的函數來選擇任何元素的內容:

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

對於任何一個標籤可以通過這種短期和簡單的代碼選擇標籤內的所有文本。它會突出顯示黃色的整個標籤區域,並在其中單擊選擇文本。

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); 
}; 
相關問題