ป้องกันการเลือกข้อความหลังจากดับเบิลคลิก


294

ฉันจัดการเหตุการณ์ dblclick ในช่วงเวลาหนึ่งในเว็บแอปของฉัน ผลข้างเคียงคือการคลิกสองครั้งที่เลือกข้อความบนหน้า ฉันจะป้องกันไม่ให้สิ่งที่เลือกนี้เกิดขึ้นได้อย่างไร

คำตอบ:


351
function clearSelection() {
    if(document.selection && document.selection.empty) {
        document.selection.empty();
    } else if(window.getSelection) {
        var sel = window.getSelection();
        sel.removeAllRanges();
    }
}

คุณยังสามารถใช้สไตล์เหล่านี้กับช่วงขยายสำหรับเบราว์เซอร์ที่ไม่ใช่ IE และ IE10 ทั้งหมด:

span.no_selection {
    user-select: none; /* standard syntax */
    -webkit-user-select: none; /* webkit (safari, chrome) browsers */
    -moz-user-select: none; /* mozilla browsers */
    -khtml-user-select: none; /* webkit (konqueror) browsers */
    -ms-user-select: none; /* IE10+ */
}

44
มีวิธีใดที่จะป้องกันการเลือกจริง ๆ ไม่เหมือนกับการลบการเลือกหลังจากข้อเท็จจริงหรือไม่ นอกจากนี้ข้อที่สองของคุณหากข้อความอาจอยู่ในส่วนอื่นถ้าอ่านได้ดีขึ้น
David

8
ดีที่สุดที่จะใช้ -webkit- คำนำหน้า (นี่คือคำนำหน้าที่ต้องการสำหรับเบราว์เซอร์ที่ใช้ Webkit) นอกเหนือจาก -moz- (และ -khtml- หากคุณมีผู้ชม Konqueror จำนวนมาก)
หนังตา

3
ตอนนี้มีให้บริการใน IE10 แล้ว-ms-user-select: none;โปรดดูblogs.msdn.com/b/ie/archive/2012/01/11/… @PaoloBergantino
lemon

1
@TimHarper: เท่าที่โซลูชั่น Javascript ใช้ห้องสมุดแน่นอน ไม่แน่ใจจริงๆว่าทำไมจึงรับประกัน downvote
เปาโล Bergantino

14
มีความแตกต่างระหว่างการปิดใช้งานการเลือกเมื่อดับเบิลคลิกและปิดการใช้งานอย่างสมบูรณ์ ครั้งแรกที่เพิ่มการใช้งาน ครั้งที่สองลดลง
Robo Robok

112

ในจาวาสคริปต์ธรรมดา:

element.addEventListener('mousedown', function(e){ e.preventDefault(); }, false);

หรือกับ jQuery:

jQuery(element).mousedown(function(e){ e.preventDefault(); });

26
ใช่ฉันใช้สิ่งนี้เพื่อแก้ปัญหาเดียวกับที่ฉันมี (+1) ยกเว้นแทนที่จะreturn falseใช้event.preventDefault()ซึ่งไม่ได้ฆ่าตัวจัดการอื่น ๆ ที่คุณอาจมีใน mousedown
Simon East

2
สิ่งนี้จะแบ่งองค์ประกอบ textarea ในหน้า :(
john ktejik

1
@johnktejik เฉพาะถ้าelementเป็น textarea ใช่
fregante

11
คาดว่าจะมีตัวจัดการเหตุการณ์นี้มอบหมายให้ "dblclick" - แต่มันไม่ทำงานซึ่งแปลกมาก ด้วย "mousedown" คุณจะป้องกันไม่ให้เลือกข้อความโดยการลาก
corwin.amber

74

หากต้องการป้องกันการเลือกข้อความหลังจากดับเบิลคลิก:

คุณสามารถใช้MouseEvent#detailคุณสมบัติ สำหรับเหตุการณ์ที่มีการวางเมาส์หรือการวางเมาส์มันเป็น 1 บวกจำนวนคลิกปัจจุบัน

document.addEventListener('mousedown', function (event) {
  if (event.detail > 1) {
    event.preventDefault();
    // of course, you still do not know what you prevent here...
    // You could also check event.ctrlKey/event.shiftKey/event.altKey
    // to not prevent something useful.
  }
}, false);

ดูhttps://developer.mozilla.org/en-US/docs/Web/API/UIEvent/detail


4
นี่มันเจ๋งมาก! ใช้งานได้ใน Firefox 53
Zaroth

6
นี่ควรเป็นคำตอบที่ยอมรับได้ ทุกอย่างที่นี่ป้องกันการเลือกเมาส์ใด ๆ (หรือแย่กว่า) แทนที่จะตอบคำถามของ OP " ป้องกันการเลือกข้อความหลังจากดับเบิลคลิก "
billynoah

1
ใช้งานได้ใน Chrome ด้วย
KS74

1
ใช้ได้กับ IE 11 Windows 10 =) ขอบคุณที่แบ่งปันสิ่งนี้
Fernando Vieira

ใช้(event.detail === 2)เพื่อป้องกันการดับเบิลคลิกเท่านั้น (และไม่ใช่การคลิกสามครั้งและอื่น ๆ )
Robin Stewart

32

FWIW ฉันตั้งค่าuser-select: noneเป็นองค์ประกอบหลักขององค์ประกอบลูกเหล่านั้นที่ฉันไม่ต้องการให้เลือกเมื่อคลิกสองครั้งที่ใดก็ได้ในองค์ประกอบหลัก และมันใช้งานได้! สิ่งที่ยอดเยี่ยมคือการcontenteditable="true"เลือกข้อความและอื่น ๆ ยังคงใช้ได้กับองค์ประกอบของเด็ก!

ชอบมาก:

<div style="user-select: none">
  <p>haha</p>
  <p>haha</p>
  <p>haha</p>
  <p>haha</p>
</div>

ขอบคุณ peppering style="user-select: note"ทุกเรียงปัญหาฉันได้พยายามที่จะแก้ปัญหา :)
esaruoho

โซลูชัน css-only ที่ดีสำหรับกรณีที่โดยทั่วไปคุณไม่ต้องการให้ข้อความสามารถเลือกได้ ขอบคุณ!
Ian Lovejoy

11

ฟังก์ชัน Javascript แบบธรรมดาที่ทำให้เนื้อหาภายในองค์ประกอบของหน้าไม่สามารถเลือกได้:

function makeUnselectable(elem) {
  if (typeof(elem) == 'string')
    elem = document.getElementById(elem);
  if (elem) {
    elem.onselectstart = function() { return false; };
    elem.style.MozUserSelect = "none";
    elem.style.KhtmlUserSelect = "none";
    elem.unselectable = "on";
  }
}

4

สำหรับผู้ที่มองหาวิธีการแก้ปัญหาสำหรับเชิงมุม 2+

คุณสามารถใช้mousedownเอาต์พุตของเซลล์ตาราง

<td *ngFor="..."
    (mousedown)="onMouseDown($event)"
    (dblclick) ="onDblClick($event)">
  ...
</td>

detail > 1และป้องกันไม่ถ้า

public onMouseDown(mouseEvent: MouseEvent) {
  // prevent text selection for dbl clicks.
  if (mouseEvent.detail > 1) mouseEvent.preventDefault();
}

public onDblClick(mouseEvent: MouseEvent) {
 // todo: do what you really want to do ...
}

dblclickการส่งออกยังคงทำงานตามที่คาดไว้


3

หรือบน mozilla:

document.body.onselectstart = function() { return false; } // Or any html object

บน IE

document.body.onmousedown = function() { return false; } // valid for any html object as well

5
การแก้ปัญหานี้ไม่อนุญาตให้เลือกข้อความเลย
jmav

1
@jmav document.bodyคุณจะต้องใช้ฟังก์ชั่นการแทนที่ในองค์ประกอบที่เฉพาะเจาะจงมากขึ้นกว่า
Cypher

2

เธรดเก่า แต่ฉันพบกับโซลูชันที่ฉันเชื่อว่าสะอาดกว่าเนื่องจากไม่ได้ปิดใช้งานทุกอย่างที่ผูกไว้กับวัตถุและป้องกันการเลือกข้อความแบบสุ่มและไม่พึงประสงค์ในหน้าเท่านั้น มันตรงไปตรงมาและทำงานได้ดีสำหรับฉัน นี่คือตัวอย่าง; ฉันต้องการป้องกันการเลือกข้อความเมื่อฉันคลิกหลาย ๆ ครั้งบนวัตถุด้วยคลาส "ลูกศรขวา":

$(".arrow-right").hover(function(){$('body').css({userSelect: "none"});}, function(){$('body').css({userSelect: "auto"});});

HTH!


1

หากคุณพยายามป้องกันการเลือกข้อความโดยวิธีใดวิธีหนึ่งอย่างสมบูรณ์เช่นเดียวกับการดับเบิลคลิกเท่านั้นคุณสามารถใช้user-select: noneแอตทริบิวต์ css ฉันได้ทดสอบใน Chrome 68 แต่ตามhttps://caniuse.com/#search=user-selectมันควรจะทำงานในเบราว์เซอร์ผู้ใช้ปกติอื่น ๆ ในปัจจุบัน

ตามพฤติกรรมใน Chrome 68 นั้นได้รับการสืบทอดโดยองค์ประกอบย่อยและไม่อนุญาตให้เลือกข้อความที่มีองค์ประกอบขององค์ประกอบแม้ว่าจะมีการเลือกข้อความโดยรอบและรวมถึงองค์ประกอบนั้นก็ตาม


0

เพื่อป้องกันไม่ให้ IE 8 CTRL และ SHIFT คลิกการเลือกข้อความในแต่ละองค์ประกอบ

var obj = document.createElement("DIV");
obj.onselectstart = function(){
  return false;
}

เพื่อป้องกันการเลือกข้อความในเอกสาร

window.onload = function(){
  document.onselectstart = function(){
    return false;
  }
}

-2

ผมมีปัญหาเหมือนกัน. ฉันแก้ไขได้โดยสลับไปที่<a>และเพิ่มonclick="return false;"(เพื่อให้การคลิกที่มันจะไม่เพิ่มรายการใหม่ในประวัติเบราว์เซอร์)

โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.