本人利用vue开发移动端,遇到一个非常奇怪难解的问题,问题如下     鼠标同时点中两个块A和B,且两个块都绑定了点击事件,试问会触发哪个块的点击事件,按常理来说,会触发鼠标接触多那个块的事件,但是有些情况却不是如此,我就遇到一个问题,虽然鼠标解除A块多,但是只要鼠标触碰到了一点的B,都会导致触发B块的事件,而不触发接触多的A块的事件

解决方案 »

  1.   

      <div onclick="alert('a')" style="width:100%;height:100px;border:1px solid #ccc;">
      <div onclick="alert('b')" style="width:100px;height:40px;border:1px solid #ccc;">
    内层click会引发父级click事件
      </div>
      </div>
      <div style="position:relative;background:#eee;width:100%;height:200px;">
      <div onclick="alert('a')" style="width:100px;height:40px;border:1px solid #ccc;position:absolute;top:10px;left:10px;">
      </div>
        <div onclick="alert('b')" style="width:100px;height:40px;border:1px solid #ccc;position:absolute;top:10px;left:100px;">
      </div>
      非嵌套,则以层深z-index为依据,仅触发z-index最大的
      </div>
      

  2.   

    鼠标的真正位置尺寸只有一个点(像素),箭头型鼠标的真正位置在左上角,I型鼠标的真正位置在正中间,没有接触多少的问题,包括手指触屏也是一样。
    也就是鼠标不可能同时点中A和B两个块,除非A和B两个块是重叠在一起的,那么只会触发在上层那个块的事件。
      

  3.   

    这不是z-index的问题,我举个例子,你先写一个块为A不,在A上绑定一个事件,然后再写一个B,把B的位置用position:fixed定位在A下,在B上绑定一个事件,在电脑上用移动开发模式,鼠标会显示成一个圆圈,然后你会发现即使鼠标大部分接触A,也会导致触发的事件是B,而不是A
      

  4.   

    移动端开发,鼠标就不是剪头了,是圆圈
    那真正位置也只有一个点。但不一定在正中间,尤其是手指触屏时。

    我举个例子,你先写一个块为A不,在A上绑定一个事件,然后再写一个B,把B的位置用position:fixed定位在A下,在B上绑定一个事件,在电脑上用移动开发模式,鼠标会显示成一个圆圈,然后你会发现即使鼠标大部分接触A,也会导致触发的事件是B,而不是A,你可以试试
      

  5.   

    B的绑定事件是否用了.stop修饰符,导致没有传到下一层
      

  6.   

    你最好贴上代码我刚才模拟移动端测试,用position重叠,测试结果就是圆心处于的对象
      

  7.   

    <ul  @click="dianjiul">1111</ul><p @click="dianjip">eee</p>    样式如下ul样式 height:40px;border-bottom:1px  solid  #ccc    p的样式height:20px;position:fixed;top:40px;再随便设置个背景颜色区分,因本人工作电脑不能连外网,只能打这么多了
      

  8.   

    ul  @click="dianjiul">1111</ul><p @click="dianjip">eee</p>    样式如下ul样式 height:40px;border-bottom:1px  solid  #ccc    p的样式height:20px;position:fixed;top:40px;再随便设置个背景颜色区分,因本人工作电脑不能连外网,只能打这么多了
      

  9.   

    这个确实没碰到过,正好学习一下。可以做个边界检测,在2个接触的边缘点击计算一下位置属于哪一个,在手机上误触比较多
    <!DOCTYPE html>
    <html>
    <head>
    <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
    <title>_</title>
    <script src="https://cdn.jsdelivr.net/npm/vue"></script>
    <script src="http://libs.baidu.com/jquery/1.11.1/jquery.min.js"></script>
    <script src="https://cdn.bootcss.com/fastclick/1.0.6/fastclick.js"></script>
    <style type="text/css">
    .block{
    width:400px; height:300px; background:#069;
    }
    .fixed{
    position:fixed; left:300px; width:200px; height:200px; background:#900;
    }
    </style>
    </head>
    <body>
    <div id="app">
    <div class="block" @click="blockClick"></div>
    <div class="fixed" @click="fixedClick"></div>
    <div id="debug"></div>
    </div>
    </body>
    </html>
    <script type="text/javascript">
    var range = 10;
    new Vue({
    el: '#app',
    data:{
    },
    methods:{
    blockClick(e){
    this.log("block click");
    },
    fixedClick(e){
    var block = $(".block");
    var offset = block.offset();
    var width = block.width(), 
    height = block.height(),
    left = offset.left - range, 
    top = offset.top - range, 
    right = offset.left + width + range, 
    bottom = offset.top + height + range;
    if(e.x > left && e.x < right && e.y > top && e.y < bottom){
    this.blockClick(e);
    }else{
    this.log("fixed click");
    }
    },
    log(msg){
    $("#debug").html($("#debug").html() + msg + "<br/>");
    }
    }
    });
    </script>
      

  10.   

    <!DOCTYPE html>
    <html>
    <head>
        <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
        <title>_</title>
        <script src="https://cdn.jsdelivr.net/npm/vue"></script>
        <script src="http://libs.baidu.com/jquery/1.11.1/jquery.min.js"></script>
        <script src="https://cdn.bootcss.com/fastclick/1.0.6/fastclick.js"></script>
        <style type="text/css">
    body {margin:0px;padding:0px;}
            .block{
                width:400px; height:300px; background:#069;z-index:0;border:1px solid red;
            }
            .fixed{
                position:fixed; left:300px; width:200px; height:200px;top:300px;z-index:100; background:#900;
            }
    .block:hover {background:#eee;}
    .fixed:hover {background:#ccc}
        </style>
    </head>
    <body>
    <div id="app">
        <div class="block" @click="blockClick">
    <div class="fixed" @click="fixedClick"></div>
    </div>
        <div id="debug"></div>
    </div>
    </body>
    </html>
    <script type="text/javascript">
    var range = 10;
    new Vue({
        el: '#app',
        data:{       
        },
        methods:{
            blockClick:function(e){
    console.log(e)
                this.log("block click");
            },
            fixedClick:function(e){
    console.log(e)
    e.preventDefault();
    e.stopPropagation();
    this.log("fixed click");
            },
            log:function(msg){
                $("#debug").html($("#debug").html() + msg + "<br/>");
            }
        }
    });
    </script>我这个在模拟移动端测试的时候到时真的碰到一点点的内部嵌套的fixed层,就触发了flxed层的事件但如何fixed层和另外层没有从属关系,还是哪个面积大触发哪个然后通过console.log(e)观察了一下,如果没有从属关系,那就没什么可说的了,应该是移动端的点击机制,直接按面积计算对应srcElement,然后触发如果是有从属,那么应该是冒泡方式的,从最内层向外触发那么个人推测,应该是只要接触到,都会被计算的
      

  11.   

    谢谢你这么认真的回答,其实我这个问题一开始是这样的:在移动端开发,一个页面,分成两部分,一部分是顶部导航栏,就是横着的那种,另一部分是下面的内容,下面的内容就是一个列表,切换顶部导航栏的时候,下面的内容跟着切换到不同的列表上(下面的内容支持下拉刷新,刷新组件用的事mintui),一开始自己也没怎么去在意点击问题,就是偶尔总是觉得自己明明点击到导航栏了,却老是触发点击列表的事件,进去详情去了,后来测试提出了这个问题,我才去研究,然后发现真的是存在这样的问题,就是稍微触碰到列表,都会优先触发列表的事件,后来我就自己在导航栏底部加了个fixed的一个透明层(我在想这样就可以避免触碰到列表了),发现还是不行(只要透明层底下的列表有事件,那么一样会出现这种情况,虽然不会再触发列表事件,但是即使稍微碰到透明层,就不会触发导航栏的切换事件),然后我试着把列表上绑定的事件去掉,然后又没这个问题了,但我列表上必须有事件,所以我觉得很诡异,这个问题我也到现在还没解决,你的方法我试了,还是不行
      

  12.   

    看到position:fixed可能是点击穿透问题。
      

  13.   

    不是哦,点击穿透是可以触发到fixed下面的其他对象的事件,但是我这个这个并不会