欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

通过 JavaScript 实现弹出层的简单方式

程序员文章站 2022-05-06 09:33:08
...

文件结构

文件结构参照下图,忽略 .vscode 文件夹
通过 JavaScript 实现弹出层的简单方式

说明

  • 点击按钮出现弹出层
  • 允许用户自定义弹出框内容
  • 弹出层存在时隐藏滚动条并禁止滚动
  • 点击弹出框的按钮或右上角的 X 关闭弹出层

效果图

下图为弹出前样式
通过 JavaScript 实现弹出层的简单方式
下图为弹出层样式
通过 JavaScript 实现弹出层的简单方式

HTML 结构

<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>弹出层练习</title>
    <link rel="stylesheet" href="./main.css" />
</head>

<body>
    <!-- 弹出层结构 -->
    <!-- <div class="mask"></div>
    <div class="modal-wrap">
        <div class="modal">
            <div class="modal-header">
                <div class="modal-title">Title</div>
                <div class="close">
                    <span></span>
                    <span></span>
                </div>
            </div>

            <div class="modal-content">Content</div>

            <div class="modal-footer">
                <button class="modal-confirm">Confirm</button>
            </div>
        </div>
    </div> -->

    <!-- 用户定义弹出框内容 -->
    <div class="user-input">
        <input type="text" id="input-title" placeholder="请输入弹出框标题(默认为 Title)" />
        <input type="text" id="input-content" placeholder="请输入弹出框内容(默认为 Content)" />
        <input type="text" id="input-buttontext" placeholder="请输入弹出框关闭按钮文字(默认为 Confirm)" />
    </div>

    <!-- 点击按钮触发弹出层 -->
    <div>
        <button id="test">Trigger</button>
    </div>

    <script src="./main.js"></script>
</body>

</html>

CSS

body {
    padding: 0;
    margin: 0;
    font-size: 14px;
}

.mask {
    position: fixed;
    height: 100vh;
    width: 100vw;
    top: 0;
    left: 0;
    z-index: 1;
    background-color: rgba(0, 0, 0, 0.3);
    overflow: hidden;
}

.user-input {
    display: grid;
    grid-template-columns: 400px;
    grid-template-rows: repeat(3, 1fr);
    row-gap: 10px;
    margin-bottom: 10px;
}

.user-input input {
    outline: none;
    padding: 4px;
}

.modal-wrap {
    position: fixed;
    top: 0;
    left: 0;
    display: flex;
    height: 100vh;
    width: 100vw;
    justify-content: center;
    align-items: center;
    z-index: 2;
    overflow: hidden;
}

.modal {
    background-color: #fff;
    box-shadow: 0 0 30px rgba(0, 0, 0, 0.1);
    width: 400px;
    border-radius: 2px;
}

.modal-header,
.modal-content {
    border-bottom: 1px solid #eee;
}

.modal-header {

    position: relative;
}

.modal-title {
    padding: 10px;
    font-size: 16px;
    font-weight: 700;
}

.close:hover span {
    background-color: red;
}

.close {
    position: absolute;
    right: 10px;
    top: 10px;
    cursor: pointer;
    width: 16px;
    height: 16px;
}

.close span {
    display: block;
    position: absolute;
    width: 16px;
    height: 2px;
    background-color: lightgray;
    top: 50%;
    transition: all 0.2s ease-out;
}

.close span:nth-child(1) {
    transform: rotate(-45deg);
}

.close span:nth-child(2) {
    transform: rotate(45deg);
}

.modal-content {
    padding: 10px;
}

.modal-footer{
    padding: 10px;
    text-align: right;
}

JavaScript

// 隐藏滚动条并禁止滚动
let stopScroll = () => {
    let body = document.querySelector('body');
    body.style.overflow = 'hidden';
    body.onmousewheel = () => false;
    body.onkeydown = function (e) {
        if (e.keyCode == 38 || e.keyCode == 40) {
            return false;
        }
    }
}

// 显示滚动条并允许滚动
let openScroll = () => {
    let body = document.querySelector('body');
    body.style.overflow = 'auto';
    body.onmousewheel = () => true;
    body.onkeydown = function (e) {
        if (e.keyCode == 38 || e.keyCode == 40) {
            return true;
        }
    }
}

// 显示弹出框
let showModal = () => {
    // 获取用户输入内容
    let title = document.querySelector('#input-title').value;
    let content = document.querySelector('#input-content').value;
    let buttonText = document.querySelector('#input-buttontext').value;
    title = title === '' ? undefined : title;
    content = content === '' ? undefined : content;
    buttonText = buttonText === '' ? undefined : buttonText;
    let mask = genMask();
    let modalWrap = genModalWrap();
    let modal = genModal(title, content, buttonText);
    let body = document.querySelector('body');
    modalWrap.appendChild(modal);
    body.appendChild(mask);
    body.appendChild(modalWrap);
    stopScroll();
    return true;
}

// 隐藏弹出框
let hideModal = () => {
    let mask = document.querySelector('.mask');
    let modalWrap = document.querySelector('.modal-wrap');
    let body = document.querySelector('body');
    body.removeChild(mask);
    body.removeChild(modalWrap);
    openScroll();
    return true;
}

// 生成指定名称的 tag 并添加相应的 class
let createElementWithClasslist = (name, classList = []) => {
    let ele = document.createElement(name);
    for (const v of classList) {
        ele.classList.add(v);
    }
    return ele;
}

// 生成弹出框
let genModal = (title = 'Title', content = 'Content', buttonText = 'Confirm') => {
    let modal = createElementWithClasslist('div', ['modal']);
    // modalHeader
    let modalHeader = createElementWithClasslist('div', ['modal-header']);
    let modalTitle = createElementWithClasslist('div', ['modal-title']);
    modalTitle.innerHTML = title;
    let close = createElementWithClasslist('div', ['close']);
    close.appendChild(document.createElement('span'));
    close.appendChild(document.createElement('span'));
    // 点击 X 关闭弹出框
    close.addEventListener('click', hideModal);
    modalHeader.appendChild(modalTitle);
    modalHeader.appendChild(close);
    // modalContent
    let modalContent = createElementWithClasslist('div', ['modal-content']);
    modalContent.innerHTML = content;
    // modalFooter
    let modalFooter = createElementWithClasslist('div', ['modal-footer']);
    let modalConfirm = createElementWithClasslist('button', ['modal-confirm']);
    modalConfirm.innerHTML = buttonText;
    // 点击按钮关闭弹出框
    modalConfirm.addEventListener('click', hideModal);
    modalFooter.appendChild(modalConfirm);
    // building
    modal.appendChild(modalHeader);
    modal.appendChild(modalContent);
    modal.appendChild(modalFooter);
    // return element
    return modal;
}

// 生成遮罩层
let genMask = () => {
    return createElementWithClasslist('div', ['mask']);
}

// 生成弹出框的 wrapper
let genModalWrap = () => {
    return createElementWithClasslist('div', ['modal-wrap']);
}

// 为按钮绑定事件(点击时出现弹出层)
let testButton = document.querySelector('#test');
testButton.addEventListener('click', showModal);
相关标签: JavaScript 前端