Vượt qua các sự kiện chuột thông qua yếu tố định vị tuyệt đối


307

Tôi đang cố gắng ghi lại các sự kiện chuột trên một phần tử với một phần tử được định vị tuyệt đối khác ở trên phần tử đó.

Ngay bây giờ, các sự kiện trên phần tử được định vị tuyệt đối đánh vào nó và nổi lên với cha mẹ của nó, nhưng tôi muốn nó "trong suốt" đối với các sự kiện chuột này và chuyển tiếp chúng vào bất cứ điều gì đằng sau nó. Làm thế nào tôi nên thực hiện điều này?

Câu trả lời:


488
pointer-events: none;

Là một thuộc tính CSS làm cho các sự kiện "đi qua" phần tử được áp dụng và làm cho sự kiện xảy ra trên phần tử "bên dưới".

Xem để biết chi tiết: https://developer.mozilla.org/en/css/pulum-events

Nó không được hỗ trợ lên tới IE 11; tất cả các nhà cung cấp khác đều hỗ trợ nó từ khá lâu (hỗ trợ toàn cầu là ~ 92% trong 12/12): http://caniuse.com/#feat=pulum-events (cảm ơn @ s4y đã cung cấp liên kết trong các nhận xét) .


3
Cảm ơn! Đây là một giải pháp hoàn hảo cho các trình duyệt hiện đại (và không phải IE). Tại thời điểm câu hỏi này được đăng, tôi không nghĩ là pointer-eventscó tồn tại! Tôi có thể chuyển câu trả lời được chấp nhận sang câu hỏi này tại một số điểm.
s4y

16
Woah, điều này chỉ giúp tôi tiết kiệm hàng giờ.
Dan Abramov

2
Tôi chỉ chuyển câu trả lời được chấp nhận cho câu hỏi này. Hỗ trợ pointer-events vẫn không phải là siêu tuyệt vời , nhưng nó đang trở nên tốt hơn. Để có tùy chọn tương thích hơn, hãy đi với câu trả lời của @ JedSchmidt.
s4y

1
Cảm ơn, tôi không bao giờ biết điều này thực sự tồn tại. nó đã giúp tôi tiết kiệm hàng giờ
Mohammed A. Al Jama

2
Nhưng điều gì sẽ xảy ra nếu bạn chỉ muốn cho một số sự kiện như sự kiện cuộn đi qua nhưng phần tử trên cùng vẫn đáp ứng với tất cả các sự kiện khác. Đặt các sự kiện con trỏ thành không giết chết tất cả các sự kiện trên phần tử trên cùng.
AndroidDev

50

Nếu tất cả những gì bạn cần là mousedown, bạn có thể thực hiện bằng document.elementFromPointphương thức, bằng cách:

  1. loại bỏ lớp trên cùng trên mousedown,
  2. chuyển xytọa độ từ sự kiện sang document.elementFromPointphương thức để lấy phần tử bên dưới, và sau đó
  3. Khôi phục lớp trên cùng.

9
Giải thích nhiều từ hơn ở đây: vinylfox.com/forwarding-mouse-events-ENC-layers
Nathan

2
Tuyệt vời, tôi không biết phương pháp đó thậm chí còn tồn tại! Nó có thể được cũng được sử dụng khá dễ dàng để có được tất cả các yếu tố dưới con trỏ sử dụng một trong khi vòng lặp để có được những yếu tố trên cùng và sau đó ẩn nó để tìm ra kế tiếp. Lấy phiên bản của tôi tại đây: gist.github.com/Pichan/5498404
jpeltoniemi

2
Vấn đề với cách giải quyết này là nó không hoạt động với việc phóng to trang. Đối với các thiết bị di động hoặc trình duyệt máy tính để bàn được phóng to theo tọa độ XY không còn ý nghĩa gì nữa và không có cách nào rõ ràng để tính toán thu phóng. Tôi tin rằng để phóng to thu nhỏ nó thực sự không thể.
Impossibear

39

Cũng rất vui được biết ...
Các sự kiện con trỏ có thể bị vô hiệu hóa cho một phần tử cha (có thể là div trong suốt) và chưa được bật cho các phần tử con. Điều này rất hữu ích nếu bạn làm việc với nhiều lớp div chồng chéo, nơi bạn muốn có thể nhấp vào các phần tử con của bất kỳ lớp nào. Đối với điều này, tất cả các div cha mẹ có được pointer-events: nonevà nhấp chuột con có được các sự kiện con trỏ được kích hoạt bởipointer-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
Tuyệt vời, ngay sau khi khám phá cao pointer-events:nonevà sự thất vọng sắp xảy ra khi có các nút trẻ em bị ảnh hưởng, bạn hãy tiết kiệm trong ngày :)
Juan Cortés

;) Rất vui mừng về điều đó
Allisone

Nó có thể được đun sôi xuống chỉ: .parent * { pointer-events:all; }cho trẻ em?
Dmitry

Nó phải là "sự kiện con trỏ: auto;". Giá trị "tất cả" chỉ áp dụng cho các SVG. Xem developer.mozilla.org/en-US/docs/Web/CSS/pulum-events
mattavatar

7

Lý do bạn không nhận được sự kiện là vì phần tử được định vị tuyệt đối không phải là phần tử con của phần tử mà bạn muốn "nhấp chuột" (div màu xanh). Cách sạch nhất tôi có thể nghĩ đến là đặt yếu tố tuyệt đối như một đứa trẻ của cái bạn muốn nhấp, nhưng tôi cho rằng bạn không thể làm điều đó hoặc bạn sẽ không đăng câu hỏi này ở đây :)

Một tùy chọn khác là đăng ký một trình xử lý sự kiện nhấp chuột cho phần tử tuyệt đối và gọi trình xử lý nhấp chuột cho div màu xanh lam, khiến cả hai đều nhấp nháy.

Do cách các sự kiện nổi lên thông qua DOM Tôi không chắc có câu trả lời đơn giản hơn cho bạn, nhưng tôi rất tò mò liệu có ai khác có bất kỳ thủ thuật nào tôi không biết!


Cảm ơn đã trả lời, Loktar. Thật không may, trên trang thực tôi sẽ không biết những gì bên dưới yếu tố được định vị tuyệt đối và có thể có nhiều hơn một mục tiêu có thể. Cách giải quyết duy nhất tôi có thể nghĩ đến là nắm lấy tọa độ chuột và so sánh chúng với các mục tiêu có thể để xem chúng có giao nhau không. Đó sẽ chỉ là khó chịu đơn giản.
s4y

4

Có một phiên bản javascript có sẵn để chuyển hướng thủ công các sự kiện từ div này sang div khác.

Tôi đã dọn sạch nó và biến nó thành một plugin jQuery.

Đây là kho lưu trữ Github: https://github.com/BaronVonSmeaton/jquery.forwardevents

Thật không may, mục đích tôi đang sử dụng nó - che một mặt nạ trên Google Maps đã không nắm bắt được các sự kiện nhấp và kéo và con trỏ chuột không thay đổi làm giảm trải nghiệm người dùng đến mức tôi chỉ quyết định ẩn mặt nạ trong IE và Opera - hai trình duyệt không hỗ trợ các sự kiện con trỏ.


1

Nếu bạn biết các yếu tố cần sự kiện chuột và nếu lớp phủ của bạn trong suốt, bạn có thể đặt chỉ số z của chúng thành thứ gì đó cao hơn lớp phủ. Tất cả các sự kiện nên hoạt động trong trường hợp đó trên tất cả các trình duyệt.

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.