【JavaScript】列表拖拽升级,支持双击添加和时间轴左右拖动

article/2025/9/14 7:40:32

@TOC在这里插入图片描述

H5实现时间揍拖动


实现双击文件列表的项添加到时间揍的最后一条。
时间轴里可以左右拖动位置。
主要代码:

/*** 时间轴拖动结束* @param $event* @constructor*/
const lineDragEnd = ( $event ) => {console.log( '时间轴拖动结束' , $event )console.log('移动了',$event.pageX - moveStartPosition.value.x,$event.pageY-moveStartPosition.value.y)lineList.value[moveIndex].left+=$event.pageX - moveStartPosition.value.xmoveStartPosition.value.x = 0moveStartPosition.value.y = 0moveIndex = ''
}

计算拖动距离给项设置左边距实现
全部代码
index.vue

<template>{{ moveStartPosition }}<p>文件列表</p><div class="file-list"><div class="file" v-for="(file,index) in fileList"draggable="true"@dragstart="fileDragStart($event,file)"@dragend="fileDragEnd($event,file)"@dblclick="appendFile(file)":key="'file'+index">{{ file.name }}</div></div><div>时间轴{{ moveIn }}</div><div class="line-list" :class="{'line-in':lineIn}"@dragenter="lineDragEnter"@dragleave="lineDragLeave"@dragover="lineDragOver"@drop="lineDropFile"><transition-group name="list"><div class="line" v-for="(line,index) in lineList":key="'line'+line.key":style="style(line)":title="line.name"@dragstart="lineDragStart($event,index)"@dragend="lineDragEnd":draggable="lineDraggable"@dragenter="lineItemDragEnter($event,index)"@dragleave="lineItemDragLeave"@dragover="lineItemDragMove"@drop.stop="lineItemDropFile(index)">{{ line.name }}</div></transition-group></div><!--    隐藏对象--><div class="hidden"><div id="move" ref="moveBlock">{{ nowFile.name }}</div></div>
</template><script setup>
import { randColor } from '@/utils/color.js'
import { uuid } from '@/utils/key.js'
import { ref } from 'vue'
const fileList = ref( [{ name: '视频1.mp4' , type: 'video' , duration: 10 } ,{ name: '音频2.mp4' , type: 'audio' , duration: 60 } ,{ name: '视频3.mp4' , type: 'video' , duration: 70 } ,{ name: '音频4.mp4' , type: 'audio' , duration: 80 } ,
] )
const lineList = ref( [] )
const moveBlock = ref( null )
const nowFile = ref( { name: '' } )
const lineIn = ref( false )
const moveStartPosition = ref({x:0,y:0})
let dragType = 'create'
let moveIndex = ''
let moveIn = ''
const style = ( file ) => {return {background: file.color ,width: file.duration * 5 + 'px','margin-left':file.left + 'px'}
}const appendFile = (item)=> {console.log('双击添加',item)let color = randColor()let file = {key: uuid() ,name: item.name ,type: item.type ,duration: item.duration ,left:0,color: color}console.log( 'file' , file )lineList.value.push( file )
}/*** 文件列表拖拽开始* @param $event* @param file*/
const fileDragStart = ( $event , file ) => {console.log( '文件列表拖拽开始' , $event , file )dragType = 'create'nowFile.value = filelet width = nowFile.value.duration * 2moveBlock.value.style.width = (width > 270 ? 270 : width) + 'px'$event.dataTransfer.setDragImage( moveBlock.value , 0 , 0 )
}/*** 文件列表拖拽结束* @param $event* @param file*/
const fileDragEnd = ( $event , file ) => {console.log( '文件列表拖拽结束' , $event , file )lineIn.value = false
}/*** 时间轴进入* @param $event* @constructor*/
const lineDragEnter = ( $event ) => {console.log( '时间列表进入' , $event )$event.preventDefault(); //阻止默认事件lineIn.value = true
}
/*** 时间轴离开* @param $event* @param file* @constructor*/
const lineDragLeave = ( $event , file ) => {console.log( '时间列表离开' , $event )$event.preventDefault(); //阻止默认事件lineIn.value = false
}/*** 时间轴阻止默认* @param $event* @constructor*/
const lineDragOver = ( $event ) => {$event.preventDefault(); //阻止默认事件
}/*** 时间轴放入* @param $event*/
const lineDropFile = ( $event ) => {console.log( '时间列表放入' ,dragType, $event )// 放在空的地方if ( dragType === 'create' ) {let color = randColor()let file = {key: uuid() ,name: nowFile.value.name ,type: nowFile.value.type ,duration: nowFile.value.duration ,left:0,color: color}console.log( 'file' , file )lineList.value.push( file )}
}/*** 时间轴拖动开始* @param $event* @param index*/
const lineDragStart = ( $event , index ) => {console.log( '时间轴拖动开始' , $event )dragType = 'move'moveIndex = indexmoveStartPosition.value.x = $event.pageXmoveStartPosition.value.y = $event.pageY
}const lineItemDragMove = ($event) => {console.log("拖拽移动",$event)console.log('移动了',$event.pageX - moveStartPosition.value.x,$event.pageY-moveStartPosition.value.y)
}
/*** 时间轴拖动结束* @param $event* @constructor*/
const lineDragEnd = ( $event ) => {console.log( '时间轴拖动结束' , $event )console.log('移动了',$event.pageX - moveStartPosition.value.x,$event.pageY-moveStartPosition.value.y)lineList.value[moveIndex].left+=$event.pageX - moveStartPosition.value.xmoveStartPosition.value.x = 0moveStartPosition.value.y = 0moveIndex = ''
}/*** 时间轴内容进入* @param $event* @constructor*/
const lineItemDragEnter = ( $event,index ) => {console.log( '时间轴进入' , $event )$event.preventDefault(); //阻止默认事件moveIn = index
}
/*** 时间轴内容离开* @param $event* @constructor*/
const lineItemDragLeave = ( $event  ) => {console.log( '时间轴离开' , $event )$event.preventDefault(); //阻止默认事件moveIn = ''
}/*** 时间轴放入* @param index*/
const lineItemDropFile = ( index ) => {console.log( '时间轴放入' , index )// 放在某个轴上if ( dragType === 'create' ) {let color = randColor()let file = {key: uuid() ,name: nowFile.value.name ,type: nowFile.value.type ,left:0,duration: nowFile.value.duration ,color: color}console.log( 'file' , file )lineList.value.splice(index,0,file)}// 移动if ( dragType === 'move' ) {console.log( '移动' ,moveIndex,index)let list = lineList.valueif(moveIndex > index){const item = lineList.value[moveIndex]list.splice(moveIndex,1)list.splice(index,0,item)}else{const item = lineList.value[moveIndex]console.log('移动',item,list)list.splice(moveIndex,1)list.splice(index,0,item)console.log("移动到后面",list)}lineList.value = list}
}const lineDraggable = ref(true)</script><style lang="less" scoped>
.hidden {position: fixed;left: 0;top: -100px;#move {min-width: 20px;height: 20px;background: red;border: 1px solid #07b3c9;overflow: hidden;}
}.line-list {height: 200px;overflow-y: auto;.line {user-select: none;overflow: hidden;height: 20px;white-space: nowrap; /*不显示的地方用省略号...代替*/text-overflow: ellipsis; /* 支持 IE */.move{display: inline-block;cursor: move;}}
}.line-in {background: #999;
}.list-move, /* 对移动中的元素应用的过渡 */
.list-enter-active,
.list-leave-active {transition: all 0.5s ease;
}.list-enter-from,
.list-leave-to {opacity: 0;transform: translateX(30px);
}/* 确保将离开的元素从布局流中删除以便能够正确地计算移动的动画。 */
.list-leave-active {position: absolute;
}
</style>

http://chatgpt.dhexx.cn/article/4cjBro1q.shtml

相关文章

echarts拖拽echarts实现多条可拖动节点的折线图

<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <script src="js/echarts/echarts.js"></script> <title>在指定位置画多个点</title> <style> …

html拖拽页面特效,div+css实现网页模块或栏目拖动(即拖拽效果)

//为Number增加一个属性,判断当前数据类型是否是数字 Number.prototype.NaN0function(){return isNaN(this)?0:this;} //全局变量 var iMouseDownfalse; var dragObjectnull; //获得鼠标的偏移量(对象2-对象1) function getMouseOffset(target,ev) { evev||window.event; var …

RecyclerView实现Item可拖拽(拖动、删除)

RecyclerView实现Item可拖拽&#xff08;拖动、删除&#xff09; 话不多说&#xff0c;先附上效果图&#xff1a; ItemTouchHelper 这是一个RecyclerView的工具&#xff0c;提供了drag & swipe 的功能&#xff0c;可以帮助我们处理RecyclerView中的Item的拖拽和滑动事件…

原生drag拖拽后元素过大,挡住其他可拖动位置无法拖动问题

写一个蒙层&#xff0c;还未拖动前原始层在上面&#xff0c; 拖动那过程中&#xff08;dragover&#xff09;原始层在下面&#xff0c; 拖进目标元素后&#xff08;drop&#xff09;&#xff0c;此时蒙层在上面&#xff0c;根据drop的$event获取落在蒙层哪个div上&#xff0c…

html5播放器禁止拖拽功能实例(教学内容禁止拖动观看)

html5播放器禁止拖拽功能实例&#xff08;常用于场景&#xff1a;企业培训、在线教学内容禁止学员拖动视频进行观看&#xff09; 实例1&#xff1a;参数开启后&#xff0c;视频教学内容或视频课件将不允许拖动进度条。 <div id"player"></div> <scr…

html5播放器禁止拖拽、视频禁止拖动的实例

阿酷TONY / 2023-3-8 / 长沙 html5播放器禁止拖拽功能,常用于场景&#xff1a;企业培训、在线教学内容禁止学员拖动视频进行观看。 应用代码实例&#xff1a; <div id"player"></div> <script src"//player.polyv.net/script/player.js">…

WPF TreeView拖动排序拖拽排列

底部附有Demo示例。需要的朋友可以去下载参考 一、图示 先上图&#xff0c;不知为啥&#xff0c;GIF总看起来特别卡&#xff0c;实际却很流畅。 由于录制问题&#xff0c;GIF动画只会播放一次&#xff0c;需要重复观看的&#xff0c;请将网页关闭后重新打开再观看 WPF的资料…

js原生拖拽的两种方法

一.mousedown、mousemove和mouseup 拖着目标元素在页面任意位置 如果要设置物体拖拽&#xff0c;那么必须使用三个事件&#xff0c;并且这三个事件的使用顺序不能颠倒。 1.onmousedown&#xff1a;鼠标按下事件 2.onmousemove&#xff1a;鼠标移动事件 3.onmouseup&#xff…

前端原生拖拽(drag drop)的一点小总结

新工作中&#xff0c;第一个手生的功能&#xff0c;遇到了很多诡异的问题&#xff0c;今天终于解惑了。最终原因还是对代码没有透彻的了解&#xff0c;jquery的运用也不熟练导致的。稍稍的记录一下。 原始功能 对项目列表中的元素进行拖拽&#xff0c;拖拽到一定的位置&#xf…

Vue2 _ 实现拖拽功能

老项目重构&#xff0c;其中有一些拖拽功能&#xff0c;不过用的是两个开源 JS 拖拽文件实现的效果&#xff0c;版本太老了&#xff0c;所以需要换代了&#xff0c;然后就查阅了能够用 Vue 来简单快速实现拖拽的功能实现方法 &#xff1a; 目录 一、HTML 拖放 二、Vue.Dragg…

vue2 使用 Sortable 库进行拖拽操作

一、vue 项目使用 文档地址&#xff1a; https://www.itxst.com/sortablejs/neuinffi.html 1、安装依赖 npm i -S vuedraggable2、.vue 文件引入组件 import draggable from "vuedraggable"; components: { draggable },3、.使用 查看文档中的示例即可&#xff…

空指针、悬空指针、野指针

文章目录 前言一、指针&#xff1f;二、指针的应用场景三、 空指针四、 悬空指针五、 野指针正确用法 总结 前言 相信很多小伙伴对指针的使用都有一定的了解了。但更多的人可能对指针又爱又恨。这次我们谈点重要的&#xff0c;进一步加深对指针的理解 一、指针&#xff1f; 指…

【C语言】指针(野指针)

目录 1&#xff1a;什么是野指针&#xff1f; 2&#xff1a;如何规避野指针 1.1&#xff1a;指针变量的初始化 2.2&#xff1a;指针越界访问 3.3&#xff1a;指针指向的空间如果我们还回去的话&#xff0c;就把指针指针置为NULL 4.4&#xff1a;指针使用之前检查有效性…

C语言的野指针

1.野指针 指针变量中的值是非法的内存地址&#xff0c;进而形成野指针野指针不是NULL指针&#xff0c;是指向不可用内存地址的指针NULL指针并无危害&#xff0c;很好判断&#xff0c;也很好调试C语言中无法判断一个指针所保存的地址是否合法&#xff0c;合法的地址是通过变量或…

初识C语言---野指针

野指针概念&#xff1a; 野指针就是指针指向的位置是不可知的&#xff08;随机的、不正确的、没有明确限制的&#xff09;。 一、野指针成因 1、指针未初始化就使用 #include<stdio.h> int main() {int* p; *p 10; return 0; }此段代码中&#…

野指针(概念,产生原因,危害,避免方法)

思维导图: 1.野指针与垂悬指针的区别: 野指针:访问一个已销毁或者访问受限的内存区域的指针,野指针不能判断是否为NULL来避免 垂悬指针:指针正常初始化,曾指向一个对象,该对象被销毁了,但是指针未制空,那么就成了悬空指针。 2.概念 指针指向了一块随机的空间,不受…

野指针概念、定义、及如何规避野指针

野指针 野指针的概念&#xff1a; 野指针就是指针指向的位置不可知的。&#xff08;随机的、不正确的、没有明确限制的&#xff09; 野指针的三种情况 1、指针未定义 #include <stdio.h> int main() {int* p; //局部变量指针未初始化&#xff0c;默认就是随机值*p10;r…

使用 OKTA 作为 SAML IdP 为 FortiClient配置 SAML SSO 登录

描述 随着用于 FortiGate 和 FortiClient 6.4 的 FortiOS 6.4 的发布,现在可以创建SSL SSO 单点登录解决方案,该解决方案可以集成第三方 SAML SSO 身份提供商 (IdP) 并利用其 MFA 功能。 前置条件 FortiGate 运行 FortiOS 6.4.0 或更高版本FortiClient 6.4.0 或更高版本OK…

SAML 流程讲解

SAML&#xff08;Security Assert Mark Language&#xff09;常用来实现SSO。 本文主要梳理一下SAML的代码逻辑 术语讲解&#xff1a; IDP: Identity provider 在单点登陆中是指统一身份认证平台。 SP&#xff1a;Service Provider 在单点登陆中是指需要被认证的服务方。 A…

SAML单点登录-spring-security-saml 整合使用

本文链接&#xff1a;http://t.csdn.cn/BIGKc SAML单点登录-spring-security-saml客户端SP 使用spring-security-saml搭建SAML协议的客户端&#xff0c;该依赖是spring框架的官方库&#xff0c;配置方便、文档详细。提供了包括单点登录、单点登出、获取sq元数据文件等接口&…