【工作记录】基于CSS+JS可拖拽改变大小、可吸附到边界的DIV

记录一段实现可拖拽、可自动吸附到边界的代码。

<!DOCTYPE html>
<html lang="en">
<head><style>body {overflow: hidden;}#pane {position: absolute;width: 45%;height: 45%;top: 20%;left: 20%;margin: 0;padding: 0;z-index: 99;border: 2px solid purple;background: #fefefe;}#title {font-family: monospace;background: purple;color: white;font-size: 16px;height: 22px;text-align: center;}#ghostpane {background: #999;opacity: 0.2;width: 45%;height: 45%;top: 20%;left: 20%;position: absolute;margin: 0;padding: 0;z-index: 98;-webkit-transition: all 0.25s ease-in-out;-moz-transition: all 0.25s ease-in-out;-ms-transition: all 0.25s ease-in-out;-o-transition: all 0.25s ease-in-out;transition: all 0.25s ease-in-out;}</style><title>测试div可拖拽</title><meta http-equiv="Content-Type" content="text/html;charset=utf-8"/>
</head>
<body>
<div>这里是测试文本
</div>
<div id="pane"><div id="title">属性配置</div>
</div>
<div id="ghostpane"></div>
<script>// Minimum resizable areavar minWidth = 400;var minHeight = 200;// Thresholdsvar FULLSCREEN_MARGINS = -10;var MARGINS = 4;// End of what's configurable.var clicked = null;var onRightEdge, onBottomEdge, onLeftEdge, onTopEdge;var rightScreenEdge, bottomScreenEdge;var preSnapped;var b, x, y;var redraw = false;var pane = document.getElementById('pane');var ghostpane = document.getElementById('ghostpane');function setBounds(element, x, y, w, h) {element.style.left = x + 'px';element.style.top = y + 'px';element.style.width = w + 'px';element.style.height = h + 'px';}function hintHide() {setBounds(ghostpane, b.left, b.top, b.width, b.height);ghostpane.style.opacity = 0;}// Mouse eventspane.addEventListener('mousedown', onMouseDown);document.addEventListener('mousemove', onMove);document.addEventListener('mouseup', onUp);// Touch eventspane.addEventListener('touchstart', onTouchDown);document.addEventListener('touchmove', onTouchMove);document.addEventListener('touchend', onTouchEnd);function onTouchDown(e) {onDown(e.touches[0]);e.preventDefault();}function onTouchMove(e) {onMove(e.touches[0]);}function onTouchEnd(e) {if (e.touches.length === 0) onUp(e.changedTouches[0]);}function onMouseDown(e) {onDown(e);e.preventDefault();}function onDown(e) {calc(e);var isResizing = onRightEdge || onBottomEdge || onTopEdge || onLeftEdge;clicked = {x: x,y: y,cx: e.clientX,cy: e.clientY,w: b.width,h: b.height,isResizing: isResizing,isMoving: !isResizing && canMove(),onTopEdge: onTopEdge,onLeftEdge: onLeftEdge,onRightEdge: onRightEdge,onBottomEdge: onBottomEdge};}function canMove() {return x > 0 && x < b.width && y > 0 && y < b.height && y < 30;}function calc(e) {b = pane.getBoundingClientRect();x = e.clientX - b.left;y = e.clientY - b.top;onTopEdge = y < MARGINS;onLeftEdge = x < MARGINS;onRightEdge = x >= b.width - MARGINS;onBottomEdge = y >= b.height - MARGINS;rightScreenEdge = window.innerWidth - MARGINS;bottomScreenEdge = window.innerHeight - MARGINS;}let e;function onMove(ee) {calc(ee);e = ee;redraw = true;}function animate() {requestAnimationFrame(animate);if (!redraw) return;redraw = false;if (clicked && clicked.isResizing) {if (clicked.onRightEdge) pane.style.width = Math.max(x, minWidth) + 'px';if (clicked.onBottomEdge) pane.style.height = Math.max(y, minHeight) + 'px';if (clicked.onLeftEdge) {var currentWidth = Math.max(clicked.cx - e.clientX + clicked.w, minWidth);if (currentWidth > minWidth) {pane.style.width = currentWidth + 'px';pane.style.left = e.clientX + 'px';}}if (clicked.onTopEdge) {var currentHeight = Math.max(clicked.cy - e.clientY + clicked.h, minHeight);if (currentHeight > minHeight) {pane.style.height = currentHeight + 'px';pane.style.top = e.clientY + 'px';}}hintHide();return;}if (clicked && clicked.isMoving) {if (b.top < FULLSCREEN_MARGINS || b.left < FULLSCREEN_MARGINS || b.right > window.innerWidth - FULLSCREEN_MARGINS || b.bottom > window.innerHeight - FULLSCREEN_MARGINS) {// hintFull();setBounds(ghostpane, 0, 0, window.innerWidth, window.innerHeight);ghostpane.style.opacity = 0.2;} else if (b.top < MARGINS) {// hintTop();setBounds(ghostpane, 0, 0, window.innerWidth, window.innerHeight / 2);ghostpane.style.opacity = 0.2;} else if (b.left < MARGINS) {// hintLeft();setBounds(ghostpane, 0, 0, window.innerWidth / 2, window.innerHeight);ghostpane.style.opacity = 0.2;} else if (b.right > rightScreenEdge) {// hintRight();setBounds(ghostpane, window.innerWidth / 2, 0, window.innerWidth / 2, window.innerHeight);ghostpane.style.opacity = 0.2;} else if (b.bottom > bottomScreenEdge) {// hintBottom();setBounds(ghostpane, 0, window.innerHeight / 2, window.innerWidth, window.innerWidth / 2);ghostpane.style.opacity = 0.2;} else {hintHide();}if (preSnapped) {setBounds(pane,e.clientX - preSnapped.width / 2,e.clientY - Math.min(clicked.y, preSnapped.height),preSnapped.width,preSnapped.height);return;}// movingpane.style.top = (e.clientY - clicked.y) + 'px';pane.style.left = (e.clientX - clicked.x) + 'px';return;}// This code executes when mouse moves without clicking// style cursorif (onRightEdge && onBottomEdge || onLeftEdge && onTopEdge) {pane.style.cursor = 'nwse-resize';} else if (onRightEdge && onTopEdge || onBottomEdge && onLeftEdge) {pane.style.cursor = 'nesw-resize';} else if (onRightEdge || onLeftEdge) {pane.style.cursor = 'ew-resize';} else if (onBottomEdge || onTopEdge) {pane.style.cursor = 'ns-resize';} else if (canMove()) {pane.style.cursor = 'move';} else {pane.style.cursor = 'default';}}animate();function onUp(e) {calc(e);if (clicked && clicked.isMoving) {// Snapvar snapped = {width: b.width,height: b.height};if (b.top < FULLSCREEN_MARGINS || b.left < FULLSCREEN_MARGINS || b.right > window.innerWidth - FULLSCREEN_MARGINS || b.bottom > window.innerHeight - FULLSCREEN_MARGINS) {// hintFull();setBounds(pane, 0, 0, window.innerWidth, window.innerHeight);preSnapped = snapped;} else if (b.top < MARGINS) {// hintTop();setBounds(pane, 0, 0, window.innerWidth, window.innerHeight / 2);preSnapped = snapped;} else if (b.left < MARGINS) {// hintLeft();setBounds(pane, 0, 0, window.innerWidth / 2, window.innerHeight);preSnapped = snapped;} else if (b.right > rightScreenEdge) {// hintRight();setBounds(pane, window.innerWidth / 2, 0, window.innerWidth / 2, window.innerHeight);preSnapped = snapped;} else if (b.bottom > bottomScreenEdge) {// hintBottom();setBounds(pane, 0, window.innerHeight / 2, window.innerWidth, window.innerWidth / 2);preSnapped = snapped;} else {preSnapped = null;}hintHide();}clicked = null;}
</script>
</body>
</html>

效果展示:
起始状态
吸附效果:
吸附效果

结语

不得不说css和js用的好的话是可以实现很多好玩的功能的,只是我自己对这俩用的还没那么精通。
看到这个好玩的代码就赶紧记录下来,希望能帮助到需要的人吧。

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

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

相关文章

Google禁止自动更新

前言&#xff1a; 为了使用selenium&#xff0c;必须要禁止google自动更新&#xff0c;要不然辛苦下的驱动&#xff0c;随着更新还得再下一遍。 解决&#xff1a; 1.打开服务 2.禁用google更新服务 然后就可以了

单片机学习12-串口通信

目录 串口通信实验 通信的基本概念 串行通信与并行通信 异步通信与同步通信 单工、半双工与全双工通信 通信速率&#xff08;比特率&#xff09; 单片机串口介绍 串口通信简介 串口相关寄存器 串口工作方式 方式 0 方式 1 方式 2 和方式 3 串口的使用方法 硬件设计…

vtk创建x,y,z轴

创建三维空间中的xyz轴 引言示例开发环境示例代码运行结果总结 引言 本文的示例实际上是vtk官网中的示例&#xff0c;只是稍做了一点改动。 示例 开发环境 使用QtCreator4.11.2来开发&#xff0c;基于Qt5.14.2。使用的vtk9.2。创建空项目。 示例代码 由于是空项目&#x…

开源大型语言模型(llm)总结

大型语言模型&#xff08;LLM&#xff09;是人工智能领域中的一个重要研究方向&#xff0c;在ChatGPT之后&#xff0c;它经历了快速的发展。这些发展主要涉及以下几个方面&#xff1a; 模型规模的增长&#xff1a;LLM的规模越来越大&#xff0c;参数数量显著增加。这种扩展使得…

抖音seo矩阵系统源码|需求文档编译说明(一)

抖音seo矩阵系统文章目录技术囊括 ①产品原型 ②需求文档 ③产品流程图 ④部署方式说明 ⑤完整源码 ⑥源码编译方式说明 ⑦三方框架和SDK使用情况说明和代码位置 ⑧平台操作文档 ⑨程序架构文档 短视频矩阵系统源码开发锦囊囊括前言一、短视频账号矩阵系统开发者必备能力语言&…

计算机视觉 + Self-Supervised Learning 五种算法原理解析

计算机视觉领域下自监督学习方法原理 导语为什么在计算机视觉领域中进行自我监督学习&#xff1f; 自监督学习方法Generative methodsBEiT 架构 Predictive methodsContrastive methodsBootstraping methodsSimply Extra Regularization methods 导语 自监督学习是一种机器学习…

【React】React Hooks解析

React Hooks解析 React 16.8 认识和体验Hooks 为什么需要Hook? Hook是 React 16.8 的新增特性&#xff0c;它可以让我们在不编写class的情况下使用state以及其他的React特性&#xff08;比如生命周期&#xff09; 我们先来思考一下class组件相对于函数式组件有什么优势&…

期末复习【计算机网络】

期末复习【计算机网络】 前言推荐期末复习如何快速阅读电子书重点第1章 概述1.6 计算机网络的性能1.6.2 计算机网络的性能指标√ 1.7 计算机网络体系结构1.7.3 具有五层协议的体系结构√ 第2章 物理层2.3 物理层下面的传输媒体 *2.4 信道复用技术2.4.1 频分复用、时分复用和统计…

node笔记_读写excel

文章目录 ⭐前言⭐安装依赖⭐读取excel&#x1f496; 按行读取&#x1f496; 按列读取 ⭐写入excel⭐结束 ⭐前言 大家好&#xff0c;我是yma16&#xff0c;本文分享关于node读取excel内容 往期文章 node_windows环境变量配置 node_npm发布包 linux_配置node node_nvm安装配置…

vivo 自研鲁班分布式 ID 服务实践

作者&#xff1a;vivo IT 平台团队- An Peng 本文介绍了什么是分布式ID&#xff0c;分布式ID的业务场景以及9种分布式ID的实现方式&#xff0c;同时基于vivo内部IT的业务场景&#xff0c;介绍了自研鲁班分布式ID服务的实践。 一、方案背景 1.1 分布式ID应用的场景 随着系统的…

【CV】EfficientNet相比resnet有哪些优点,什么是深度可分离卷积

目录 前言使用深度可分离卷积普通卷积的计算参数量深度可分离卷积分为两个步骤&#xff1a;深度卷积和逐点卷积 使用多个缩放因子使用 Swish 激活函数 前言 高效的神经网络主要通过&#xff1a;1. 减少参数数量&#xff1b;2. 量化参数&#xff0c;减少每个参数占用内存 目前的…

【2023年江西省研究生数学建模竞赛】题目三 植物的多样性 建模方案及参考文献

代码与结果如下&#xff1a;完整文档见文末 相关思路请点击这里到原文章查看 2023年江西省研究生数模竞赛题目三&#xff1a;植物的多样性 植物作为食物链中的生产者&#xff0c;通过光合作用吸收二氧化碳&#xff0c;制造氧气&#xff0c;同时为其他生物提供食物和栖息地&a…