前端实战:实现块级元素的拖拽与缩放功能

在现代网页开发中,用户交互是一个非常重要的部分。在这篇文章中,我们将详细介绍如何使用原生 JavaScript 实现块级元素的拖拽与缩放功能。具体来说,我们将实现以下功能:

  1. 点击并拖动 outer 元素,可以移动整个块。
  2. 点击并拖动 inner 元素,可以调整 outer 元素的宽高。
    在这里插入图片描述

实现思路

为了实现上述功能,我们需要对两个元素分别进行事件监听和处理。具体来说,我们需要监听 mousedownmousemovemouseup 事件,并根据事件触发的位置和元素的状态,来决定执行拖动还是缩放操作。

HTML 结构

首先,我们定义两个块元素 outerinnerinner 位于 outer 的右下角,用于调整 outer 的大小。

<div id="outer" style="width: 100px; height: 100px; border: 1px solid black; position: relative;"><span id="inner" style="position: absolute; bottom: 0; right: 0; width: 10px; height: 10px; background: red; cursor: nwse-resize;"></span>
</div>

在这里插入图片描述

CSS 样式

简单的样式来定义块元素的尺寸和位置:

#outer {width: 100px;height: 100px;border: 1px solid black;position: relative;
}#inner {position: absolute;bottom: 0;right: 0;width: 10px;height: 10px;background: red;cursor: nwse-resize;
}

JavaScript 实现

接下来,我们编写 JavaScript 代码,实现块的拖动和缩放功能。我们需要两个主要的事件处理程序,一个用于 outer 的拖动,另一个用于 inner 的缩放。

拖动功能

首先实现 outer 的拖动功能:

document.addEventListener('DOMContentLoaded', function() {const outer = document.getElementById('outer');let isDragging = false;let dragStartX, dragStartY, startLeft, startTop;outer.addEventListener('mousedown', function(e) {if (e.target === outer) {isDragging = true;dragStartX = e.clientX;dragStartY = e.clientY;startLeft = outer.offsetLeft;startTop = outer.offsetTop;document.addEventListener('mousemove', drag);document.addEventListener('mouseup', stopDrag);}});function drag(e) {if (isDragging) {const dx = e.clientX - dragStartX;const dy = e.clientY - dragStartY;outer.style.left = `${startLeft + dx}px`;outer.style.top = `${startTop + dy}px`;}}function stopDrag() {isDragging = false;document.removeEventListener('mousemove', drag);document.removeEventListener('mouseup', stopDrag);}
});

以下是实现拖动效果,此时还未实现缩放功能。
在这里插入图片描述

缩放功能

接下来实现 inner 的缩放功能:

document.addEventListener('DOMContentLoaded', function() {const outer = document.getElementById('outer');const inner = document.getElementById('inner');let isResizing = false;let resizeStartX, resizeStartY, startWidth, startHeight;inner.addEventListener('mousedown', function(e) {e.stopPropagation(); // 阻止事件冒泡到 outerisResizing = true;resizeStartX = e.clientX;resizeStartY = e.clientY;startWidth = outer.offsetWidth;startHeight = outer.offsetHeight;document.addEventListener('mousemove', resize);document.addEventListener('mouseup', stopResize);});function resize(e) {if (isResizing) {const dx = e.clientX - resizeStartX;const dy = e.clientY - resizeStartY;outer.style.width = `${startWidth + dx}px`;outer.style.height = `${startHeight + dy}px`;}}function stopResize() {isResizing = false;document.removeEventListener('mousemove', resize);document.removeEventListener('mouseup', stopResize);}
});

组合功能

为了确保两个功能可以同时存在,我们需要确保在 inner 被拖动时,outer 的拖动功能不会被触发。为此,我们在 innermousedown 事件处理程序中调用 e.stopPropagation(),以阻止事件冒泡到 outer

完整代码

以下是完整的实现代码,包括 HTML、CSS 和 JavaScript 部分:

<!DOCTYPE html>
<html lang="en">
<head><meta charset="UTF-8"><meta name="viewport" content="width=device-width, initial-scale=1.0"><title>拖拽与缩放功能</title><style>#outer {width: 100px;height: 100px;border: 1px solid black;position: absolute;}#inner {position: absolute;bottom: 0;right: 0;width: 10px;height: 10px;background: red;cursor: nwse-resize;}</style>
</head>
<body><div id="outer"><span id="inner"></span></div><script>document.addEventListener('DOMContentLoaded', function() {const outer = document.getElementById('outer');const inner = document.getElementById('inner');let isDragging = false;let isResizing = false;let dragStartX, dragStartY, startLeft, startTop;let resizeStartX, resizeStartY, startWidth, startHeight;outer.addEventListener('mousedown', function(e) {if (e.target === outer) {isDragging = true;dragStartX = e.clientX;dragStartY = e.clientY;startLeft = outer.offsetLeft;startTop = outer.offsetTop;document.addEventListener('mousemove', drag);document.addEventListener('mouseup', stopDrag);}});inner.addEventListener('mousedown', function(e) {e.stopPropagation(); // 阻止事件冒泡到 outerisResizing = true;resizeStartX = e.clientX;resizeStartY = e.clientY;startWidth = outer.offsetWidth;startHeight = outer.offsetHeight;document.addEventListener('mousemove', resize);document.addEventListener('mouseup', stopResize);});function drag(e) {if (isDragging) {const dx = e.clientX - dragStartX;const dy = e.clientY - dragStartY;outer.style.left = `${startLeft + dx}px`;outer.style.top = `${startTop + dy}px`;}}function stopDrag() {isDragging = false;document.removeEventListener('mousemove', drag);document.removeEventListener('mouseup', stopDrag);}function resize(e) {if (isResizing) {const dx = e.clientX - resizeStartX;const dy = e.clientY - resizeStartY;outer.style.width = `${startWidth + dx}px`;outer.style.height = `${startHeight + dy}px`;}}function stopResize() {isResizing = false;document.removeEventListener('mousemove', resize);document.removeEventListener('mouseup', stopResize);}});</script>
</body>
</html>

总结

通过本文的介绍和代码示例,我们成功实现了使用原生 JavaScript 实现块级元素的拖拽与缩放功能。在实际开发中,这种交互功能非常常见,并且对于提升用户体验非常有帮助。希望本文能够帮助你更好地理解事件处理和 DOM 操作。如果你有任何问题或建议,欢迎交流讨论。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.rhkb.cn/news/361517.html

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

利用LinkedHashMap实现一个LRU缓存

一、什么是 LRU LRU是 Least Recently Used 的缩写&#xff0c;即最近最少使用&#xff0c;是一种常用的页面置换算法&#xff0c;选择最近最久未使用的页面予以淘汰。 简单的说就是&#xff0c;对于一组数据&#xff0c;例如&#xff1a;int[] a {1,2,3,4,5,6}&#xff0c;…

Android Studio上传新项目到Gitee

一、在Gitee上创建仓库 首先需要再Gitee上创建仓库 1、在Gitee中新建仓库 2、输入仓库信息 3、生成仓库地址 创建成功会生成一个仓库地址&#xff0c;格式如下&#xff1a; https://gitee.com/test/compose_mvi_demo.git二、Android Studio 上传项目到Gitee 1、在Android …

MySQL数据库笔记(二)

第一章 单行函数 1.1 什么是函数 函数的作用是把我们经常使用的代码封装起来,需要的时候直接调用即可。这样既提高了代码效率,又提高了可维护性。在SQL中使用函数,极大地提高了用户对数据库的管理效率。 1.2 定义 操作数据对象。 接受参数返回一个结果。 只对一行进行…

使用PEFT库进行ChatGLM3-6B模型的LORA高效微调

PEFT库进行ChatGLM3-6B模型LORA高效微调 LORA微调ChatGLM3-6B模型安装相关库使用ChatGLM3-6B模型GPU显存占用准备数据集加载模型加载数据集数据处理数据集处理配置LoRA配置训练超参数开始训练保存LoRA模型模型推理从新加载合并模型使用微调后的模型 LORA微调ChatGLM3-6B模型 本…

【SpringSecurity】认证与鉴权框架SpringSecurity——授权

目录 权限系统的必要性常见的权限管理框架SpringSecurity授权基本流程准备脚本限制访问资源所需权限菜单实体类和Mapper封装权限信息封装认证/鉴权失败处理认证失败封装鉴权失败封装配置SpringSecurity 过滤器跨域处理接口添加鉴权hasAuthority/hasAnyAuthorityhasRole/​ hasA…

node mySql 实现数据的导入导出,以及导入批量插入的sql语句

node 实现导出, 在导出excel中包含图片&#xff08;附件&#xff09; node 实现导出, 在导出excel中包含图片&#xff08;附件&#xff09;-CSDN博客https://blog.csdn.net/snows_l/article/details/139999392?spm1001.2014.3001.5502 一、效果 如图&#xff1a; 二、导入 …

声场合成新方法:基于声波传播的框架

声场合成是指在房间内的麦克风阵列上&#xff0c;根据来自房间内其他位置的声源信号&#xff0c;合成每个麦克风的音频信号。它是评估语音/音频通信设备性能指标的关键任务&#xff0c;因为它是一种成本效益高的方法&#xff0c;用于数据生成以替代真实的数据收集&#xff0c;后…

elasticsearch的安装和配置

单节点安装与部署 我们通过docker进行安装 1.docker的安装 如果以及安装了docker就可以跳过这个步骤。 首先更新yum: yum update安装docker: yum install docker查看docker的版本&#xff1a; docker -v此时我们的docker就安装成功了。 2.创建网络 我们还需要部署kiban…

盲源信道分离—FastICA算法性能仿真

本案例中使用Matlab软件对FastICA算法的声音分离性能进行了仿真&#xff0c;分别对简单波形的混合信号、不同类型声音的混合信号、同一类型的混合信号这三种情况进行仿真&#xff0c;主要从分离信号的波形形状、串音误差两方面对分离性能进行衡量&#xff0c;仿真结果显示快速I…

可以一键生成热点营销视频的工具,建议收藏

在当今的商业环境中&#xff0c;热点营销已经成为了一种非常重要的营销策略。那么&#xff0c;什么是热点营销呢&#xff1f;又怎么做热点营销视频呢&#xff1f; 最近高考成绩慢慢公布了&#xff0c;领导让结合“高考成绩公布”这个热点&#xff0c;做一个关于企业或产品的营销…

3.任务的创建与删除

1.什么是任务&#xff1f; 任务可以理解为进程/线程&#xff0c;创建一个任务&#xff0c;就会在内存开辟一个空间。 任务通常都含有while(1)死循环 2.任务创建与删除相关的函数 3.CUBEMAX相关配置 编辑一个led1闪烁的任务

RPC架构基本结构和核心技术

当你在构建一个分布式系统时&#xff0c;势必需要考虑的一个问题是&#xff1a;如何实现服务与服务之间高效调用&#xff1f;当然&#xff0c;你可以使用Dubbo或Spring Cloud等分布式服务框架来完成这个目标&#xff0c;这些框架帮助我们封装了技术实现的复杂性。那么&#xff…

Gitlab合并代码并解决冲突演示

天行健&#xff0c;君子以自强不息&#xff1b;地势坤&#xff0c;君子以厚德载物。 每个人都有惰性&#xff0c;但不断学习是好好生活的根本&#xff0c;共勉&#xff01; 文章均为学习整理笔记&#xff0c;分享记录为主&#xff0c;如有错误请指正&#xff0c;共同学习进步。…

Jenkins定时构建自动化(二):Jenkins的定时构建

目录 ​编辑 一、 jenkins定时构建语法&#xff1a; 1. 语法规则&#xff1a; 2. 常见用法举例 3. 再次举例 接上一篇&#xff1a;Jenkins定时构建自动化(一)&#xff1a;Jenkins下载安装配置&#xff1a;Jenkins定时构建自动化(一)&#xff1a;Jenkins下载安装配置-CSDN博客 …

input()函数——输入

自学python如何成为大佬(目录):https://blog.csdn.net/weixin_67859959/article/details/139049996?spm1001.2014.3001.5501 语法参考 input()函数可以提示并接收用户的输入&#xff0c;将所有的输入按照字符串进行处理&#xff0c;并返回一个字符串&#xff0c;input()函数的…

化茧成蝶 | 继HuggingFace首家落地大模型具身智能场景

关于具身智能的起源 近年来&#xff0c;大语言模型&#xff08;LLMs&#xff09;的兴起给机器人领域带来了革命性的改变&#xff0c;大模型赋予了传统机器人理解和推理的能力&#xff0c;让具身智能这一概念再度出现在大众的视角中。OpenCSG 作为国内 AI 开源社区的先锋&#…

python flask 入门-helloworld

学习视频链接&#xff1a; 01-【前奏】课程介绍_哔哩哔哩_bilibili 1.安装flask pip install flask 踩坑记&#xff1a;本机不要连代理&#xff0c;否则无法install 提示报错valueError: check_hostname requires server_hostname 2.程序编写 在根目录下创建 app.py fr…

从零开始学docker(四)-安装mysql及主从配置(一)

mysql MySQL是一个关系型数据库管理系统&#xff0c;由瑞典MySQL AB 公司开发&#xff0c;属于 Oracle 旗下产品。MySQL 是最流行的关系型数据库管理系统之一&#xff0c;在 WEB 应用方面&#xff0c;MySQL是最好的 RDBMS (Relational Database Management System&#xff0c;关…

【HDC.2024】华为云Astro低代码平台开启AI敏捷组装时代,探索低代码创新无限可能

6月22日&#xff0c;华为开发者大会2024期间&#xff0c;华为云举办了以“敏捷组装时代来临「高低零码智能协同」加速行业创新”为主题的Astro低代码平台专题论坛。论坛汇聚了业界精英和专家学者&#xff0c;共同探讨低代码技术在推动企业数字化转型中的重要实践及未来发展趋势…

cs与msf权限传递,与mimikatz抓取win2012明文密码

CS与MSF的权限互相传递抓取windows2012的明文密码 CS与MSF的权限互相传递 1、启动cs服务端 2、客户端连接 3、配置监听&#xff0c;并设置监听端口为9999 4、生成脚本 5、开启服务&#xff0c;下载并运行木马 已获取权限 6、进入msf并设置监听 7、cs新建监听&#xff0c;与m…