เลือกข้อความ DIV ทั้งหมดด้วยการคลิกเมาส์เพียงครั้งเดียว


143

วิธีการเน้น / เลือกเนื้อหาของแท็ก DIV เมื่อผู้ใช้คลิกที่ DIV ... แนวคิดก็คือข้อความทั้งหมดจะถูกเน้น / เลือกดังนั้นผู้ใช้จึงไม่จำเป็นต้องไฮไลต์ข้อความด้วยเมาส์ด้วยตนเองและอาจ พลาดข้อความไปหน่อย?

ตัวอย่างเช่นสมมติว่าเรามี DIV ดังต่อไปนี้:

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

... และเมื่อผู้ใช้คลิกที่ URL ใด ๆ ข้อความ URL ทั้งหมดจะถูกไฮไลต์เพื่อให้สามารถลากข้อความที่เลือกไปรอบ ๆ ในเบราว์เซอร์ได้อย่างง่ายดายหรือคัดลอก URL ที่สมบูรณ์ด้วยการคลิกขวา

ขอบคุณ!

คำตอบ:


199

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 เป็นอาร์กิวเมนต์ซึ่งในกรณีนี้คือ "เลือกได้" แต่เป็นแบบสากลทำให้คุณสามารถใช้งานได้ทุกที่หลายครั้งโดยไม่ต้องใช้ตามที่ chiborg กล่าวไว้ jQuery


8
BTW คุณสามารถเปลี่ยนสิ่งนี้ให้เป็นตัวจัดการเหตุการณ์คลิก jQuery แทนที่document.getElementById('selectable')ด้วยthisไฟล์. จากนั้นคุณสามารถเพิ่มฟังก์ชันอย่างสงบเสงี่ยมให้กับองค์ประกอบต่างๆเช่น div หลายตัวในคอนเทนเนอร์: jQuery('#selectcontainer div').click(selectText);
chiborg

3
ใช้งานได้ดีบน Chrome, FF, Safari (Mac) และ Chrome และ IE (ไม่ได้ทดสอบ Windows 9+, 8) แต่ดูเหมือนจะไม่ทำงานบน Safari บน iPad Mini (iOS6) หรือ iPhone 4 ไม่แน่ใจเกี่ยวกับ iOS หรือ Android อื่น ๆ
ต้นแบบ

1
ในบทความนี้ข้อความค้นหาif (window.getSelection) {ควรมาก่อนสำหรับ Opera ( quirksmode.org/dom/range_intro.html )
ต้นแบบ

1
โซลูชันนี้ดูเหมือนจะไม่ทำงานใน ie11 คิดว่าทำไม?
Swiss Mister

5
ใน Chrome เวอร์ชัน 36+ สิ่งนี้จะแสดงข้อผิดพลาด "ไม่รองรับการเลือกที่ไม่ชัดเจน" วิธีแก้คือต้องเพิ่มwindow.getSelection().removeAllRanges();ก่อนwindow.getSelection().addRange(range);
nHaskins

128

อัพเดท 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( ... );

แต่ปัญหาคือมันเลือก Node เองรวมถึง DIV tag เป็นต้น

ในการเลือกข้อความของ Node ตามคำถาม 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 ได้ตราบใดที่อยู่ในclickListener ขององค์ประกอบ
Zach Saucier

46

มีโซลูชัน 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 ที่ไม่ได้มาตรฐาน แต่เบราว์เซอร์รองรับได้ดี - ดูการค้นหา #

.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 */

}
<div class="selectable">
click and all this will be selected
</div>

อ่านเพิ่มเติมเกี่ยวกับการเลือกผู้ใช้ที่นี่บน MDNและเล่นได้ที่นี่ใน w3scools


4
+1 สุดยอดโซลูชันที่ยอดเยี่ยม! ทดสอบเมื่อกันยายน 2017 และทำงานได้อย่างไร้ที่ติบน FireFox และ Chrome แต่ไม่อยู่ใน MICROSOFT EDGE! ความคิดใด ๆ ทำไมไม่และวิธีแก้ไข ขอบคุณ!
แซม

มิโนขอบคุณสิ่งนี้! คลิกเดียวเลือกองค์ประกอบทั้งหมด อย่างไรก็ตามทำให้ไม่สามารถปัดเพื่อเลือกชุดย่อยของข้อความได้ . . . คุณอาจหมายถึง-webkit-touch-callout: none;? allฉันได้รับการแจ้งเตือนสำหรับ อย่างไรก็ตามการตั้งค่านั้นทำอะไรที่นี่? . . . @Sam ในปี 2020 ฉันเห็นuser-selectผลงานบน MS Edge หัว Saner อาจมีชัย
Bob Stein

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();?
Taha Paksu

5

ตัวอย่างข้อมูลนี้ให้ทำงานแบบที่คุณต้องการ สิ่งที่คุณต้องทำคือเพิ่มเหตุการณ์ลงใน div ที่เปิดใช้งาน fnSelect แฮ็คด่วนที่คุณไม่ควรทำโดยสิ้นเชิงและอาจไม่ได้ผลจะมีลักษณะดังนี้:

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 เป็นทางเลือกเก่าของ IE สำหรับ IE8 และรุ่นก่อนหน้า
Jan Aagaard

3

วิธีง่ายๆนี้เป็นอย่างไร? :)

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

แน่นอนว่ามันไม่ใช่โครงสร้าง Div อย่างที่คุณพูดถึง แต่ก็ยังใช้ได้สำหรับฉัน


1
วิธีแก้ปัญหาที่กระชับ แต่ไม่ได้คำนึงถึงข้อความในองค์ประกอบอื่นนอกเหนือจากฟิลด์อินพุตหรือพื้นที่ข้อความ
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!


1

ทำได้อย่างง่ายดายด้วยคุณสมบัติ css ที่ผู้ใช้เลือกตั้งค่าเป็นทั้งหมด แบบนี้:

div.anyClass {
  user-select: all;
}


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 ();} else if (window.getSelection) {var range = document.createRange (); range.selectNode (el ); window.getSelection (). removeAllRanges (); window.getSelection (). addRange (ช่วง);}}); }
Haider Abbas
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.