zoukankan      html  css  js  c++  java
  • 移动端 弹窗-内容可滚动,背景不动

    实际开发中,总免不了使用弹窗,如果弹窗比较短,内容不需要滑动,那还好处理,vue中直接阻止滑动就可以了,但是如果弹窗内的内容需要滑动,那就有点麻烦了,之前看到的方案都是给body设置fixed,但是事实上都不是很好,还好,网上找了一种解决方案,实现思路比较简单直接,滑动的时候监听touch事件,通过target来判断滑动的是谁,如果是遮罩层,那么直接preventDefault(),当然,这还没完,还需要处理滑动的边界情况,在最顶部以及最底部,此时,如果继续滑动的话,底部的内容依然会滑动,所以,在边界情况下还是需要阻止滑动,下面以自己实现的mask组件为例来说明把,其实这基本就实现了需求

    话不多说,下面附上自己写的一个通用组件

    <template>
      <div class="lo-mask" @touchstart="start" @touchmove="move" @touchend="end">
        <div class="mask-container" ref="container">
          <p v-for="val in 20">{{val}}</p>
          <div class="content">
            <slot name="title"></slot>
            <slot name="content"></slot>
          </div>
          <footer>
            <button v-if="cancel"  @click="cancelBtn" class="btn cancel">{{cancel}}</button>
            <span class="line" v-if="cancel&&confirm"></span>
            <button  v-if="confirm"  @click="successBtn" class="btn">{{confirm}}</button>
          </footer>
        </div>
      </div>
    
    </template>
    
    <script>
      export default {
        name: 'loMask',
        props: {
          cancel: {
            type: String,
            default: ''
          },
          confirm: {
            type: String,
            default: ''
          }
        },
        data() {
          return {
            startY: 0
          }
        },
        methods: {
          successBtn() {},
          cancelBtn() {},
    
          start(e) {
            // console.log(e.target);
            // let target = e.target;
            // console.log(target.className);
            console.log(e);
            this.startY = e.touches[0].clientY;
          },
          move(e) {
            // console.log(e.target);
            // e.preventDefault()
            let container = this.$refs.container;
            let target = e.target;
    
            let sTop = container.scrollTop,       // 滚动的高度    (滚动卷去的高度)
                sHeight = container.scrollHeight, // 可滚动的高度  (实际总高度)
                vHeight = container.offsetHeight; // 视窗的高度    (可视区域高度)
            if (target.className === 'lo-mask') {
              e.preventDefault()
            }
            let newY = e.touches[0].clientY;
            let dis = newY - this.startY;
    
            if (dis > 0) {
              // 向下
              if (sTop <= 0&& e.cancelable) { //是否是最上面
                e.preventDefault()
              }
            } else {
              // 向上
              if (sTop + vHeight >= sHeight&& e.cancelable) { //是否滑动到底了
                e.preventDefault()
              }
            }
          },
          end() {}
        }
      }
    </script>
    
    <style scoped lang="scss">
      .lo-mask{
        position: fixed;
         100%;
        height: 100%;
        background:rgba(0, 0, 0, 0.7);
        z-index: 50;
        top: 0;
        left: 0;
        display: flex;
        align-items: center;
        justify-content: center;
        padding-left: 0.2rem;
        padding-right: 0.2rem;
        overflow: auto;
      }
      .mask-container{
        position: relative;
        display: flex;
        flex-direction: column;
         2.7rem;
        min-height: 1.5rem;
        max-height: 2rem;
        overflow-y: scroll;
        background-color: #fff;
        border-radius: 0.08rem;
        box-shadow: 0 3px 19px rgba(89, 89, 89, 0.85);
      }
      .content{
        flex: 1;
      }
      footer{
        display: flex;
        box-sizing: content-box;
        align-items: center;
        justify-content: space-around;
         100%;
        height: 0.4rem;
        background-color: #f7f7f7;
        border-top: 1px solid #E2E2E2;
        border-radius: 0 0 0.08rem 0.08rem;
        .btn{
          flex: 1;
          height: 0.4rem;
          color: #E9327B;
          font-size: 0.17rem;
          font-weight: bold;
        }
        .line{
           1px;
          height: 0.4rem;
          background-color: #E2E2E2;
        }
      }
    
    </style>
    
    

    直接复制过去就可以用,还是不错的
    自己测试了下,效果还行,不过vant-ui里面的popup组件就可以实现上述效果,大家可以引用vant-ui 的这个组件来使用

  • 相关阅读:
    C#实现二维码生成与解码
    js中正则表达式使用
    Busybox镜像
    linux删除文件后,空间未释放的一种情况,使用lsof查看
    linux中.nfsxxxx引起的文件无法删除
    linux中的查找命令find,locate,which,whereis
    openj9
    Ali流量控制中间件Sentinel
    LDAP认证模式简介
    nginx支持ipv6
  • 原文地址:https://www.cnblogs.com/ysla/p/11992345.html
Copyright © 2011-2022 走看看