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日

相关文章

  • JavaScript中的50+个实用工具函数小结

    为了更好地讲解“JavaScript中的50+个实用工具函数小结”,我们可以按照以下步骤进行: 1. 定义 在文章的第一部分,应当对所涉及的内容进行定义和说明。具体来说,可以介绍什么是实用工具函数(Utility Function),以及JavaScript中有哪些常见的工具函数。 示例: 1.1 实用工具函数 实用工具函数是可以在项目开发中频繁使用的、具有…

    JavaScript 2023年6月10日
    00
  • jquery+ajax每秒向后台发送请求数据然后返回页面的代码

    首先,我们需要明确这个需求的实现流程:前端通过jQuery发起Ajax请求,后端接收请求并处理,返回数据给前端,前端再通过jQuery将数据渲染至页面上。其中,需要注意的是前端需要每秒向后端发送一次请求,需要使用JavaScript定时器来完成。 下面,我提供两个示例,分别是使用原生JavaScript和jQuery实现每秒向后端发送请求并更新页面的代码。 …

    JavaScript 2023年6月11日
    00
  • jquery处理json对象

    一、简介 在前端开发中,处理 JSON 数据是一项基本技能,而 jQuery 正是我们最常使用的 JS 库之一。本文将详细介绍 jQuery 如何处理 JSON 数据对象。 二、jQuery 处理 JSON 将 JSON 字符串转换为 JavaScript 对象 使用 JSON.parse() 方法,可以将 JSON 字符串转换为 JavaScript 对象…

    JavaScript 2023年5月27日
    00
  • 用javascript做一个小游戏平台 (二) 游戏选择器

    下面就让我来详细讲解如何用 JavaScript 做一个小游戏平台。 游戏选择器 游戏选择器是一个可以让用户选择游戏的组件,我们需要实现以下功能: 显示游戏的缩略图和名称。 点击缩略图或名称可以进入游戏。 可以添加新游戏。 首先,我们需要初始化一个游戏列表。我们可以使用一个存储游戏信息的对象数组来存储游戏列表。每个游戏对象都应该包含游戏名称、游戏缩略图、游戏…

    JavaScript 2023年6月10日
    00
  • 微信小程序防止多次点击跳转和防止表单组件输入内容多次验证功能(函数防抖)

    微信小程序中,为了提高用户体验,往往需要对一些按钮或表单组件进行防止多次点击或输入内容多次验证,以避免用户重复提交数据或误操作。这时,我们可以使用函数防抖来实现这些效果。 函数防抖是指在一段时间内,多次触发同一事件,只执行一次函数。具体而言,是在延迟时间内,如果再次触发了同一事件,则清空之前的计时器并重新开始计时,直到延迟时间过去后再触发该事件时才会执行真正…

    JavaScript 2023年6月10日
    00
  • JavaScript中从setTimeout与setInterval到AJAX异步

    JavaScript中从setTimeout与setInterval到AJAX异步 setTimeout与setInterval setTimeout setTimeout是JavaScript中的一个定时器函数,它接受2个参数:一个函数和一个时间(单位为毫秒)。当函数被发送到浏览器的事件队列时,它会在指定的时间之后执行。 setTimeout(functi…

    JavaScript 2023年6月11日
    00
  • webpack自定义loader全面详解

    webpack自定义loader全面详解 什么是loader 在webpack的构建过程中,通过loader可以对文件进行转换处理。loader可以将文件从不同的语言(例如:TypeScript)转换为JavaScript,或将内联图像转换为data URL。webpack本身只能理解JavaScript和JSON文件,而loader能够让webpack处理…

    JavaScript 2023年6月10日
    00
  • 关于js typeof 与 instanceof 判断数据类型区别及开发使用

    关于 JS typeof 与 instanceof 判断数据类型的区别及使用攻略 在 JavaScript 开发中,判断数据类型是一项非常重要的操作,正因为这个原因,我们需要了解如何使用 typeof 和 instanceof 来判断不同类型的数据。 typeof 操作符 typeof 操作符是 JavaScript 中最常用的类型判断工具之一,它可以返回一…

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