非常有用的pointer-events屬性


介紹

pointer-events是css3的一個屬性,指定在什么情況下元素可以成為鼠標事件的target(包括鼠標的樣式)

屬性值

pointer-events屬性有很多值,但是對於瀏覽器來說,只有auto和none兩個值可用,其它的幾個是針對SVG的(本身這個屬性就來自於SVG技術)。

/* Keyword values */

pointer-events: auto; /* 默認 */

pointer-events: none;

pointer-events: visiblePainted/* SVG only */

pointer-events: visibleFill;  /* SVG only */

pointer-events: visibleStroke;  /* SVG only */

pointer-events: visible;  /* SVG only */

pointer-events: painted;  /* SVG only */

pointer-events: fill;  /* SVG only */

pointer-events: stroke;  /* SVG only */

pointer-events: all;  /* SVG only */

/* Global values */

pointer-events: inherit;

pointer-events: initial;

pointer-events: unset;

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 的時候,才重新請求新的數據。

  •  <!--CSS--> <style> .active{ pointer-events: none; } </style> <!--HTML--> <ul> <li><a class="tab"></a></li> <li><a class="tab active"></a></li> <li><a class="tab"></a></li> </ul>復制代碼
  •  

案例二:切換開/關按鈕狀態

點擊提交按鈕的時候,為了防止用戶一直點擊按鈕,發送請求,當請求未返回結果之前,給按鈕增加 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>

參考

CSS3 pointer-events介紹

MDN pointer-events

網易考拉前端團隊 css3 pointer-events 介紹

CSS3 pointer-events:none應用舉例及擴展


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM