CSS3pointer-events:none应⽤举例及扩展
⼀、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,于是,当我们⿏标移上去的时候,会有如下的差异反应:
下⾯这个打开的选项卡,⿏标移上去好像不存在⼀般,点击它也是没有任何反应。这就是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键的索引)。
您可以狠狠地点击这⾥:
例如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元素是个链接之类,可以跳转,考虑到可访问性,有必要⽀持键盘响应。否则,当作摆设元素处理。
因此……您可以狠狠地点击这⾥:
这下⼦,彻底让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实现,可以参见我之前的⽂章:
具体实现⾮重点,不展⽰,您有兴趣可以参考下⾯demo页⾯的源代码。
您可以狠狠地点击这⾥:
在IE浏览器下,filter滤镜实现的半透明渐变背景元素本⾝就是镂空的穿透的,即我们可以使⽤⿏标选择或点击半透明背景后⾯的元素,如下截图:
但是对于FireFox或是Chrome等现代浏览器,则半透明覆盖下⾯的元素会被遮住,⽆法选择或点击:
此时,我们可以利⽤pointer-events:none的“幻影”特性,对半透明覆盖元素应⽤pointer-events:none声明使其可以⿏标穿透,于是,半透明覆盖后⾯的⽂字可以选择了,链接也可以点击了:
五、兼容性
⽬前FireFox浏览器,Chrome都⽀持。Opera以及IE不⽀持。
六、pointer-events扩展之浏览器⽀持的JS判断
var supportsPointerEvents = (function(){
var dummy = ateElement('_');
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';
veChild(dummy);
return r;
})();
上⾯的代码其实对于浏览器是否⽀持其他CSS3属性也是⽐较受⽤的。
看到这是是否与我产⽣同样的疑惑?
为什么要设置两次pointerEvents的属性呢?
dummy.style.pointerEvents = ‘auto';
dummy.style.pointerEvents = ‘x';
⽽且,我把后⾯的去掉也不影响检查啊
下⾯引⽤这个回答者说的话:
这是我个⼈理解
1.明显的是x会把之前赋值的auto覆盖掉
2.后⾯⽤了getComputedStyle这个⽅法。由于x是个⽆效的值,所以如果浏览器⽀持pointer-event这个css属性的话,计算出来的样式应该是auto。
要验证上⾯的这两句话,可以尝试把dummy.style.pointerEvents = ‘x';换成dummy.style.pointerEvents = ‘none';
然后 alert( dummy.style.pointerEvents);
发现当设为“x”的时候,输出的是auto,当设为“none”的时候输出的是none,就是说不能把不能识别的值传⼊pointerEvents
七、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).pe);
});
}
上⾯展⽰代码中有个⽐较有意思的⽅法就是elementFromPoint,这东西兼容性还是很不错的。具体可参见我之前这篇“”(较长)中的Part 三部分,有demo⽰意。
⼋、⼩卖弄:a标签按钮完全禁⽤实例
最后,⼩⼩卖弄下,综合本⽂杂七杂⼋的内容,做个可能没多⼤实际意义的实例,就是上⾯唠叨了很多的a标签按钮完全禁⽤效果。
按钮UI借鉴新浪微博。
您可以狠狠地点击这⾥:
注:本demo是为了应⽤CSS3 pointer-events属性⽽使⽤了pointer-events,实际应⽤⽆需如此折腾。
本demo应⽤了上⾯浏览器是否⽀持pointer-events属性的JS扩展。完整JavaScript代码如下:
var supportsPointerEvents = (function(){
//上⾯验证浏览器⽀持pointer-events属性代码
})();
var oArea = ElementById("testArea"),
oButton = ElementById("testButton");
var length = this.innerHTML.length;
if (length == 0 || length > 140) {
css鼠标点击样式oButton.className = "test_button test_button_disabled";
} else {
oButton.className = "test_button";
oButton.href = "javascript:";
}
};
//如果⽀持CSS3 pointer-events,CSS⾃动判定是否执⾏点击事件,脚本这边可以⽆顾忌执⾏弹出
//如果不⽀持CSS3 pointer-events
//通过按钮状态判定是否弹出
if (supportsPointerEvents || (!supportsPointerEvents && this.href)) {
alert("发送成功");
}
return false;
};
通过控制href属性实现完全意义上的禁⽤。
注:最后⾯那个例⼦,如果我输⼊了,然后⼜删除了,发送还是可以点击的;
作者的回答:Chrome浏览器下确实有该问题,因为对于contenteditable元素其会内置换⾏符。这⾥仅仅⽰意,懒得替换折腾。
九、结束语
本⽂原本计划写个短篇的,可写着写着就胀出来了。其他俗耐的话就省了。本⽂虽然题为pointer-events,实际该属性不管他也不妨,毕竟是新事物。然⽽,本⽂相关旁击侧敲的些内容倒是很有⽤,
希望不要看题思意,凭空揣摩,遗漏真正有⽤的东西。
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系QQ:729038198,我们将在24小时内删除。
发表评论