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

文件结构

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

说明

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

效果图

下图为弹出前样式
通过 JavaScript 实现弹出层的简单方式_第2张图片
下图为弹出层样式
通过 JavaScript 实现弹出层的简单方式_第3张图片

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="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">Triggerbutton>
    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,前端)