1. 程式人生 > >CSS3中的pointer-events

CSS3中的pointer-events

gin 實例 zhang view ctype ssa 指定 max-width 檢查

今天做項目中偶然誤把元素加上了pointer-events屬性,結果導致後來在js中給該元素加點擊事件不能用,檢查了半天才發現是這個屬性的問題。之前沒有好好研究,於是決定仔細研究一下。

一、定義及語法

根據MDN上的解釋如下:

CSS屬性pointer-events允許作者控制特定的圖形元素在何時成為屬性事件的target。當未指定該屬性時,SVG內容表現如同visiblePainted

除了指定元素不成為鼠標事件的目標,none值還指示鼠標事件穿過該元素,並指向位於元素下面的元素。

初始值 auto
適用元素 all elements
是否是繼承屬性 yes
適用媒體 visual
計算值 as specified
是否適用於 CSS 動畫
正規順序 the unique non-ambiguous order defined by the formal grammar

語法

pointer-events:  auto | none | visiblePainted | visibleFill | visibleStroke | visible | painted | fill | stroke | all | inherit

auto
pointer-events屬性未指定時的表現效果相同,對於SVG內容,該值與visiblePainted
效果相同
none
元素永遠不會成為鼠標事件的target。但是,當其後代元素的pointer-events屬性指定其他值時,鼠標事件可以指向後代元素,在這種情況下,鼠標事件將在捕獲或冒泡階觸發父元素的事件偵聽器。
visiblePainted
只適用於SVG。元素只有在以下情況才會成為鼠標事件的目標:
  • visibility屬性值為visible,且鼠標指針在元素內部,且fill屬性指定了none之外的值
  • visibility屬性值為visible,鼠標指針在元素邊界上,且stroke屬性指定了none之外的值
visibleFill
只適用於SVG。只有在元素visibility
屬性值為visible,且鼠標指針在元素內部時,元素才會成為鼠標事件的目標,fill屬性的值不影響事件處理。
visibleStroke
只適用於SVG。只有在元素visibility屬性值為visible,且鼠標指針在元素邊界時,元素才會成為鼠標事件的目標,stroke屬性的值不影響事件處理。
visible
只適用於SVG。只有在元素visibility屬性值為visible,且鼠標指針在元素內部或邊界時,元素才會成為鼠標事件的目標,fillstroke屬性的值不影響事件處理。
painted
只適用於SVG。元素只有在以下情況才會成為鼠標事件的目標:
  • 鼠標指針在元素內部,且fill屬性指定了none之外的值
  • 鼠標指針在元素邊界上,且stroke屬性指定了none之外的值
visibility屬性的值不影響事件處理。
fill
只適用於SVG。只有鼠標指針在元素內部時,元素才會成為鼠標事件的目標,fillvisibility屬性的值不影響事件處理。
stroke
只適用於SVG。只有鼠標指針在元素邊界上時,元素才會成為鼠標事件的目標,strokevisibility屬性的值不影響事件處理。
all
只適用於SVG。只有鼠標指針在元素內部或邊界時,元素才會成為鼠標事件的目標,fillstrokevisibility屬性的值不影響事件處理。

二、到底什麽是pointer-events

pointer-events如上述所言支持的值很多,但大多都與SVG相關,我們可以不用理會。而對於我們來講,需要註意的就是[none|auto]兩個屬性值了。“auto”沒什麽好說的,就是在正常狀態下的元素。本文將著重研究一下“none”。

pointer-events:none顧名思意,就是讓任何鼠標元素對鼠標事件不起作用,這裏的鼠標事件包括css中的hover,同時也會關閉js中的onclick。

三、效果

pointer-events:none的作用不只是禁用鏈接hover,打開鏈接等效果,是真實意義上的將onlick事件去掉了。但是,他不會關閉鍵盤時間,比如點擊"tab"鍵會切換<a>標簽,設置了pointer-events:none的元素同樣有反應。

我們看一下例子:

技術分享

代碼如下:

技術分享
<!DOCTYPE html>
<html>
<head lang="en">
    <meta charset="UTF-8">
    <title></title>
    <style>
        .none{
            pointer-events: none;
        }
    </style>
</head>
<body>
<a href="#1" class="auto">auto1</a>
<a href="#2" class="none">none</a>
<a href="#3" class="auto">auto2</a>
</body>
</html>
技術分享

註:要想真的將元素鼠標和鍵盤事件都去掉,可以使用:無href + pointer-events:none

下面內容轉載自:http://www.zhangxinxu.com/wordpress/2011/12/css3-pointer-events-none-javascript/

四、實際應用

在IE瀏覽器下,filter濾鏡實現的半透明漸變背景元素本身就是鏤空的穿透的,即我們可以使用鼠標選擇或點擊半透明背景後面的元素,如下截圖:

但是對於FireFox或是Chrome等現代瀏覽器,則半透明覆蓋下面的元素會被遮住,無法選擇或點擊:

此時,我們可以利用pointer-events:none的“幻影”特性,對半透明覆蓋元素應用pointer-events:none聲明使其可以鼠標穿透,於是,半透明覆蓋後面的文字可以選擇了,鏈接也可以點擊了:

五、兼容性

目前FireFox瀏覽器,Chrome都支持。Opera以及IE不支持。

六、pointer-events擴展之瀏覽器支持的JS判斷

考慮到某些瀏覽器不支持CSS3 pointer-events屬性,因此,在實際應用的時候,可能要對不同瀏覽器做不同處理,這個時候就需要判別當前用戶瀏覽器是否支持pointer-events. 下面就是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;
})();
技術分享

上面的代碼其實對於瀏覽器是否支持其他CSS3屬性也是比較受用的。

該驗證idea來自 Martin Auswöger (https://github.com/ausi/Feature-detection-technique-for-pointer-events)

七、pointer-events擴展之幻影特性的JS替代實現

直接代碼(基於jQuery):

技術分享
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,這東西兼容性還是很不錯的。具體可參見我之前這篇“CSSOM視圖模式(CSSOM View Module)相關整理”(較長)中的Part 三部分,有demo示意。

八、小賣弄:a標簽按鈕完全禁用實例

最後,小小賣弄下,綜合本文雜七雜八的內容,做個可能沒多大實際意義的實例,就是上面嘮叨了很多的a標簽按鈕完全禁用效果。

按鈕UI借鑒新浪微博。

您可以狠狠地點擊這裏:a標簽按鈕完全禁用demo賣弄版

:本demo是為了應用CSS3 pointer-events屬性而使用了pointer-events,實際應用無需如此折騰。

本demo應用了上面瀏覽器是否支持pointer-events屬性的JS擴展。完整JavaScript代碼如下:

技術分享
var supportsPointerEvents = (function(){
    //上面驗證瀏覽器支持pointer-events屬性代碼
})();

var oArea = document.getElementById("testArea"),
     oButton = document.getElementById("testButton");

oArea.onkeyup = function() {
    var length = this.innerHTML.length;
    if (length == 0 || length > 140) {
        oButton.className = "test_button test_button_disabled";
        oButton.removeAttribute("href");    
    } else {
        oButton.className = "test_button";
        oButton.href = "javascript:";        
    }
};

oButton.onclick = function() {
    //如果支持CSS3 pointer-events,CSS自動判定是否執行點擊事件,腳本這邊可以無顧忌執行彈出
    //如果不支持CSS3 pointer-events
    //通過按鈕狀態判定是否彈出
    if (supportsPointerEvents || (!supportsPointerEvents && this.href)) {
        alert("發送成功");
    }
    return false;
};
技術分享

通過控制href屬性實現完全意義上的禁用。

轉載:http://www.cnblogs.com/shytong/p/5152476.html

CSS3中的pointer-events