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

yizhihongxing

实现可拖拽、可关闭的弹窗效果需要借助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日

相关文章

  • JavaScript中Dom操作实例详解

    JavaScript中Dom操作实例详解 什么是Dom Dom,即Document Object Model,指的是文档对象模型。 它是一个用于HTML和XML文档的编程接口,可以改变或者操作文档的内容、结构和样式。 通过Dom,我们可以像操作HTML页面一样,动态地修改页面上的内容和样式,实现网页的交互和动态效果。 Dom元素的选取 通过Dom元素的选取,…

    JavaScript 2023年6月10日
    00
  • js判断在哪个浏览器打开项目的方法

    要判断当前网页所在的浏览器类型,可以使用JavaScript的navigator对象。该对象提供了一些属性,包括userAgent,用于返回客户端的信息,包括浏览器类型、版本、操作系统等。在浏览器端执行以下代码可输出当前浏览器的版本信息: const browser = navigator.userAgent.toLowerCase(); console.l…

    JavaScript 2023年6月11日
    00
  • JS实现继承的几种常用方式示例

    下面是详细的“JS实现继承的几种常用方式示例”的完整攻略。 什么是继承 继承是一种代码复用的技术,它使得子类获得父类的属性和方法。在 JavaScript 中,实现继承有多种方式,本文将介绍几种常用的方式。 实现继承的几种常用方式 原型链继承 原型链继承是通过设置子类的原型对象指向父类的实例对象实现的。这样就可以使子类继承父类的属性和方法。当在子类实例中查找…

    JavaScript 2023年5月28日
    00
  • javascript 对象比较实现代码

    如果要实现JavaScript对象的比较,可以使用比较运算符==和===来比较两个对象(当然,也可以使用Object.is()方法进行比较)。但是,如果是比较两个具有同样键名和键值对的对象时,这些运算符和方法都不能完成任务。因为这些运算符和方法只能比较变量存储的是对象引用,而不是对象自身。因此,我们需要使用自定义函数来比较两个对象的每个键名和键值对是否相等。…

    JavaScript 2023年5月27日
    00
  • javascript先序遍历DOM树的方法

    关于JavaScript先序遍历DOM树的方法,以下是详细讲解的完整攻略: 什么是DOM树? 首先我们需要了解什么是DOM树,DOM(Document Object Model)树是浏览器用来解析HTML文档时,生成的一颗树状结构。它包含了HTML标签、文本、注释等所有节点,每个节点都是一个实际存在的JS对象。DOM树中的节点按照层级关系排列,我们可以通过J…

    JavaScript 2023年6月10日
    00
  • JavaScript输入分钟、秒倒计时技巧总结(附代码)

    我来详细讲解“JavaScript输入分钟、秒倒计时技巧总结(附代码)”的完整攻略。 概述 本文主要介绍如何利用JavaScript实现分钟、秒倒计时,并提供了相关的代码示例和解释。读者可以根据自己的需求进行参考和修改,具体实现过程可以参考下文。 实现思路 主要实现过程是利用setInterval()函数和JavaScript DOM,通过获取输入的分钟和秒…

    JavaScript 2023年5月27日
    00
  • Javascript中级语法快速入手

    Javascript中级语法快速入手 什么是Javascript中级语法 Javascript中级语法是一组更高阶的Javascript语言特性。与初级语法不同,它涵盖了更多复杂的用法和更繁琐的细节。 Javascript中级语法有哪些 Javascript中级语法包括但不限于以下内容: 对象:Javascript的面向对象特性 函数:更为复杂的函数定义和调…

    JavaScript 2023年5月27日
    00
  • 在JavaScript中处理字符串之link()方法的使用

    让我详细讲解一下JavaScript中处理字符串之link()方法的使用吧! link() 方法是什么? link() 是字符串对象的方法,它可以生成一个HTML链接标签 (<a>) 用于把指定的字符串转换成可点击的链接。link() 方法具有以下语法: str.link(url) 其中: str:需要生成链接的字符串。 url:链接所指向的UR…

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