介紹
pointer-events是css3的一個屬性,指定在什么情況下元素可以成為鼠標事件的target(包括鼠標的樣式)
屬性值
pointer-events屬性有很多值,但是對於瀏覽器來說,只有auto和none兩個值可用,其它的幾個是針對SVG的(本身這個屬性就來自於SVG技術)。
|
pointer-events屬性值詳解
-
auto——效果和沒有定義pointer-events屬性相同,鼠標不會穿透當前層。在SVG中,該值和visiblePainted的效果相同。
-
none——元素永遠不會成為鼠標事件的target(目標)。但是,當其后代元素的
pointer-events
屬性指定其他值時,鼠標事件可以指向后代元素,在這種情況下,鼠標事件將在捕獲或冒泡階段觸發父元素的事件偵聽器。實際上默
認就可以穿透當前層,因為pointer-events默認為auto
瀏覽器兼容性
Firefox 3.6+和chrome 2.0+ 以及safari 4.0+都支持這個CSS3屬性,IE6/7/8/9都不支持,Opera在SVG中支持該屬性但是HTML中不支持。
檢測瀏覽器是否支持該屬性的JS代碼,其實也可以用來檢測其他的屬性
var supportsPointerEvents = (function(){
var dummy = document.createElement('_');
if(!('pointerEvents' in dummy.style)) return false;
dummy.style.pointerEvents = 'auto';
dummy.style.pointerEvents = 'x';
document.body.appendChild(dummy);
var r = getComputedStyle(dummy).pointerEvents === 'auto';
document.body.removeChild(dummy);
return r;
})(); |
為什么要設置兩次pointerEvents的屬性呢?
dummy.style.pointerEvents = ‘auto’;
dummy.style.pointerEvents = ‘x’;
解讀:明顯的是x會把之前賦值的auto覆蓋掉,后面用了getComputedStyle這個方法。由於x是個無效的值,所以如果瀏覽器支持pointer-event這個css屬性的話,計算出來的樣式應該是auto。
使用JS替代實現pointerEvents穿透當前層的效果
function noPointerEvents (element) {
$(element).bind('click mouseover', function (evt) {
this.style.display = 'none';
var x = evt.pageX, y = evt.pageY,
under = document.elementFromPoint(x, y);
this.style.display = '';
evt.stopPropagation();
evt.preventDefault();
$(under).trigger(evt.type);
});
} |
elementFromPoint:返回給定坐標處的所在的元素
使用實例:document.elementFromPoint(100,100)
trigger:觸發被選元素指定的事件類型
event.type:返回事件類型
實例一
案例一:穿透當前層
在某個項目中,很多元素需要定位在一個地圖層上面,這里就要用到很多絕對定位或者相對定位的元素,但是這樣的話,這些浮在上面的div或者其它元素一般都會給個寬高,或者relative的元素可以不給寬高,這個時候,這些元素就會蓋
住下面的地圖層,以至於地圖層無法操作。。。
然后正好在Google map見到了類似的問題,拿來當例子來說:
Google map中左上角的操作區域占位是挺大的,如紅色框區域,然后在這個區域是無法操作地圖層的。那么我們就可以給這個div設置 pointer-events:none,然后你就會發現下面的地圖就可以拖動和點擊了。
但是悲劇的是,操作區域本身卻無法操作了,直接被無視掉了。不過不用擔心,我們可以給里面的元素重新設置為 pointer-events:auto,當然,只給需要操作的元素區域設置。
貌似有點兒糾結,不過這樣可以保證地圖本身的可操作區域最大化。
實例二:pointer-events 可以禁用 HTML 元素的 hover/focus/active 等動態效果。
案例一:禁用 a 標簽事件效果
在做 tab 切換的時候,當選中當前項,禁用當前標簽的事件,只有切換其他 tab 的時候,才重新請求新的數據。
|
案例二:切換開/關按鈕狀態
點擊提交按鈕的時候,為了防止用戶一直點擊按鈕,發送請求,當請求未返回結果之前,給按鈕增加 pointer-events: none,可以防止這種情況,這種情況在業務中也十分常見。
<!--CSS-->
.j-pro{ pointer-events: none; }
<!--HTML-->
<button r-model={this.submit()} r-class={{"j-pro": flag}}>提交</button>
<!--JS-->
submit: function(){
this.data.flag = true;
this.$request(url, {
// ... onload: function(json){
if(json.retCode == 200){
this.data.flag = false;
} }.bind(this)
// ...
});
}
|
案例三:防止透明元素和可點擊元素重疊不能點擊
一些內容的展示區域,為了實現一些好看的 css 效果,當元素上方有其他元素遮蓋,為了不影響下方元素的事件,給被遮蓋的元素增加 pointer-events: none; 可以解決。
<!--CSS-->
.layer{ backround: linear-gradient(180deg, #fff, transparent); }
.j-pro{ poninter-events: none; }
<!--HTML-->
<ul>
<li class="layer j-pro"></li>
<li class="item"></li>
<li class="item"></li>
<li class="item"></li>
</ul>
|