一、pointer-events:none是?
pointer-events
是CSS3中又一冉冉的屬性,其支持的值牛毛般多,不過大多都與SVG相關,我們可以不用理會。當下,對於偶們來講,與SVG划開界線值得一提的就是[none|auto]兩個屬性值了。其中”auto”的感覺與width屬性的”auto”類似,一般在一些特殊場合露一手,平時閨門不出,沒什么說頭。因此,一輪篩選下來,我們需要留意的只是pointer-events:none
而已。
pointer-events:none
是個很有意思的東西,某些情況下其精湛的表現會讓人兩眼發光。
pointer-events:none
顧名思意,就是鼠標事件拜拜的意思。元素應用了該CSS屬性,鏈接啊,點擊啊什么的都變成了“浮雲牌醬油”。
嘮叨到嘴巴打結還不如一個明快的例子給力,下面是例子大放送時間。
二、pointer-events:none與乖乖的選項卡
為了更好的示意pointer-events:none
的含義,我做了個選項卡的例子。
您可以狠狠地點擊這里:當前選項卡鼠標禁用demo
上下兩個選項卡,差別在何處呢?就是當前打開的選項卡下面這個應用了pointer-events:none
,於是,當我們鼠標移上去的時候,會有如下的差異反應:
下面這個打開的選項卡,鼠標移上去好像不存在一般,點擊它也是沒有任何反應。這就是pointer-events:none
的作用:對鼠標事件Say GoodBye!!
哇咔咔,pointer-events:none
的作用不只是禁用鏈接hover,打開鏈接等效果,是真實意義上的將onlick
事件去掉了。如果您反應迅速,創新意識強的話,是不是想到可以利用pointer-events:none
實現按鈕、選項卡等的禁用效果等。
我們很多時候,考慮到兼容性等原因,常常使用a
標簽作為按鈕實現一些交互效果,例如新浪微博的發送按鈕:
其中就涉及到按鈕的禁用(沒有文字或文字個數大於140)與可用幾種狀態。而按鈕禁用狀態下點擊事件的阻止往往是使用JS實現的,而現在,有了pointer-events
,我們是不是省掉這部分的腳本呢?
想法是很不錯的,然而,人生不如意事八九,事情沒有這么簡單。pointer-events:none
可以直接讓鼠標事件醬油化,但是,其並不能讓鍵盤事件變成打醬油的。因為pointer-events
這里是”pointer
“,而不是”any
“或是”every
“之類。
還是上面選項卡demo的例子,對於第二個選項卡,我們使用tab鍵索引選項卡,會發現,應用了pointer-events:none
聲明的選項卡可以被focus選中(虛框+特意增加的內陰影),而且回車的時候,地址欄地址后面增加了”#bound2″,如下截圖:
是不是有心情頓時涼了半截的感覺——單純的CSS禁用按鈕事件還是不靠譜啊!
矮油,古語有雲:天無絕人之路,車到山前必有路,柳暗花明又一村…… 所以,不要這么快就退卻了,腦中快快閃現我們以往頁面制作的一些經驗,想想其他方法~~
//zxx: 假設你已經有過一番不錯的思考……
不是大家有沒有研究過a標簽+disabled屬性
這種組合。首先,大家都知道input[type=text|button|radio|checkbox]
等控件元素完全支持disabled
屬性,可以實現事件的完全禁用(附帶UI變化)。而a
標簽呢則是部分瀏覽器部分支持,由於不是本文重點,這里簡單說下。a
標簽應用disabled
屬性是無法阻擋任何鼠標經過或是點擊事件的(雖然IE下置灰文字看上去可以禁用),因此,在實際web開發的時候,我們不對a
標簽應用disabled
屬性。但是,實際上,您可能不知道的是,在絕大多數瀏覽器下,a
標簽應用disabled
可以禁用鍵盤事件(避開tab
鍵的索引)。
您可以狠狠地點擊這里:選項卡a標簽應用disabled實例
例如FireFox瀏覽器下,我們tab
鍵遍歷事件元素,結果發現先前可以被鍵盤focus的“年終獎”項被直接跳過去了,無法被鍵盤捕獲。
更新於2013-04-23
今天在FireFox下重新測試,可以被鍵盤focus了,看來是火狐修復了,與Chrome等瀏覽器保持了一致。
IE瀏覽器下同樣如此。♩♫ ♬ ♪ ♩♪……心中是不是哼起歡樂的小曲呢?pointer-events:none + disabled = 完美禁用
。然而,就像北京的空氣一樣,清晰的日子總是很短暫,happy ending不是這么容易來滴。
如果您在Chrome或是Safari(需要設置偏好設置)下查看上面的實例頁面,會發現應用了disabled
屬性的a
標簽還是可以被鍵盤捕獲(內陰影效果呈現,回車URL地址改變)。
是不是有心情頓時涼了半截的感覺——簡單地使用CSS, HTML禁用按鈕事件還是比較懸啊!
唉,不要那么容易灰心嘛,大熊被技安揍了137次還樂觀地活着,我們可以再想想其他法子嘛~~
這里就不再賣關子了。在a
標簽元素的href
屬性上動刀子。a
標簽元素之所以能夠響應鍵盤索引,其關鍵就在於href
屬性。有了這個,瀏覽器會認為這個a元素是個鏈接之類,可以跳轉,考慮到可訪問性,有必要支持鍵盤響應。否則,當作擺設元素處理。
因此……您可以狠狠地點擊這里:無href + pointer-events:none禁用demo
這下子,徹底讓IE, FireFox, Chrome等瀏覽器下的a標簽鏈接域鍵盤事件拜拜了。示例代碼如下:
<a class="tab_a tab_on" >年終獎</a>
因此,禁用a標簽鏈接或按鈕的完美組合是:pointer-events:none & without href
三、pointer-events:none情感化認識
pointer-events:none
的作用是讓元素實體“虛化”。例如一個應用pointer-events:none
的按鈕元素,則我們在頁面上看到的這個按鈕,只是一個虛幻的影子而已,您可以理解為海市蜃樓,幽靈的軀體。當我們用手觸碰它的時候可以輕易地沒有任何感覺地從中穿過去。
一切都是幻影!
四、pointer-events:none“幻影”特性的實際應用
上面花了不少篇幅講了如何利用pointer-events:none
本身的含義實現完全禁用的a標簽按鈕效果。然而,考慮到現實情況——IE瀏覽器以及目前的Opera(11.6)都不支持改CSS3屬性,因此,a標簽按鈕禁用的實現也只能是嘴上說說,紙上寫寫而已。
但是,這里的例子是可以切切實實應用在大型web項目上的。該例子不是利用pointer-events:none
的本性(禁用鼠標),而是利用其表性(幻影)。
下圖所示的這種效果目前很多地方都有見到,水平或是垂直列表的兩端(可能會有平滑滾動效果)有個白色的半透明漸變覆蓋:
OK,如果是您,這里的白色半透明漸變覆蓋該如何實現?
幾年前,要實現類似這樣的效果估計得借助圖片,不過現在,可以借助CSS實現,可以參見我之前的文章:CSS實現兼容性的漸變背景效果
具體實現非重點,不展示,您有興趣可以參考下面demo頁面的源代碼。
您可以狠狠地點擊這里:pointer-events:none“幻影”應用demo
在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
屬性實現完全意義上的禁用。
九、結束語
本文原本計划寫個短篇的,可寫着寫着就脹出來了。其他俗耐的話就省了。本文雖然題為pointer-events,實際該屬性不管他也不妨,畢竟是新事物。然而,本文相關旁擊側敲的些內容倒是很有用,希望不要看題思意,憑空揣摩,遺漏真正有用的東西。
感謝閱讀!
原創文章,轉載請注明來自張鑫旭-鑫空間-鑫生活[http://www.zhangxinxu.com]
本文地址:http://www.zhangxinxu.com/wordpress/?p=2091