zoukankan      html  css  js  c++  java
  • 再次总结移动端事【件穿穿透】问题

    整体代码

    <!DOCTYPE html>
    <html>
    
    <head>
      <meta charset=utf-8>
      <meta name=viewport content="width=device-width,initial-scale=1">
      <title>vui</title>
    </head>
    <style>
        #app {
             100px;
            height: 100px;
            position: absolute;
            left: 0;
            top: 0;
            z-index: 2;
            background-color: red;
        }
    
        .dow {
             300px;
            height: 300px;
            position: absolute;
            left: 0;
            top: 0;
            background-color: blue;
        }
    </style>
    <body>
      <div class="dow">
            <div id=app>
    
            </div>
      </div>
      <script >
      let app = document.querySelector('#app')
      let dow = document.querySelector('.dow')
    //   app.ontouchstart = function () {
    //     console.log('app click')
    //   }
      app.addEventListener('touchstart', function (e) {
        app.style.display = 'none'
        console.log('app click')
        e.preventDefault();
        e.stopPropagation();
      })
    
      dow.addEventListener('click', function () {
        console.log('dow click')
      })
    
      // touchstart 事件只能通过dom2方式 (也就是addEventListener传播)以下这种方式无响应的
    //   dow.ontouchstart = function () {
    //     console.log('dow click')
    //   }
      </script>
    
    </body>
    
    </html>
    

    事件穿透 不是 事件冒泡

    1事件冒泡

    事件冒泡存在的前提是层级嵌套

    如: 这种情况下 两个元素都绑定click事件 或者touchstart事件,点击 app时 事件会冒泡到dow上

      <div class="dow">
            <div id=app>
    
            </div>
      </div>
    

    如: 这种情况下 两个元素都绑定click事件 或者touchstart事件,点击 app时 事件不会冒泡

      <div id=app>
    
      </div>
      <div class="dow">
    
      </div>
    

    总结: 由于body是所有dom的父层级,所以 任何事件都会冒泡到body上

    2事件穿透

    存在前提:
    • 上层绑定 touchstart事件
    • 下层绑定click事件
    • 上层点击时候 隐藏自身
    • 与两个元素是嵌套 还是 上下层 无关

    产生原因: touchstart 先与click执行

    解决方案:

      app.addEventListener('touchstart', function (e) {
        app.style.display = 'none'
        console.log('app click')
    	//重点
        e.preventDefault(); //组织事件默认事件,在事件touchstart时候就组织了继续往下产生click	ouchend事件
        e.stopPropagation();//非必须 此方法主要组织冒泡,由于前面结论可知,仅当dom存在嵌套下才会产生冒泡才需要此方法
      })
    

    "e.preventDefault(); //组织事件默认事件,在事件touchstart时候就组织了继续往下产生click ouchend事件" 的解释

      <div class="dow">
            <div id=app>
    
                </div>
      </div>
    
     app.addEventListener('touchstart', function (e) {
        app.style.display = 'none'
        console.log('app touchstart')
        e.preventDefault();
        e.stopPropagation();
      })
      app.addEventListener('touchend', function (e) {
            console.log('app end')
      })
      app.addEventListener('click', function (e) {
            console.log('app click')
      })
      dow.addEventListener('touchstart', function () {
        console.log('dow touchstart')
      })
      dow.addEventListener('click', function () {
        console.log('dow click')
      })
    
      dow.addEventListener('touchend', function (e) {
            console.log('dow touchend')
      })
    

    运行点击结果

    • app touchstart
    • app end
    • dow touchend

    翻译翻译

    -对页面点击一次 会先后产生'touchstart' ----'touchend' ---- 'click'事件

    我们对 app 绑定了 'touchstart' ----'touchend' ---- 'click' 并对 touchstart 绑定两个阻止方法
    当我们点击app时候

    产生 touchstart事件 ,由于对事件组织默认事件,所以接下来不会再产生click事件,也不会冒泡
    产生 touchend事件 ,
    冒泡 touchend事件 到dow上

    补充两篇相关文章

    最后的结论

    移动端不建议用touch事件,弊端如代码只能在移动端使用,pc端无法使用,且ie内核可能无法兼容
    用click事件 目前都用fastclick解决,其本质是在touchend事件中 触发click事件,并阻止默认的click事件,从而避免了300s延迟 和 事件 穿透

  • 相关阅读:
    Linux服务器免密登录设置
    Docker 批量停止、删除容器和镜像
    python破解wifi密码
    python调用paramiko模块连接服务器
    Docker搭建redis-cluster集群三主三备
    Centos7.7搭建Prometheus2.0+Grafana监控Docker容器
    Centos7.7部署fastdfs分布式文件系统
    拉取git代码仓库项目到本地
    Seafile对接Amazon S3存储后端
    Centos7.x部署SeaFile私有网盘
  • 原文地址:https://www.cnblogs.com/WhiteHorseIsNotHorse/p/8289377.html
Copyright © 2011-2022 走看看