zoukankan      html  css  js  c++  java
  • CSS3中的pointer-events

    今天做项目中偶然误把元素加上了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

  • 相关阅读:
    2018年5月份
    2018年4月份
    2018年3月份
    2018年2月份
    代码书写欣赏
    关于Model层中Datetime Datetime? 默认值的问题
    关于DotNetBar中DataGridViewX 自动全屏 Anchor属性无效问题
    关于ios 8 7 下的模态窗口大小的控制 代碼+場景(mainstoryboard)( Resizing UIModalPresentationFormSheet )
    ios 关于StoryBoard 的简易使用说明
    VS2012 Build相关
  • 原文地址:https://www.cnblogs.com/BluceLee/p/7264948.html
Copyright © 2011-2022 走看看