这篇文章发布于 2011年12月7日,星期三,22:38,归类于 Web综合。 阅读 230266 次, 今日 4 次 34 条评论
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
的作用:对鼠标事件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" 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滤镜实现的半透明渐变背景元素本身就是镂空的穿透的,即我们可以使用鼠标选择或点击半透明背景后面的元素,如下截图:
但是对于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
(本篇完)
- CSSOM视图模式(CSSOM View Module)相关整理 (0.689)
- 鼠标无限移动 JS API Pointer Lock简介 (0.260)
- jQuery - 鼠标经过(hover)事件的延时处理 (0.138)
- MooTools和jQuery库继承实现class切换对比 (0.138)
- js页面文字选中后分享到新浪微博实现 (0.138)
- HTML5终极备忘大全(图片版+文字版) (0.138)
- JS滚轮事件(mousewheel/DOMMouseScroll)了解 (0.138)
- 小卖弄:纯CSS实现的outline切换transition动画效果 (0.131)
- css margin的相关属性,问题及应用 (0.122)
- jQuery之addClasas与removeClass使用实例 (0.122)
- CSS margin-inline和margin-block区别是什么? (RANDOM - 0.008)
给了pointer-events::none之后,cursor:not-allowed的鼠标样式就会没有了,这是怎么一回事
因为此属性把鼠标事件完全禁用了,当然也包含鼠标的样式
四、pointer-events:none“幻影”特性的实际应用
非常感谢,学到了,之前做过类似的遮罩,但是没有用上这个
麻烦修改一下发布按钮被禁止的时候的backgroun:postion属性:
.test_button_disabled {
background: url(http://img.t.sinajs.cn/t5/skin/diy/diy005/images/all_iconbtn.png?id=1348554801578) -225px -275px;
pointer-events: none;
}
应该是-295px而不是-275px
真他妈逼费劲.读你的文章
就是,啰嗦得不行~
那就别看,去别的地找好的技术文章看,最看不惯你这种二逼。能力水的一笔还特么矫情。
赞一个,哈哈
哈哈哈哈哈,赞+1,摘抄进我的小本本
拿枪指着你看了?看文章收你钱了?
谁家的狗,赶紧牵走
你丫有病啊 让你看啦?
怎么跑出来只没人管的狗 不爱看Ctrl+W 麻利的滚
有病吧,谁逼着你看了,不爱看滚蛋,事儿多
第一次发评论特意来喷你个二逼,看人家的文章还特么嫌人家写的罗嗦,你是脑残吗。
有毛病
在选项卡a标签应用disabled实例中,我测试了火狐和chrome(当然都是比较高的版本)发现是可以相应键盘的tab事件的啊。我觉得如果要避开键盘时间,tabindex可以使用的啊
你好,看这篇文章明白不少。最后一个demo“a标签按钮完全禁用demo卖弄版”按钮样式背景图片位置有点问题
.test_button_disabled {
background: url(http://img.t.sinajs.cn/t5/skin/diy/diy005/images/all_iconbtn.png?id=1348554801578) -225px -275px;
pointer-events: none;
}
改成-225px -295px就好了。
我刚才试了下 “pointer-events:none“幻影”应用demo” 中,IE的渐变特效只能支持IE9- ,导致在IE9+后没有了渐变效果,但同时 pointer-events 貌似在IE11中才被支持,所以IE10 无法实现穿透效果。
elementFromPoint,这个属性貌似从来没用过,目测感觉有了这个方法,可以猥琐出来很多事情,我来测试一下!
谢谢你提供的检测方法,找了很久了
不知能否使用js突破新浪微博140字限制?
哥,以这个css3属性来说,其实他还有个很不错的应用方式,我提出来试试:
我们在移动端touch与click事件处理的响应速度是两个数量级,所以为了提升按钮响应速度会逐步使用tap事件替换click
而tap事件带来的“点透”现象在某些情况下就可以以此属性解决
感谢分享pointer-events:none这一新CSS3特性及应用。不过最后的去掉a标签的href使其成为disable状态应该是大家在做选项卡时经常用到的吧?以前会给当前状态设置cursor样式,不过估计是不支持键盘行为的。
请教一下,不明白这个地方,为什么要设置两次pointerEvents的属性呢?
dummy.style.pointerEvents = ‘auto’;
dummy.style.pointerEvents = ‘x’;
而且,我把后面的去掉也不影响检查啊,实在不明白。
这是我个人理解
1.明显的是x会把之前赋值的auto覆盖掉
2.后面用了getComputedStyle这个方法。由于x是个无效的值,所以如果浏览器支持pointer-event这个css属性的话,计算出来的样式应该是auto。
如果去掉a的href属性,用a没什么意义,完全可以用其它标签代替
写得非常好! 很好的研究精神啊!学习了~ 我个人来说,因为ie这个垃圾的存在,会导致我研究的心情大打折扣~ 所以看你的东西会让我有很爽的感觉~
Chrome下
那个 输入几个字再删除掉 按钮状态就没变回来了
好文 ~~ 神奇的用法+1
最后面那个例子,如果我输入了,然后又删除了,发送还是可以点击的
@蔡述雄 Chrome浏览器下确实有该问题,因为对于contenteditable元素其会内置换行符。这里仅仅示意,懒得替换折腾。
真佩服你的专研精神,学了