vue pop two solutions slidable shield

sequence

  During the development process, we often encounter needs to be added pop, and if the current page to show the data show a screen finish, after you open a pop, sometimes sliding operation, the page will also slide. So how do we deal with this problem?

common problem

  Our development process, the most common problems are described above: pop open when the sliding operation, the page will also slide. Problem diagram is as follows:


2502265-5741072c4add5709.gif
Background can not be shielded pop .gif

final effect

We look correct a wave of demonstration

2502265-18f62c9079f1d505.gif
Slidably pop .gif

solution

  Two solutions for two different situations:

  1. Less elastic frame data, without sliding
  2. Elastic frame data to swipe

1. pop without sliding

a. Ideas

Ideas:
VUE comes modifier solve this problem -@touchmove.prevent

This program will focus on @touchmove.preventis bound to pop the module and then dynamically control the pop show Hide.

b. effect
2502265-27aaf3f858302f47.gif
Non-slidable pop .gif
c. Code
<template>
    <div class="modalTest">
        <!-- 按钮组 -->
        <div class="btn">
            <el-button type="success" size="small" @click="modalSign1 = true">弹窗1</el-button>
        </div>

        <!-- 背景数据 -->
        <div class="listBG">
            <ul>
                <li v-for="item in 50">这是第{{item}}条背景数据</li>
            </ul>
        </div>


        <!-- 弹框1 -->
        <div class="modalBox" v-if="modalSign1" @touchmove.prevent @click.self="modalSign1 = false">
            <div class="modal">
                <ul>
                    <li v-for="item in 8">这是第{{item}}条数据</li>
                </ul>
            </div>
        </div>
    </div>
</template>

<script>
    export default {
        data() {
            return {
                modalSign1: false, // 弹窗是否打开
            }
        }
    }
</script>

2. The elastic frame data to swipe

a. Ideas

  First, we use the normal operation of vue, just when such modifiers / syntactic sugar to operate, although the data can be masked background slide, but at the same time sliding the event will also stop playing the box out, we are unable to complete the requirements . If this does not work, there are other ways to accomplish our needs?
  I consider a scheme, but belong to DOM manipulation, and may not be in line with the original intention of vue. However, this scheme is not vectors as a way to effectively solve the problem.

Idea:
use css position: fixedand top: x pxfixed position. Step broken down as follows:

  1. Writing style into a common css spare;
  2. Click the button, Control pop show hidden;
  3. Two methods, the step of controlling a 1dynamically added to css written bodyon, the other to remove the effect of the control;
    • Adding methods: ① height to get the current page from the top, to the data stored in; ② is added to the body of step 1 css; ③ body height is set to a height just acquired.
    • Removal Method: ① winter will just add to the css body removal; ② the current slide height to height data stored.
b. effect
2502265-18f62c9079f1d505.gif
Slidably pop .gif
c. two cases the complete code
<template>
    <div class="modalTest">
        <!-- 按钮组 -->
        <div class="btn">
            <el-button type="success" size="small" @click="modalSign1 = true">弹窗1</el-button>
            <br>
            <el-button type="danger" size="small" @click="openModal">弹窗2</el-button>
        </div>

        <!-- 背景数据 -->
        <div class="listBG">
            <ul>
                <li v-for="item in 50">这是第{{item}}条背景数据</li>
            </ul>
        </div>


        <!-- 弹框1 -->
        <div class="modalBox" v-if="modalSign1" @touchmove.prevent @click.self="modalSign1 = false">
            <div class="modal">
                <ul>
                    <li v-for="item in 8">这是第{{item}}条数据</li>
                </ul>
            </div>
        </div>
        <!-- 弹框2 -->
        <div class="modalBox" v-if="modalSign2" @click.self="closeModal">
            <div class="modal">
                <ul>
                    <li v-for="item in 20">这是第{{item}}条数据</li>
                </ul>
            </div>
        </div>
    </div>
</template>

<script>
    export default {
        data() {
            return {
                modalSign1: false, // 弹窗是否打开
                modalSign2: false, // 弹窗是否打开
                scrollTop: undefined, // 距离顶端的值
                className: 'modalOpen', // 类名
            }
        },
        methods: {
            // 打开弹层 要做的事
            afterOpen () {
                this.scrollTop = document.scrollingElement.scrollTop;
                document.body.classList.add(this.className);
                document.body.style.top = `-${this.scrollTop}px`;
            },
            // 弹层关闭之前 要做的事
            beforeClose () {
                document.body.classList.remove(this.className);
                document.scrollingElement.scrollTop = this.scrollTop;
            },
            // 打开弹窗
            openModal () {
                this.modalSign2 = true;
                this.afterOpen();
            },
            // 关闭弹窗
            closeModal () {
                this.modalSign2 = false;
                this.beforeClose();
            }
        },
        mounted() {

        }
    }
</script>

<style type="text/scss" lang="scss" scoped>
    .modalTest{
        width: 100%;
        min-height: 100vh;
        overflow: scroll;
        .btn{
            padding: 10px;
            position: fixed;
            top: 0;
            left: 0;
            z-index: 10;
            &>button{
                margin: 10px 0;
            }
        }
        .listBG{
            text-align: center;
            line-height: 50px;
        }
        .modalBox{
            width: 100vw;
            height: 100vh;
            overflow: hidden;
            position: fixed;
            top: 0;
            left: 0;
            background: rgba(0,0,0,0.4);
            z-index: 999;

            .modal{
                width: 220px;
                height: 280px;
                overflow: scroll;
                background: #fff;
                border-radius: 10px;
                position: absolute;
                left: 50%;
                top: 50%;
                transform: translate(-50%, -50%);
                -moz-box-shadow:10px 10px 9px #332A0D;
                -webkit-box-shadow:10px 10px 9px #332A0D;
                box-shadow:10px 10px 9px #332A0D;
                padding: 30px 0 0;

                ul{
                    text-align: center;
                    li{
                        list-style: none;
                        line-height: 30px;
                    }
                }
            }
        }
    }
</style>
d. Remarks

.modalOpenThe css styles in a public style, because we have to change is the body style, so the writing style in a component may fail. For example, I will put a stylesrc/assets/css/common.css

/*弹层*/
body.modalOpen {
    -webkit-overflow-scrolling:touch;
    position: fixed;
    width: 100%;
}

Guess you like

Origin blog.csdn.net/weixin_34114823/article/details/91017853