2

CSS3 pointer-events:none应用举例及扩展

 2 years ago
source link: https://www.zhangxinxu.com/wordpress/2011/12/css3-pointer-events-none-javascript/
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.

by zhangxinxu from http://www.zhangxinxu.com
本文地址:http://www.zhangxinxu.com/wordpress/?p=2091

一、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的选项卡鼠标经过截图  张鑫旭-鑫空间-鑫生活
应用pointer-events:none的选项卡鼠标经过截图 张鑫旭-鑫空间-鑫生活

下面这个打开的选项卡,鼠标移上去好像不存在一般,点击它也是没有任何反应。这就是pointer-events:none的作用:对鼠标事件Say GoodBye!!

哇咔咔,pointer-events:none的作用不只是禁用链接hover,打开链接等效果,是真实意义上的将onlick事件去掉了。如果您反应迅速,创新意识强的话,是不是想到可以利用pointer-events:none实现按钮、选项卡等的禁用效果等。

我们很多时候,考虑到兼容性等原因,常常使用a标签作为按钮实现一些交互效果,例如新浪微博的发送按钮:

a标签作为按钮 张鑫旭-鑫空间-鑫生活

其中就涉及到按钮的禁用(没有文字或文字个数大于140)与可用几种状态。而按钮禁用状态下点击事件的阻止往往是使用JS实现的,而现在,有了pointer-events,我们是不是省掉这部分的脚本呢?

想法是很不错的,然而,人生不如意事八九,事情没有这么简单。pointer-events:none可以直接让鼠标事件酱油化,但是,其并不能让键盘事件变成打酱油的。因为pointer-events这里是”pointer“,而不是”any“或是”every“之类。

还是上面选项卡demo的例子,对于第二个选项卡,我们使用tab键索引选项卡,会发现,应用了pointer-events:none声明的选项卡可以被focus选中(虚框+特意增加的内阴影),而且回车的时候,地址栏地址后面增加了”#bound2″,如下截图:

键盘事件对应用pointer-events:none元素的作用 张鑫旭-鑫空间-鑫生活
锚点出现

是不是有心情顿时凉了半截的感觉——单纯的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的“年终奖”项被直接跳过去了,无法被键盘捕获。

a链接应用disabled后无法捕获键盘响应 张鑫旭-鑫空间-鑫生活

更新于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" style="pointer-events:none;">年终奖</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滤镜实现的半透明渐变背景元素本身就是镂空的穿透的,即我们可以使用鼠标选择或点击半透明背景后面的元素,如下截图:

IE浏览器下半透明的镂空效果 张鑫旭-鑫空间-鑫生活

但是对于FireFox或是Chrome等现代浏览器,则半透明覆盖下面的元素会被遮住,无法选择或点击:

现代浏览器半透明覆盖无法穿透 张鑫旭-鑫空间-鑫生活

此时,我们可以利用pointer-events:none的“幻影”特性,对半透明覆盖元素应用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,实际该属性不管他也不妨,毕竟是新事物。然而,本文相关旁击侧敲的些内容倒是很有用,希望不要看题思意,凭空揣摩,遗漏真正有用的东西。

感谢阅读!

(本篇完)1f44d.svg 是不是学到了很多?可以分享到微信
1f44a.svg 有话要说?点击这里


About Joyk


Aggregate valuable and interesting links.
Joyk means Joy of geeK