CSS / JS เพื่อป้องกันการลากภาพผี?


152

มีวิธีการป้องกันไม่ให้ผู้ใช้เห็นผีของภาพที่พวกเขากำลังพยายามลาก (ไม่ต้องกังวลเกี่ยวกับความปลอดภัยของภาพ แต่เป็นประสบการณ์)

ฉันได้ลองวิธีนี้แล้วซึ่งแก้ไขปัญหาด้วยการเลือกสีน้ำเงินในข้อความและรูปภาพ แต่ไม่ใช่ภาพผี:

img {
  -webkit-user-select: none;
  -khtml-user-select: none;
  -moz-user-select: none;
  -o-user-select: none;
  user-select: none;
}

(ฉันพยายามทำรังภาพภายใน div ด้วยกฎเดียวกันกับที่ใช้กับ div) ขอบคุณ


1
ดูคำตอบนี้: stackoverflow.com/a/4211930/1060487คำถามซ้ำกันได้
mattdlockyer

คำตอบ:


195

คุณสามารถตั้งค่าdraggableแอตทริบิวต์เป็นfalseในรหัสมาร์กอัปหรือรหัส JavaScript

// As a jQuery method: $('#myImage').attr('draggable', false);
document.getElementById('myImage').setAttribute('draggable', false);
<img id="myImage" src="http://placehold.it/150x150">


48
ทำไมต้องเพิ่มด้วย JavaScript ??? <img id="myImage" src="http://placehold.it/150x150" draggable="false">
เกร็ก

26
@Greg: ทำไมคุณถามฉัน มันเป็น OP ที่ต้องการโซลูชัน JavaScript นอกจากนี้ฉันก็พูดว่า "ทั้งในมาร์กอัปหรือรหัส JavaScript" อย่างไรก็ตามมันไม่เหมือนกับที่คุณไม่สามารถทำได้ในมาร์กอัปหากคุณมีตัวเลือกในการแก้ไขมาร์กอัปของคุณ
BoltClock

12
ไม่ทำงานใน FF -moz-user-select: noneร่วมกับ วิธีการแก้ปัญหาที่เป็นไปได้: pointer-events: noneเพิ่ม
Cedric Reichenbach

9
บางทีฉันอาจตีความคำถามผิด ๆ แต่ OP ไม่ใช่ถามว่าพวกเขาสามารถเก็บลากและวาง แต่เพียงซ่อนภาพผีได้อย่างไร การตั้งค่าdraggableเป็นfalseจะปิดใช้งานการลาก & วางอย่างสมบูรณ์
James

1
@ James: มันไม่ชัดเจนมากจากคำถามที่จะซื่อสัตย์ ฉันส่วนใหญ่ตอบภายใต้สมมติฐานว่าภาพผีเป็นตัวบ่งชี้ภาพสำหรับการลากแล้ววาง (ซึ่งก็คือ) และคนส่วนใหญ่ที่ต้องการซ่อนภาพผีโดยทั่วไปไม่สนใจว่าการลากและวางเป็นอย่างไร ปิดการใช้งานโดยสิ้นเชิง
BoltClock

87

ฉันคิดว่าคุณสามารถเปลี่ยนของคุณ

img {
  -webkit-user-select: none;
  -khtml-user-select: none;
  -moz-user-select: none;
  -o-user-select: none;
  user-select: none;
}

เป็น

img {
  -webkit-user-drag: none;
  -khtml-user-drag: none;
  -moz-user-drag: none;
  -o-user-drag: none;
  user-drag: none;
}

3
@victorsosa จริง แต่มาตรฐาน de-พฤตินัยยังคงเป็นมาตรฐาน W3C หรือไม่ นั่นคือถ้าเบราว์เซอร์ทุกตัวรองรับมันก็เป็นการดีที่จะไป โปรดจำไว้ว่าสิ่ง W3C มากมายเริ่มเป็นกรรมสิทธิ์เช่น AJAX
Beejor

4
วิธีนี้ไม่ทำงานใน IE11 และ Firefox 57.0
ทิวดอร์ Ciotlos

34

ลองมัน:

img {
  pointer-events: none;
}

และพยายามหลีกเลี่ยง

* {
  pointer-events: none;
}

8
นี่เป็นวิธีการแก้ปัญหาที่ไม่ดีเนื่องจากเป็นการขจัดความสามารถทั้งหมดในการโต้ตอบกับองค์ประกอบ OP ขอให้ปิดการใช้งานฟังก์ชั่น "ลาก" ขององค์ประกอบเท่านั้นไม่ใช่เพื่อปิดใช้งานการโต้ตอบใด ๆ ที่อิงกับตัวชี้กับองค์ประกอบทั้งหมด
ชาด

4
@Chad ที่เป็นจริง แต่เป็นไปได้ที่จะตัดภาพและเพิ่มฟังเหตุการณ์เพื่อห่อหุ้มในขณะที่ภาพไม่มีภาพผีอีกต่อไป
Vincent Hoch-Drei

18

คุณสามารถใช้คุณสมบัติ CSS เพื่อปิดใช้งานรูปภาพในเบราว์เซอร์ webkit

img{-webkit-user-drag: none;}

3
นี้ยังทำงานร่วมกับ-ms-user-drag, และ-moz-user-drag user-dragโซลูชัน CSS-only ที่ยอดเยี่ยม!
Beejor

14

การดำเนินการนี้จะปิดใช้งานการลากรูปภาพในเบราว์เซอร์ทั้งหมดในขณะที่รักษาเหตุการณ์อื่นเช่นคลิกและโฮเวอร์ ทำงานได้ตราบใดที่ HTML5, JS หรือ CSS พร้อมใช้งาน

<img draggable="false" onmousedown="return false" style="user-drag: none" />

หากคุณมั่นใจว่าผู้ใช้จะมี JS คุณจะต้องใช้แอตทริบิวต์ JS และอื่น ๆ เพื่อความยืดหยุ่นมากขึ้นดูที่ ondragstart, onselectstart และ CSS WebKit tap / touch บางส่วน


คุณอาจต้องการที่จะทำ (this.onclick || this.click) () แทน .. หาก onclick สามารถไม่ได้กำหนดตามตรรกะนี้?
Van Nguyen

@ Kaizoku ขอบคุณฉันไม่ได้คิดอย่างนั้น! อัปเดตคำตอบของฉันตามคำแนะนำของคุณ
Beejor

สิ่งนี้ดูเหมือนจะไม่ทำงานใน FireFox เพราะพูดอย่างเคร่งครัด <img> ไม่มีแม้แต่ onclick หรือ click events อย่างไรก็ตามฉันเพิ่งใช้ส่วน onmouseup และให้ผู้ปกครอง DIV จัดการ onclick และใช้งานได้
เนลสัน

@ เนลสันขอบคุณที่แจ้งให้เราทราบ ดูเหมือนว่าไม่จำเป็นต้องมีการเปิดใช้งานเนื่องจากการคลิก onclick โดยไม่คำนึงถึงค่าส่งคืนจากตัวจัดการ onmousedown / up ใด ๆ ฉันตัดสินใจทบทวนคำตอบของฉันเพื่อความเรียบง่าย ซับใหม่ควรทำงานได้ดี เพิ่งทดสอบใน FF, Safari, Chrome, IE8 / 10
Beejor

ฉันใช้ Firefox 62 และonmousedown="return false"เพียงพอแล้ว นอกจากนี้ยังจำเป็นเพื่อหลีกเลี่ยงผู้ใช้ที่เลือกรูปภาพในขณะที่ลากไปบนรูปภาพซึ่งจะอนุญาตให้พวกเขาลากส่วนที่เลือก
loxaxs


4

คุณสามารถกำหนดภาพผีอื่นได้หากคุณต้องการใช้เหตุการณ์ลากและไม่สามารถตั้ง draggable = false ได้ ดังนั้นเพียงแค่กำหนด png ที่ว่างเปล่าเช่นนั้น:

    $('#img').bind({
        dragstart: function(e) {
            var dragIcon = document.createElement('img');
            dragIcon.src = 'blank.png';
            dragIcon.width = 100;
            e.dataTransfer.setDragImage(dragIcon, -10, -10);
        }
    });

2
ไม่ใช่ทุกเบราว์เซอร์ที่รองรับsetDragImageแม้ว่าจะรองรับการลากและวางเช่น IE10 / 11
James

เป็นไปได้ไหมที่จะใช้เคล็ดลับนี้โดยไม่ใช้ png เปล่า?
Fabien Quatravaux

1
คุณสามารถใช้ภาพที่เข้ารหัส base64 แบบอินไลน์ ... เช่นdragIcon.src = 'data:image/gif;base64,R0lGODlhAQABAIAAAAAAAP///yH5BAEAAAAALAAAAAABAAEAAAIBRAA7';
Murray Smith


2

สำหรับ Firefox คุณต้องทำสิ่งนี้ให้ลึกขึ้น:

var imgs = document.getElementsByTagName('img');

    // loop through fetched images
    for (i = 0; i < imgs.length; i++) {
        // and define onmousedown event handler
        imgs[i].onmousedown = disableDragging;
    }

function disableDragging(e) {
        e.preventDefault();
    }

สนุก.


1

ฉันพบว่าสำหรับ IE คุณต้องเพิ่มแอตทริบิวต์ draggable = "false" ให้กับรูปภาพและจุดยึดเพื่อป้องกันการลาก ตัวเลือก CSS ใช้งานได้กับเบราว์เซอร์อื่นทั้งหมด ฉันทำสิ่งนี้ใน jQuery:

$("a").attr('draggable', false); 
$("img").attr('draggable', false);

1

มีวิธีแก้ไขที่ง่ายกว่าที่นี่มากกว่าการเพิ่มผู้ฟังเหตุการณ์ที่ว่างเปล่า เพียงตั้งค่าpointer-events: noneภาพของคุณ หากคุณยังต้องการให้คลิกได้ให้เพิ่มคอนเทนเนอร์ที่ล้อมรอบซึ่งเป็นต้นเหตุของเหตุการณ์



0

ทดสอบกับ Firefox: การลบและนำกลับมาใช้งานได้จริง! และมันก็โปร่งใสในการดำเนินการเช่นกัน ตัวอย่างเช่น

$('.imageContainerClass').mousedown(function() {
    var id = $(this).attr('id');
    $('#'+id).remove();
    $('#'+id).append('Image tag code');
});

แก้ไข : ใช้งานได้เฉพาะบน IE และ Firefox อย่างแปลกประหลาด ฉันยังเพิ่มdraggable = falseในแต่ละภาพ ยังคงเป็นผีกับ Chrome และ Safari

แก้ไข 2 : โซลูชันภาพพื้นหลังเป็นโซลูชันที่ดีที่สุดอย่างแท้จริง ความละเอียดเพียงอย่างเดียวคือbackground-sizeคุณสมบัติจะต้องมีการกำหนดใหม่ทุกครั้งที่มีการเปลี่ยนภาพพื้นหลัง! นั่นคือสิ่งที่ดูเหมือนจากข้างฉัน ยังดีกว่าฉันมีปัญหากับimgแท็กปกติภายใต้ IE ที่ IE ล้มเหลวในการปรับขนาดภาพ ตอนนี้ภาพมีขนาดที่ถูกต้อง ง่าย:

$(id).css( 'background-image', url('blah.png') );
$(id).css( 'background-size', '40px');

นอกจากนี้อาจพิจารณาสิ่งต่อไปนี้:

background-Repeat:no-repeat;
background-Position: center center;

0

คุณสามารถตั้งค่ารูปภาพที่แสดงเมื่อลากรายการ ทดสอบกับ Chrome แล้ว

setDragImage

ใช้

onclick = myFunction();
myFunction(e) {
    e.dataTransfer.setDragImage(someImage, xOffset, yOffset);
}

อีกวิธีหนึ่งดังที่ได้กล่าวไปแล้วในคำตอบคุณสามารถกำหนดdraggable="false"องค์ประกอบ HTML ได้หากไม่สามารถลากองค์ประกอบได้เลยไม่มีปัญหา


0

be-all-end-all สำหรับการไม่เลือกหรือลากด้วยคำนำหน้าเบราว์เซอร์ทั้งหมด:

-webkit-user-select: none;
-khtml-user-select: none;
-moz-user-select: none;
-o-user-select: none;
-ms-user-select: none;
user-select: none;

-webkit-user-drag: none;
-khtml-user-drag: none;
-moz-user-drag: none;
-o-user-drag: none;
-ms-user-drag: none;
user-drag: none;

นอกจากนี้คุณยังสามารถตั้งค่าแอตทริบิวต์draggable falseคุณสามารถทำเช่นนี้กับอินไลน์ HTML: draggable="false"มี Javascript: elm.draggable = falseหรือกับ elm.attr('draggable', false)jQuery:

นอกจากนี้คุณยังสามารถจัดการกับฟังก์ชั่นonmousedown return falseคุณสามารถทำได้ด้วย inline HTML onmousedown="return false":, กับ Javascript: elm.onmousedown=()=>return false;หรือด้วย jQuery:elm.mousedown(()=>return false)


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