JS实现可拖曳、可关闭的弹窗效果

实现可拖拽、可关闭的弹窗效果需要借助JavaScript和CSS的帮助。主要的实现步骤如下:

步骤一:HTML结构

先定义一个弹窗的HTML结构,包括一个模态框、一个标题、一个内容和两个关闭按钮:

<div class="modal">
  <div class="modal-header">
    <h3 class="modal-title">弹窗标题</h3>
    <button class="btn-close">&times;</button>
  </div>
  <div class="modal-body">
    <p>弹窗内容</p>
  </div>
  <button class="btn-close btn-close-modal">&times;</button>
</div>

其中,.modal是弹窗的容器,.modal-header是弹窗标题的容器,.modal-title是弹窗标题,.btn-close是用于关闭弹窗的按钮,.modal-body是弹窗内容的容器,.btn-close-modal是关闭弹窗按钮的一部分,点击弹窗内容部分也可以关闭弹窗。

步骤二:CSS样式

CSS样式主要是用于定义弹窗的基本样式、位置和动画效果。

.modal {
  position: absolute;
  top: 50%;
  left: 50%;
  transform: translate(-50%, -50%);
  border: 1px solid #ccc;
  background-color: #fff;
  box-shadow: 0 0 10px #aaa;
  z-index: 100;
  display: none;
}

.modal-header {
  padding: 10px;
  background-color: #eee;
  cursor: move;
}

.modal-body {
  padding: 10px;
}

.btn-close {
  position: absolute;
  top: 5px;
  right: 10px;
  font-size: 24px;
  cursor: pointer;
}

.btn-close:hover {
  color: #f00;
}

.btn-close-modal {
  position: absolute;
  top: 0;
  left: 0;
  width: 100%;
  height: 100%;
  cursor: default;
}

.fade-in {
  animation: fade-in 0.3s;
}

.fade-out {
  animation: fade-out 0.3s;
}

@keyframes fade-in {
  from {
    opacity: 0;
  }
  to {
    opacity: 1;
  }
}

@keyframes fade-out {
  from {
    opacity: 1;
  }
  to {
    opacity: 0;
  }
}

其中,.modalposition设置为绝对定位,topleft设置为50%,以便将弹窗居中显示。transform属性用于偏移弹窗,使其相对于中心点水平和垂直居中。

.modal-header中,padding设置为10像素,background-color设置为灰色,cursor设置为move,以便实现拖动弹窗的效果。

.btn-close中,position设置为绝对定位,topright设置为5像素和10像素,使关闭按钮出现在右上角;font-size设置为24像素,使关闭按钮更加显眼;cursor设置为pointer,使鼠标光标变成小手形状。

.fade-in.fade-out是用于实现弹窗的动画效果,fade-in代表淡入,fade-out代表淡出。在动画过程中,会逐渐改变弹窗的透明度(opacity)。

步骤三:JS实现

创建弹窗

先定义一个Modal类,用于创建一个新的弹窗。该类的构造函数接受一个表示弹窗标题的字符串和一个表示弹窗内容的字符串。

class Modal {
  constructor(title, content) {
    this.title = title;
    this.content = content;
    this.modal = null;
    this.init();
  }

  init() {
    this.createModal();
    this.addEventListeners();
  }

  createModal() {
    this.modal = document.createElement("div");
    this.modal.classList.add("modal");

    const header = document.createElement("div");
    header.classList.add("modal-header");

    const title = document.createElement("h3");
    title.classList.add("modal-title");
    title.textContent = this.title;

    const btnClose = document.createElement("button");
    btnClose.classList.add("btn-close");
    btnClose.innerHTML = "&times;";

    header.appendChild(title);
    header.appendChild(btnClose);

    const body = document.createElement("div");
    body.classList.add("modal-body");
    body.innerHTML = this.content;

    this.modal.appendChild(header);
    this.modal.appendChild(body);

    document.body.appendChild(this.modal);
  }

  ...
}

其中,createModal()方法用于动态创建弹窗。通过document.createElement()方法创建了若干个DOM元素,再通过appendChild()方法组装起来,最终添加到document.body中。

弹窗的显示与隐藏

若要弹窗显示需要先调用一个show()方法,弹窗会通过JS的类名添加类名,从而达到一个动态的效果

show() {
  this.modal.classList.add("fade-in");
  this.modal.style.display = "block";
  document.body.style.overflow = "hidden";
}

当弹窗的关闭按钮或者内容区域被点击时,可以通过调用hide()方法关闭弹窗。这个方法跟show()方法加入的类名相似,只是添加的是类名为fade-out,表示关闭的过程

hide() {
  this.modal.classList.add("fade-out");
  setTimeout(() => {
    this.modal.style.display = "none";
    this.modal.classList.remove("fade-in", "fade-out");
    document.body.style.overflow = "auto";
  }, 300);
}

弹窗的拖动

Modal类中添加一个名为dragElement的方法,用于实现弹窗的拖动。在该方法内,需要操控mousedownmouseupmousemove等事件,从而实现拖动弹窗。

dragElement() {
  const header = this.modal.querySelector(".modal-header");
  let x = 0;
  let y = 0;

  header.addEventListener("mousedown", startDrag);

  function startDrag(e) {
    e.preventDefault();
    x = e.clientX;
    y = e.clientY;
    document.addEventListener("mousemove", onDrag);
    document.addEventListener("mouseup", stopDrag);
  }

  function onDrag(e) {
    e.preventDefault();
    const deltaX = e.clientX - x;
    const deltaY = e.clientY - y;
    const modalRect = this.modal.getBoundingClientRect();

    this.modal.style.top = `${modalRect.top + deltaY}px`;
    this.modal.style.left = `${modalRect.left + deltaX}px`;

    x = e.clientX;
    y = e.clientY;
  }

  function stopDrag() {
    document.removeEventListener("mousemove", onDrag);
    document.removeEventListener("mouseup", stopDrag);
  }
}

其中,mousedown事件监听在标题栏上,当事件触发时,事件回调函数startDrag会记录鼠标按下时的坐标。mousemove事件监听在整个文档上,它的回调函数onDrag会计算出鼠标和标题栏的距离差值,并将其添加到弹窗的topleft样式属性上,从而实现弹窗的拖动效果。

示例一:自定义消息弹窗

// HTML结构
<div id="alert-modal" class="modal" style="display: none;">
  <div class="modal-header">
    <h4 class="modal-title">提示</h4>
    <button class="btn-close">&times;</button>
  </div>
  <div class="modal-body">
    <p id="alert-message"></p>
  </div>
</div>

// CSS样式
.modal {
  position: absolute;
  top: 50%;
  left: 50%;
  transform: translate(-50%, -50%);
  border-radius: 8px;
  box-shadow: 0px 0px 10px rgba(0, 0, 0, 0.5);
  background-color: #fff;
  width: 400px;
  z-index: 100;
  display: none;
}
.modal .modal-header {
  padding: 15px;
  border-bottom: 1px solid #eee;
  text-align: center;
  font-size: 20px;
  font-weight: bold;
  position: relative;
}
.modal .modal-header .btn-close {
  position: absolute;
  top: 5px;
  right: 5px;
  font-size: 20px;
  cursor: pointer;
  outline: none;
  border: none;
  background-color: transparent;
}
.modal .modal-body {
  padding: 15px;
}

// JS代码
class AlertModal {
  constructor(message) {
    this.message = message;
    this.init();
  }

  init() {
    this.alertModal = document.getElementById("alert-modal");
    this.alertMessage = document.getElementById("alert-message");
    this.alertMessage.textContent = this.message;
    this.btnClose = this.alertModal.querySelector(".btn-close");
    this.addEventListeners();
  }

  addEventListeners() {
    this.btnClose.addEventListener("click", this.hide.bind(this));
    this.alertModal.addEventListener("click", this.handleModalClick.bind(this));
    window.addEventListener("keyup", this.handleKeyUp.bind(this));
  }

  show() {
    this.alertModal.classList.add("fade-in");
    this.alertModal.style.display = "block";
    document.body.style.overflow = "hidden";
  }

  hide() {
    this.alertModal.classList.add("fade-out");
    setTimeout(() => {
      this.alertModal.style.display = "none";
      this.alertModal.classList.remove("fade-in", "fade-out");
      document.body.style.overflow = "auto";
    }, 300);
  }

  handleModalClick(e) {
    if (e.target === this.alertModal) {
      this.hide();
    }
  }

  handleKeyUp(e) {
    if (e.key === "Escape") {
      this.hide();
    }
  }
}

const btnAlert = document.getElementById("btn-alert");
btnAlert.addEventListener("click", handleAlertClick);

function handleAlertClick() {
  const message = "您好,欢迎访问该网站!";
  const alertModal = new AlertModal(message);
  alertModal.show();
}

示例二:加载中的遮罩弹窗

// HTML结构
<div id="loading-modal" class="modal" style="display: none;">
  <div class="modal-body">
    <div class="loader"></div>
  </div>
</div>

// CSS样式
.modal .modal-body {
  padding: 0;
  background-color: transparent;
}
.modal .modal-body .loader {
  border: 16px solid #f3f3f3; /* Light grey */
  border-top: 16px solid #3498db; /* Blue */
  border-radius: 50%;
  width: 120px;
  height: 120px;
  animation: spin 2s linear infinite;
  margin: auto;
}
@keyframes spin {
  0% {
    transform: rotate(0deg);
  }
  100% {
    transform: rotate(360deg);
  }
}

// JS代码
class LoadingModal {
  constructor() {
    this.init();
  }

  init() {
    this.loadingModal = document.getElementById("loading-modal");
  }

  show() {
    this.loadingModal.style.display = "block";
  }

  hide() {
    this.loadingModal.style.display = "none";
  }
}

const btnLoading = document.getElementById("btn-loading");
btnLoading.addEventListener("click", handleLoadingClick);

function handleLoadingClick() {
  const loadingModal = new LoadingModal();
  loadingModal.show();

  setTimeout(function () {
    loadingModal.hide();
  }, 2000);
}

本站文章如无特殊说明,均为本站原创,如若转载,请注明出处:JS实现可拖曳、可关闭的弹窗效果 - Python技术站

(0)
上一篇 2023年6月11日
下一篇 2023年6月11日

相关文章

  • js获取时间(本周、本季度、本月..)

    获取时间是在JavaScript中很常见的需求之一。本周、本季度、本月是获取时间的常见需求,下面我们就来介绍怎样用JavaScript来实现这些功能。 获取本周、本季度、本月 获取本周 获取本周的方法,最简单的就是使用Date对象来获取当前时间,再获取当天是周几,然后算出距离本周周一的天数,最后再得到本周周一的日期即可。 下面是实现代码: // 获取本周周一…

    JavaScript 2023年5月27日
    00
  • ES6的新特性概览

    ES6的新特性概览完整攻略 ECMAScript 6.0(简称ES6)是JavaScript的下一代标准,引入了许多有用的新特性,大大提高了JavaScript的易用性和可读性。下面我们就来整理一下ES6的新特性,包括变量定义、箭头函数、Promise等内容。 变量定义 在ES6中,新增了两个定义变量的关键字:let和const。相较于ES5中的var,le…

    JavaScript 2023年6月11日
    00
  • js定时器出现第一次延迟的原因及解决方法

    JS定时器出现第一次延迟的原因是:浏览器在解释JavaScript代码时,会从上到下依次执行,而定时器是一种异步事件,会被放到事件队列中,等待JavaScript引擎空闲时才会执行。因此,定时器第一次执行会有一段时间的等待。 解决方法则是使用setTimeout()或setInterval()方法,并通过调用一次函数来解决此问题。 示例1:使用setTime…

    JavaScript 2023年6月11日
    00
  • JavaScript函数定义方法实例详解

    JavaScript函数定义方法实例详解 在JavaScript中,函数是一种重要的编程概念。函数能够帮助我们将代码组织得更好、复用性更高,并且能够进一步实现更为复杂的功能。下面将详细讲解JavaScript函数定义的多种方法。 1.函数声明 函数声明是一种最经典的JavaScript函数定义方式。 function add(a, b) { return a…

    JavaScript 2023年6月10日
    00
  • javascript的hashCode函数实现代码小结

    为了讲解JavaScript的hashCode函数实现代码小结,让我先来介绍一下什么是hashCode。 HashCode是一种数据结构,它用于将一些复杂的数据结构简化为一些简单的数据类型,通常是数字或字符串。HashCode算法将数据结构转换为一个整数,使其更容易存储或比较。在JavaScript中,我们通常使用字符串作为HashCode的生成器。生成的H…

    JavaScript 2023年5月28日
    00
  • javascript常用方法总结

    作为网站作者,我可以为您提供“Javascript常用方法总结”的完整攻略。 1. 简介 Javascript是一种广泛应用于web开发的编程语言,它具有很多强大的方法,可以对页面上的元素进行操作、获取信息、修改样式等等。在本篇攻略中,我将为大家梳理一些常用的javascript方法及其使用方法,希望能对前端开发的同学有所帮助。 2. 常用方法 2.1. g…

    JavaScript 2023年5月17日
    00
  • 返回页面顶部top按钮通过锚点实现(自写)

    下面是”返回页面顶部top按钮通过锚点实现(自写)”的完整攻略: 什么是返回页面顶部top按钮和锚点 在一个网页中,如果页面内容很多,用户在滚动页面时需要不断的滑动鼠标或手指,有时非常的不方便。为了解决这个问题,我们通常会添加一个“返回页面顶部”的按钮,让用户一键回到页面的顶部。 而锚点是指通过HTML代码中的href属性,在同一页面内跳转到不同的锚点位置,…

    JavaScript 2023年6月11日
    00
  • JavaScript的Module模式编程深入分析

    JavaScript的Module模式编程深入分析 Module模式是JavaScript中常用的一种编程模式,它能够帮助我们解决变量作用域、命名冲突、代码复用等问题。在本文中,我们将深入分析JavaScript的Module模式编程,包括如何创建一个模块、模块的特点和示例说明。 如何创建一个模块 创建一个Module模式的关键是使用闭包。闭包可以在函数执行…

    JavaScript 2023年5月27日
    00
合作推广
合作推广
分享本页
返回顶部