ส่งเหตุการณ์ของเมาส์ผ่านองค์ประกอบตำแหน่งอย่างแน่นอน


307

ฉันกำลังพยายามที่จะจับภาพเหตุการณ์ของเมาส์บนองค์ประกอบที่มีองค์ประกอบที่จัดวางอย่างอื่นอยู่ด้านบนของมัน

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

คำตอบ:


488
pointer-events: none;

เป็นคุณสมบัติ CSS ที่ทำให้เหตุการณ์ "ผ่าน" องค์ประกอบที่จะใช้และทำให้เหตุการณ์เกิดขึ้นในองค์ประกอบ "ด้านล่าง"

ดูรายละเอียดได้ที่: https://developer.mozilla.org/en/css/pointer-events

ไม่รองรับ IE 11; ผู้ขายรายอื่นทั้งหมดให้การสนับสนุนเป็นเวลาพอสมควร (การสนับสนุนทั่วโลกอยู่ที่ ~ 92% ใน 12 / '16): http://caniuse.com/#feat=pointer-events (ขอบคุณ @ s4y สำหรับการให้ลิงก์ในความคิดเห็น) .


3
ขอบคุณ! นี่เป็นโซลูชั่นที่สมบูรณ์แบบสำหรับเบราว์เซอร์ที่ทันสมัย ​​(และไม่ใช่ IE) ในขณะที่คำถามนี้ถูกโพสต์ฉันไม่คิดว่าpointer-eventsมีอยู่! ฉันอาจสลับคำตอบที่ยอมรับได้ไปเป็นคำตอบในบางประเด็น
s4y

16
ว้าวนี่ช่วยฉันได้หลายชั่วโมง
Dan Abramov

2
ฉันเพิ่งเปลี่ยนคำตอบที่ยอมรับเป็นคำตอบนี้ การสนับสนุนสำหรับpointer-events ยังคงไม่ได้ยอดเยี่ยม แต่มันก็ดีขึ้น สำหรับตัวเลือกเพิ่มเติมที่เข้ากันได้กับคำตอบของ @ JedSchmidt
s4y

1
ขอบคุณฉันไม่เคยรู้ว่าสิ่งนี้มีอยู่จริง มันช่วยฉันได้หลายชั่วโมง
โมฮัมเหม็ดอัลจายา

2
แต่ถ้าคุณต้องการให้เหตุการณ์บางอย่างเช่นเหตุการณ์เลื่อนผ่าน แต่องค์ประกอบด้านบนยังคงตอบสนองต่อกิจกรรมอื่น ๆ ทั้งหมด การตั้งค่าตัวชี้เหตุการณ์ให้ไม่มีใครฆ่าเหตุการณ์ทั้งหมดในองค์ประกอบด้านบน
AndroidDev

50

หากสิ่งที่คุณต้องการคือ mousedown คุณอาจจะสามารถทำได้ด้วยdocument.elementFromPointวิธีการโดย:

  1. เอาชั้นบนสุดบน mousedown
  2. ผ่านxและyพิกัดจากเหตุการณ์ไปยังdocument.elementFromPointวิธีการรับองค์ประกอบภายใต้แล้ว
  3. การคืนค่าชั้นบนสุด

9
คำอธิบายที่ฟุ่มเฟือยเพิ่มเติมได้ที่นี่: vinylfox.com/forwarding-mouse-events-through-layers
Nathan

2
เยี่ยมมากฉันไม่ทราบวิธีการที่มีอยู่! นอกจากนี้ยังสามารถนำมาใช้อย่างง่ายดายในการรับองค์ประกอบทั้งหมดภายใต้เคอร์เซอร์โดยใช้ลูปwhileเพื่อรับองค์ประกอบสูงสุดจากนั้นซ่อนมันเพื่อค้นหาองค์ประกอบถัดไป คว้ารุ่นของฉันที่นี่: gist.github.com/Pichan/5498404
jpeltoniemi

2
ปัญหาเกี่ยวกับวิธีแก้ปัญหานี้คือมันไม่ทำงานกับการซูมหน้า สำหรับอุปกรณ์มือถือหรือเบราว์เซอร์เดสก์ท็อปที่ซูมด้วยพิกัด XY ไม่ได้มีความหมายอะไรอีกต่อไปและไม่มีวิธีที่ชัดเจนในการคำนวณการซูม ฉันเชื่อว่าการบีบเหน็บแนมเป็นไปไม่ได้
Impossibear

39

เป็นสิ่งที่ดีที่จะรู้ ...
กิจกรรมตัวชี้สามารถปิดใช้งานสำหรับองค์ประกอบหลัก (อาจเป็น div โปร่งใส) และยังเปิดใช้งานสำหรับองค์ประกอบลูก สิ่งนี้มีประโยชน์หากคุณทำงานกับเลเยอร์ div ที่ทับซ้อนกันหลายชั้นซึ่งคุณต้องการคลิกองค์ประกอบย่อยของเลเยอร์ใดก็ได้ สำหรับ divs การเลี้ยงดูทั้งหมดนี้จะได้รับpointer-events: noneและ click-children รับตัวชี้เหตุการณ์ที่เปิดใช้งานอีกครั้งโดยpointer-events: all

.parent {
    pointer-events:none;        
}
.child {
    pointer-events:all;
}

<div class="some-container">
   <ul class="layer-0 parent">
     <li class="click-me child"></li>
     <li class="click-me child"></li>
   </ul>

   <ul class="layer-1 parent">
     <li class="click-me-also child"></li>
     <li class="click-me-also child"></li>
   </ul>
</div>

5
น่ากลัวขวาหลังจากที่สูงของการค้นพบpointer-events:noneและใกล้เข้ามาให้ลงของการมีโหนดเด็กได้รับผลกระทบคุณบันทึกวัน :)
ฆCortés

;) ดีใจมากเกี่ยวกับเรื่องนี้
Allisone

สามารถต้มให้เป็นอาหาร.parent * { pointer-events:all; }สำหรับเด็กได้หรือไม่
Dmitry

ควรเป็น "ตัวชี้เหตุการณ์: อัตโนมัติ;" ค่า "all" ใช้กับ SVG เท่านั้น ดูdeveloper.mozilla.org/en-US/docs/Web/CSS/pointer-events
mattavatar

7

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

อีกตัวเลือกหนึ่งคือการลงทะเบียนตัวจัดการเหตุการณ์การคลิกสำหรับองค์ประกอบแบบสัมบูรณ์และเรียกตัวจัดการการคลิกสำหรับตัวแบ่งสีน้ำเงินซึ่งทำให้ทั้งคู่กะพริบ

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


ขอบคุณสำหรับการตอบรับ Loktar น่าเสียดายที่หน้าจริงฉันจะไม่ทราบว่าอะไรอยู่ภายใต้องค์ประกอบที่มีตำแหน่งแน่นอนและอาจมีเป้าหมายที่เป็นไปได้มากกว่าหนึ่งรายการ วิธีแก้ปัญหาเดียวที่ฉันคิดได้คือการจับพิกัดเมาส์และเปรียบเทียบกับเป้าหมายที่เป็นไปได้เพื่อดูว่าพวกมันตัดกันหรือไม่ นั่นจะน่ารังเกียจเพียงธรรมดา
s4y

4

มีเวอร์ชันจาวาสคริปต์ที่เปลี่ยนเส้นทางเหตุการณ์จาก div หนึ่งไปยังอีกด้วยตนเอง

ฉันล้างมันและทำให้เป็นปลั๊กอิน jQuery

นี่คือที่เก็บ Github: https://github.com/BaronVonSmeaton/jquery.forwardevents

น่าเสียดายที่วัตถุประสงค์ที่ฉันใช้สำหรับ - การซ้อนทับหน้ากากบน Google แผนที่ไม่ได้จับการคลิกและการลากและเคอร์เซอร์ของเมาส์ไม่เปลี่ยนแปลงซึ่งทำให้ประสบการณ์การใช้งานของผู้ใช้ลดลงพอที่ฉันเพิ่งตัดสินใจซ่อนหน้ากากภายใต้ IE และ Opera - เบราว์เซอร์สองตัวที่ไม่รองรับกิจกรรมตัวชี้


1

หากคุณรู้องค์ประกอบที่ต้องการกิจกรรมเมาส์และหากการซ้อนทับของคุณโปร่งใสคุณสามารถตั้งค่าดัชนี z ของสิ่งเหล่านั้นให้สูงกว่าการวางซ้อน แน่นอนเหตุการณ์ทั้งหมดควรทำงานในกรณีนั้นในเบราว์เซอร์ทั้งหมด

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