当前位置: 首页 > news >正文

记录--手摸手带你撸一个拖拽效果

这里给大家分享我在网上总结出来的一些知识,希望对大家有所帮助

前言

最近看见一个拖拽效果的视频(抖音:艾恩小灰灰),看好多人评论说跟着敲也没效果,还有就是作者也不回复大家提出的一些疑问,本着知其然必要知其所以然的心理,我把实现效果研究了一遍,并且了解了其实现原理,这里给大家复盘其原理,学到就是赚到

准备

这里我们要用到字体图标,所以我们从iconfont阿里图标库直接引入

  • 找到需要的图标,添加进项目
  • 找到图标所在的项目,点击查看链接
  • 复制地址,或者点击地址复制跳转后地址链接

<link rel="stylesheet" href="https://at.alicdn.com/t/c/font_2579455_c6xlnvkj0j.cssspm=a313x.7781069.1998910419.53&file=font_2579455_c6xlnvkj0j.css">

创建所需要结构

把我们需要结构先写出来

  • draggable:让盒子可以进行拖拽
  • style="--color:#e63e31"--color让盒子背景色根据--color显示(与下方css样式相联系)
 <div class="list"><div class="list-item" draggable="true" style="--color:#e63e31"><i class="iconfont icon-shuangyuzuo constellation"></i><span class="list-item-title">双鱼座</span></div><div class="list-item" draggable="true" style="--color:#70d265"><i class="iconfont icon-shuipingzuo constellation"></i><span class="list-item-title">水平座</span></div><div class="list-item" draggable="true" style="--color:#f0e941"><i class="iconfont icon-mojiezuo constellation"></i><span class="list-item-title">摩羯座</span></div><div class="list-item" draggable="true" style="--color:#da8218"><i class="iconfont icon-chunvzuo constellation"></i><span class="list-item-title">处女座</span></div><div class="list-item" draggable="true" style="--color:#7ff0ec"><i class="iconfont icon-shizizuo constellation"></i><span class="list-item-title">狮子座</span></div></div>

编写样式

这里直接采用flex对盒子进行排版布局

  • background-color: var(--color);var(--color)是或者自定义属性的颜色
body{background-color: #000;
}
.list{width: 300px;height: 360px;/* padding: 20px 0; */margin: 100px auto 0;display: flex;flex-direction: column;justify-content: space-around;
}
.list-item{width: 100%;display: flex;align-items: center;padding: 0 16px;border-radius: 10px;/* margin-bottom: 20px; */
background-color: var(--color);
}
.constellation{line-height: 2.5em;font-size: 20px;color: #fff;
}
.list-item-img{width: 30px;height: 30px;
}
.list-item-title{margin-left: 20px;color: #fff;
}
// 移动动画class
.list-item.moving{
background-color: transparent;
border: 2px dashed #ccc;
}

js编写拖拽效果

首先获取需要用到的元素

// 获取整个list
const list = document.querySelector('.list')
// 获取每一个盒子
const item = document.querySelectorAll('.list-item')

开始拖动的时候需要加上移动的类,并且设置移动效果

// 开始拖动list.ondragstart = e => {source_node = e.targetrecode(item)setTimeout(() => {// 拖拽时样式e.target.classList.add('moving')}, 0)// 设置拖动效果e.dataTransfer.effectAllowed = 'move'}

拖拽中需要判断是从上往下还是从下往上,根据拖拽元素和放入元素的索引进行比对,从而对拖拽元素进行插入节点操作

注意: 在码上掘金从上往下的时候会出现bug,在浏览器不会,我个人觉得应该是是码上掘金的问题

 // 拖拽放入有效目标触发list.ondragenter = e => {e.preventDefault()console.log(e.target.id, list)if (e.target === list || e.target === source_node) {return false}const childer = Array.from(list.children)const sourceIndex = childer.indexOf(source_node)const targetIndex = childer.indexOf(e.target)// console.log(sourceIndex, targetIndex)if (sourceIndex < targetIndex) {// 从下往上拖动list.insertBefore(source_node, e.target.nextElementSibling)} else {// 从上往下拖动list.insertBefore(source_node, e.target)}// 动画效果函数last([e.target, source_node])}

拖拽结束后把拖拽时的样式移除

// 拖放结束list.ondragend = e => {e.target.classList.remove('moving')}

解释方法

这里有好多没有用过或者比较少用的方法,这里给大家解释一下

  • ondragstart:当用户开始拖动一个元素或文本选择时,会触发dragstart事件
  • ondragover:当元素或文本选择被拖到有效的拖放目标上时(每几百毫秒一次),就会触发拖放事件
  • ondragenter:当被拖动的元素或文本选择进入有效的拖放目标时,会触发dragenter事件
  • ondragend: 当拖放操作结束时(通过释放鼠标按钮或点击escape键)触发dragend事件。
  • e.dataTransfer.effectAllowed:用于设置拖放时的效果,常用参数有(move,link,copy)
  • getBoundingClientRect:返回元素对于视口的信息
  • requestAnimationFrame:重绘动画
  • cancelAnimationFrame:用于取消requestAnimationFrame调用请求

所有代码

HTML

<div class="list"><div class="list-item" draggable="true" style="--color:#e63e31" ><i class="iconfont icon-shuangyuzuo constellation"></i><span class="list-item-title">双鱼座</span></div><div class="list-item" draggable="true" style="--color:#70d265" ><i class="iconfont icon-shuipingzuo constellation"></i><span class="list-item-title">水平座</span></div><div class="list-item" draggable="true" style="--color:#f0e941" ><i class="iconfont icon-mojiezuo constellation"></i><span class="list-item-title">摩羯座</span></div><div class="list-item" draggable="true" style="--color:#da8218" ><i class="iconfont icon-chunvzuo constellation"></i><span class="list-item-title">处女座</span></div><div class="list-item" draggable="true" style="--color:#7ff0ec" ><i class="iconfont icon-shizizuo constellation"></i><span class="list-item-title">狮子座</span></div>
</div>

JS

// 操作dom元素const list = document.querySelector('.list')const item = document.querySelectorAll('.list-item')// 判断当前元素let source_node// 开始拖动list.ondragstart = e => {source_node = e.targetrecode(item)setTimeout(() => {e.target.classList.add('moving')}, 0)// 设置拖动效果e.dataTransfer.effectAllowed = 'move'}// 拖动在有效目标list.ondragover = e => {// 防止默认情况下允许删除e.preventDefault()}// 拖拽放入有效目标触发list.ondragenter = e => {e.preventDefault()console.log(e.target.id, list)if (e.target === list || e.target === source_node) {return false}const childer = Array.from(list.children)const sourceIndex = childer.indexOf(source_node)const targetIndex = childer.indexOf(e.target)console.log(sourceIndex, targetIndex)if (sourceIndex < targetIndex) {// 从下往上拖动//  console.log(source_node,e.target.nextElementSibling)//  if()list.insertBefore(source_node, e.target.nextElementSibling)} else {// 从上往下拖动console.log(e.target,e.target)if (!e.target==null||source_node==null) {return}list.insertBefore(source_node, e.target)}last([e.target, source_node])}// 拖放结束list.ondragend = e => {e.target.classList.remove('moving')}// 重新计算位置function recode(eleAll) {// getBoundingClientRect 返回元素对于视口信息for (let i = 0; i < eleAll.length; i++) {const {top,left} = eleAll[i].getBoundingClientRect()eleAll[i]._top = topeleAll[i]._left = left}}// 添加移动动画效果function last(eleAll) {for (let i = 0; i < eleAll.length; i++) {const dom = eleAll[i]const {top,left} = dom.getBoundingClientRect()if (dom._left) {dom.style.transform = `translate3d(${dom._left-left}px,${dom._top-top}px,0px)`// 重绘动画let rafId = requestAnimationFrame(function () {dom.style.transition = `transform 0.3s ease-out`dom.style.transform = 'none'})dom.addEventListener('transitionend', () => {dom.style.transition = 'none'// 取消requestAnimationFrame调用请求cancelAnimationFrame(rafId)})}}}

CSS

body{background-color: #000;
}
.list{width: 300px;height: 360px;/* padding: 20px 0; */margin: 100px auto 0;display: flex;flex-direction: column;justify-content: space-around;
}
.list-item{width: 100%;display: flex;align-items: center;padding: 0 16px;border-radius: 10px;/* margin-bottom: 20px; */
background-color: var(--color);
}
.constellation{line-height: 2.5em;font-size: 20px;color: #fff;
}
.list-item-img{width: 30px;height: 30px;
}
.list-item-title{margin-left: 20px;color: #fff;
}
.list-item.moving{
background-color: transparent;
border: 2px dashed #ccc;
}

本文转载于:

https://juejin.cn/post/7171269067729272868

如果对您有所帮助,欢迎您点个关注,我会定时更新技术文档,大家一起讨论学习,一起进步。

 

相关文章:

记录--手摸手带你撸一个拖拽效果

这里给大家分享我在网上总结出来的一些知识&#xff0c;希望对大家有所帮助 前言 最近看见一个拖拽效果的视频(抖音&#xff1a;艾恩小灰灰)&#xff0c;看好多人评论说跟着敲也没效果&#xff0c;还有就是作者也不回复大家提出的一些疑问&#xff0c;本着知其然必要知其所以然…...

python高德地图+58租房网站平台源码

wx供重浩&#xff1a;创享日记 对话框发送&#xff1a;python地图 免费获取完整源码源文件说明文档配置教程等 在PyCharm中运行《高德地图58租房》即可进入如图1所示的高德地图网页。 具体的操作步骤如下&#xff1a; &#xff08;1&#xff09;打开地图网页后&#xff0c;在编…...

ubuntu 将jupyter-lab保存为桌面快捷方式和favourites

ubuntu: 将jupyter-lab保存为桌面快捷方式和favourites desktop shortcut 建立一个新的desktop文件 cd ~/Desktop touch Jupyter-lab.desktop将文件修改成如下&#xff1a; [Desktop Entry] Version1.0 NameJupyterlab CommentBack up your data with one click Exec/home/cjb/…...

Java 类和对象简介

类是对象的抽象&#xff0c;是一组具有相同特性&#xff08;属性&#xff0c;事物的状态信息&#xff09;和行为&#xff08;事物能做什么&#xff09;的事物的集合&#xff0c;可以看做一类事物的模板。 对象是类的实例化&#xff0c;是具体的事物。 比如&#xff1a;人类和…...

时间复杂度的计算

个人主页&#xff1a;平行线也会相交 欢迎 点赞&#x1f44d; 收藏✨ 留言✉ 加关注&#x1f493;本文由 平行线也会相交 原创 收录于专栏【数据结构初阶&#xff08;C实现&#xff09;】 文章目录123456789时间复杂度&#xff08;就是一个函数&#xff09;的计算&#xff0c;…...

站内信箱系统的设计与实现

技术&#xff1a;Java、JSP等摘要&#xff1a;在经济全球化和信息技术成为发展迅速的今时今日&#xff0c;人们通过电子邮件收发进行信息传递已经成为主流。随着互联网和网络办公的发展&#xff0c;电子邮件正在被广泛应用在人们的日常生活中。跟据调查研究统计&#xff0c;在全…...

systemV共享内存

systemV共享内存 共享内存区是最快的IPC形式。共享内存的大小一般是4KB的整数倍&#xff0c;因为系统分配共享内存是以4KB为单位的&#xff08;Page&#xff09;&#xff01;4KB也是划分内存块的基本单位。 之前学的管道&#xff0c;是通过文件系统来实现让不同的进程看到同一…...

Python基础之if逻辑判断

在学习if语句之前&#xff0c;我们先学习一种数据类型&#xff0c;布尔类型&#xff08;bool&#xff09;&#xff0c;在if语句中&#xff0c;我们需要通过判断条件是否为真或者假&#xff0c;才进入下面的语句块执行。 一、布尔类型&#xff08;bool&#xff09; 布尔类型&a…...

实现pdf文件预览

前言 工作上接到的一个任务&#xff0c;实现pdf的在线预览&#xff0c;其实uniapp中已经有对应的api&#xff1a;uni.openDocument(OBJECT)&#xff08;新开页面打开文档&#xff0c;支持格式&#xff1a;doc, xls, ppt, pdf, docx, xlsx, pptx。&#xff09;**实现了相关功能…...

【java】alibaba Fastjson --全解史上最快的JSON解析库

文章目录前序Fastjson 简介Fastjson 的优点速度快使用广泛测试完备使用简单功能完备下载和使用将 Java 对象转换为 JSON 格式JSONField创建 JSON 对象JSON 字符串转换为 Java 对象使用 ContextValueFilter 配置 JSON 转换使用 NameFilter 和 SerializeConfigFastjson 处理日期F…...

绝对零基础的C语言科班作业(期末模拟考试)(十道编程题)

编程题&#xff08;共10题&#xff1b; 共100.0分&#xff09;&#xff08;给猛男妙妙屋更一篇模拟考试&#xff09;模拟1&#xff08;输出m到n的素数&#xff09;从键盘输入两个整数[m,n], 输出m和n之间的所有素数。 输入样例&#xff1a;3&#xff0c;20输出样例&#xff1a;…...

按位与为零的三元组[掩码+异或的作用]

掩码异或的作用前言一、按位与为零的三元组二、统计分组1、map统计分组2、异或掩码总结参考资料前言 当a b 0时&#xff0c;我们能够很清楚的知道b是个什么值&#xff0c;b 0 - a -a&#xff0c;如果当a & b 0时&#xff0c;我们能够很清楚的知道b是什么值吗&#xf…...

C++基础篇(一)-- 简单入门

C 语言是在优化 C 语言的基础上为支持面向对象的程序设计而研制的一个通用目的的程序设计语言。在后来的持续研究中&#xff0c;C 增加了许多新概念&#xff0c;例如虚函数、重载、继承、标准模板库、异常处理、命名空间等。 C 语言的特点主要表现在两个方面&#xff1a;全面兼…...

前端整理 —— javascript 2

1. generator&#xff08;生成器&#xff09; 详细介绍 generator 介绍 generator 是 ES6 提供的一种异步编程解决方案&#xff0c;在语法上&#xff0c;可以把它理解为一个状态机&#xff0c;内部封装了多种状态。执行generator&#xff0c;会生成返回一个遍历器对象。返回的…...

Spring-注解注入

一、回顾XML注解 bean 配置 创建 bean public class Student { } 配置 xml bean <?xml version"1.0" encoding"UTF-8"?> <beans xmlns"http://www.springframework.org/schema/beans"xmlns:xsi"http://www.w3.org/2001/XMLSche…...

华为校招机试 - 攻城战(Java JS Python)

目录 题目描述 输入描述 输出描述 用例 题目解析 JavaScript算法源码 Java算法源码...

Docker入门

Docker一、何为DockerDocker是一个开源的应用容器引擎&#xff0c;基于GO语言并遵循从Apache2.0协议开源。Docker可以让开发者打包他们的应用以及依赖包到一个轻量级、可移植的容器中&#xff0c;然后在发布到任何流行的Linux机器上&#xff0c;也可以实现虚拟化。容器是完全使…...

时间序列分析 | CNN-LSTM卷积长短期记忆神经网络时间序列预测(Matlab完整程序)

时间序列分析 | CNN-LSTM卷积长短期记忆神经网络时间序列预测(Matlab完整程序) 目录 时间序列分析 | CNN-LSTM卷积长短期记忆神经网络时间序列预测(Matlab完整程序)预测结果模型输出基本介绍完整程序参考资料预测结果 模型输出 layers = 具有以下层的 151 Layer 数组:...

【蒸滴C】C语言结构体入门?看这一篇就够了

目录 一、结构体的定义 二、结构的声明 例子 三、 结构成员的类型 结构体变量的定义和初始化 1.声明类型的同时定义变量p1 2.直接定义结构体变量p2 3.初始化&#xff1a;定义变量的同时赋初值。 4.结构体变量的定义放在结构体的声明之后 5.结构体嵌套初始化 6.结构体…...

第十三届蓝桥杯

这里写目录标题一、刷题统计&#xff08;ceil函数返回的是等值于某最小整数的浮点值&#xff0c;不强制转换回int就wa&#xff0c;没错就连和int整数相加都wa二、修剪灌木&#xff08;主要应看清楚会调转方向三、统计子矩阵&#xff08;前缀和滑动窗口⭐&#xff09;四、[积木画…...

python打卡day49

知识点回顾&#xff1a; 通道注意力模块复习空间注意力模块CBAM的定义 作业&#xff1a;尝试对今天的模型检查参数数目&#xff0c;并用tensorboard查看训练过程 import torch import torch.nn as nn# 定义通道注意力 class ChannelAttention(nn.Module):def __init__(self,…...

ubuntu搭建nfs服务centos挂载访问

在Ubuntu上设置NFS服务器 在Ubuntu上&#xff0c;你可以使用apt包管理器来安装NFS服务器。打开终端并运行&#xff1a; sudo apt update sudo apt install nfs-kernel-server创建共享目录 创建一个目录用于共享&#xff0c;例如/shared&#xff1a; sudo mkdir /shared sud…...

MMaDA: Multimodal Large Diffusion Language Models

CODE &#xff1a; https://github.com/Gen-Verse/MMaDA Abstract 我们介绍了一种新型的多模态扩散基础模型MMaDA&#xff0c;它被设计用于在文本推理、多模态理解和文本到图像生成等不同领域实现卓越的性能。该方法的特点是三个关键创新:(i) MMaDA采用统一的扩散架构&#xf…...

Frozen-Flask :将 Flask 应用“冻结”为静态文件

Frozen-Flask 是一个用于将 Flask 应用“冻结”为静态文件的 Python 扩展。它的核心用途是&#xff1a;将一个 Flask Web 应用生成成纯静态 HTML 文件&#xff0c;从而可以部署到静态网站托管服务上&#xff0c;如 GitHub Pages、Netlify 或任何支持静态文件的网站服务器。 &am…...

【OSG学习笔记】Day 16: 骨骼动画与蒙皮(osgAnimation)

骨骼动画基础 骨骼动画是 3D 计算机图形中常用的技术&#xff0c;它通过以下两个主要组件实现角色动画。 骨骼系统 (Skeleton)&#xff1a;由层级结构的骨头组成&#xff0c;类似于人体骨骼蒙皮 (Mesh Skinning)&#xff1a;将模型网格顶点绑定到骨骼上&#xff0c;使骨骼移动…...

3403. 从盒子中找出字典序最大的字符串 I

3403. 从盒子中找出字典序最大的字符串 I 题目链接&#xff1a;3403. 从盒子中找出字典序最大的字符串 I 代码如下&#xff1a; class Solution { public:string answerString(string word, int numFriends) {if (numFriends 1) {return word;}string res;for (int i 0;i &…...

Android 之 kotlin 语言学习笔记三(Kotlin-Java 互操作)

参考官方文档&#xff1a;https://developer.android.google.cn/kotlin/interop?hlzh-cn 一、Java&#xff08;供 Kotlin 使用&#xff09; 1、不得使用硬关键字 不要使用 Kotlin 的任何硬关键字作为方法的名称 或字段。允许使用 Kotlin 的软关键字、修饰符关键字和特殊标识…...

AI书签管理工具开发全记录(十九):嵌入资源处理

1.前言 &#x1f4dd; 在上一篇文章中&#xff0c;我们完成了书签的导入导出功能。本篇文章我们研究如何处理嵌入资源&#xff0c;方便后续将资源打包到一个可执行文件中。 2.embed介绍 &#x1f3af; Go 1.16 引入了革命性的 embed 包&#xff0c;彻底改变了静态资源管理的…...

SiFli 52把Imagie图片,Font字体资源放在指定位置,编译成指定img.bin和font.bin的问题

分区配置 (ptab.json) img 属性介绍&#xff1a; img 属性指定分区存放的 image 名称&#xff0c;指定的 image 名称必须是当前工程生成的 binary 。 如果 binary 有多个文件&#xff0c;则以 proj_name:binary_name 格式指定文件名&#xff0c; proj_name 为工程 名&…...

NXP S32K146 T-Box 携手 SD NAND(贴片式TF卡):驱动汽车智能革新的黄金组合

在汽车智能化的汹涌浪潮中&#xff0c;车辆不再仅仅是传统的交通工具&#xff0c;而是逐步演变为高度智能的移动终端。这一转变的核心支撑&#xff0c;来自于车内关键技术的深度融合与协同创新。车载远程信息处理盒&#xff08;T-Box&#xff09;方案&#xff1a;NXP S32K146 与…...