實現多層DIV疊加的js事件穿透
Flash裡面有個很好的特性是,一個容器裡,不存在實際物件的部分,不會阻攔滑鼠事件穿透到下一層。
前端就不一樣了,兩個div層疊以後,上層div會接收到所有事件(即使這個div裡面內容是空的,沒有任何實際物件),下層div什麼事件都接不到。
舉個例子:
這個示意圖中
C方塊在A容器中(A容器邊框為紅色)
D方塊在B容器中(B容器邊框為綠色)
A B部分重疊,B在上層。
不做任何處理的話,C方塊永遠無法被點到,因為B把它蓋住了。
下面,我將給出一種方案,在不改變頁面結構的情況下,讓CD都能得到正常相應。
主要利用的是css中的pointer-events
語法:
pointer-events:auto | none | visiblepainted | visiblefill | visiblestroke | visible | painted | fill | stroke | all
預設值:auto
適用於:所有元素
繼承性:有
動畫性:否
計算值:指定值
取值:
auto:
與pointer-events屬性未指定時的表現效果相同。在svg內容上與visiblepainted
值相同
none:
元素永遠不會成為滑鼠事件的target。但是,當其後代元素的pointer-events屬性指定其他值時,滑鼠事件可以指向後代元素,在這種情況下,滑鼠事件將在捕獲或冒泡階觸發父元素的事件偵聽器。
其他值只能應用在SVG上。
參考連結:http://www.css88.com/book/css/properties/user-interface/pointer-events.htm
注意,這個屬性部分舊版瀏覽器可能不支援。
我注意到,設定為none之後,其子元素仍然可以通過顯式設定auto來響應滑鼠事件,那麼我們可以將A B容器都設定為none,不響應滑鼠事件,同時,將CD顯式設定為auto,讓他們響應滑鼠事件,這樣一來,B就不會擋住A了,下面是具體程式碼
<!DOCTYPE html> <html> <head> <title>Test position</title> <style type="text/css"> .a { position: absolute; border: solid 1px red; width: 400px; height: 400px; left: 0px; pointer-events:none; } .b { position: absolute; border: solid 1px green; width: 400px; height: 400px; left: 200px; pointer-events:none; } .a1 { position: absolute; width: 100px; height: 100px; background: red; left: 250px; top: 50px; pointer-events:auto; } .b1 { position: absolute; width: 100px; height: 100px; background: green; left: 50px; top: 250px; pointer-events:auto; } </style> </head> <body> <div class="a" onclick="onclicka()"> <div class="a1"></div> </div> <div class="b" onclick="onclickb()"> <div class="b1"></div> </div> <script type="text/javascript"> function onclicka() { console.log('click a'); } function onclickb() { console.log('click b'); } </script> </body> </html>
結果如下: