一、使用原生js实现拖拽

点击打开视频讲解更加详细

<html lang="en">
<head>
<meta charset="UTF-8" />
<title>Lazyload</title>
<style>
.drag {
background-color: skyblue;
position: absolute;
line-height: 100px;
text-align: center;
width: 100px;
height: 100px;
}
</style>
</head>
<body>
<!-- left和top要写在行内样式里面 -->
<div class="drag" style="left: 0; top: 0">按住拖动</div>
<script src="./jquery-3.6.0.min.js"></script>
<script>
// 获取DOM元素
let dragDiv = document.getElementsByClassName('drag')[0]
// 鼠标按下事件 处理程序
let putDown = function (event) {
dragDiv.style.cursor = 'pointer'
let offsetX = parseInt(dragDiv.style.left) // 获取当前的x轴距离
let offsetY = parseInt(dragDiv.style.top) // 获取当前的y轴距离
let innerX = event.clientX - offsetX // 获取鼠标在方块内的x轴距
let innerY = event.clientY - offsetY // 获取鼠标在方块内的y轴距
// 按住鼠标时为div添加一个border
dragDiv.style.borderStyle = 'solid'
dragDiv.style.borderColor = 'red'
dragDiv.style.borderWidth = '3px'
// 鼠标移动的时候不停的修改div的left和top值
document.onmousemove = function (event) {
dragDiv.style.left = event.clientX - innerX + 'px'
dragDiv.style.top = event.clientY - innerY + 'px'
// 边界判断
if (parseInt(dragDiv.style.left) <= 0) {
dragDiv.style.left = '0px'
}
if (parseInt(dragDiv.style.top) <= 0) {
dragDiv.style.top = '0px'
}
if (
parseInt(dragDiv.style.left) >=
window.innerWidth - parseInt(dragDiv.style.width)
) {
dragDiv.style.left =
window.innerWidth - parseInt(dragDiv.style.width) + 'px'
}
if (
parseInt(dragDiv.style.top) >=
window.innerHeight - parseInt(dragDiv.style.height)
) {
dragDiv.style.top =
window.innerHeight - parseInt(dragDiv.style.height) + 'px'
}
}
// 鼠标抬起时,清除绑定在文档上的mousemove和mouseup事件
// 否则鼠标抬起后还可以继续拖拽方块
document.onmouseup = function () {
document.onmousemove = null
document.onmouseup = null
// 清除border
dragDiv.style.borderStyle = ''
dragDiv.style.borderColor = ''
dragDiv.style.borderWidth = ''
}
}
// 绑定鼠标按下事件
dragDiv.addEventListener('mousedown', putDown, false)
</script>
</body>
</html>

二、VUe使用js实现拖拽穿梭框

<template>
<div>
<h3 style="text-align: center">拖拽穿梭框</h3>
<div id="home" @mousemove="mousemove($event)">
<div class="tree-select-content">
<span
class="select-content"
:id="'mouse' + index"
v-for="(item, index) in leftData"
:key="item.id"
@mousedown="mousedown(index, 1)"
@mouseup="mouseup(item, 1, index)"
>
<span class="select-text">{{ item.label }}</span>
<span class="select-text-X" @click="handerClickX(item, index, 1)"
>X</span
>
</span>
</div>
<div class="tree-select-content">
<span
class="select-content"
:id="'deleteMouse' + index"
v-for="(item, index) in rightData"
:key="item.id"
@mousedown="mousedown(index, 2)"
@mouseup="mouseup(item, 2, index)"
>
<span class="select-text">{{ item.label }}</span>
<span class="select-text-X" @click="handerClickX(item, index, 2)"
>X</span
>
</span>
</div>
</div>
</div>
</template> <script>
export default {
name: "home",
data() {
return {
leftData: [
{ label: "首页", id: 1 },
{ label: "咨询", id: 2 },
{ label: "生活", id: 3 },
{ label: "财富", id: 4 },
{ label: "我的", id: 5 },
],
rightData: [{ label: "世界", id: 6 }],
isMoveTrue: false,
isMove: false,
moveId: "",
};
},
mounted() {},
components: {},
methods: {
mousedown(index, val) {
this.isMoveTrue = true;
if (val == 1) {
this.moveId = "mouse" + index;
} else {
this.moveId = "deleteMouse" + index;
}
},
mousemove(event) {
if (this.isMoveTrue) {
this.isMove = true;
document.getElementById(this.moveId).style.position = "absolute";
document.getElementById(this.moveId).style.top = event.clientY + "px";
document.getElementById(this.moveId).style.left = event.clientX + "px";
document.getElementById(this.moveId).style.transform =
"translate(-50%,-50%)";
}
},
mouseup(item, val, index) {
if (!this.isMove) {
this.isMoveTrue = false;
this.moveId = "";
}
if (this.isMoveTrue && val == 2) {
this.$nextTick(() => {
this.rightData.splice(index, 1);
this.leftData.push(item);
});
} else if (this.isMoveTrue && val) {
this.leftData.splice(index, 1);
this.rightData.push(item);
}
document.getElementById(this.moveId).style.display = "none";
this.isMoveTrue = false;
this.isMove = false;
this.moveId = "";
},
handerClickX(item, index, val) {
if (val == 1) {
this.leftData.splice(index, 1);
this.rightData.push(item);
} else {
this.rightData.splice(index, 1);
this.leftData.push(item);
}
},
},
};
</script> <style scoped>
#home {
display: flex;
justify-content: space-around;
}
.tree-select-content {
width: 40%;
height: 300px;
background: #f9faff;
border: 1px solid #dee0ec;
border-radius: 4px;
display: flex;
flex-wrap: wrap;
align-content: baseline;
}
.select-content {
width: max-content;
height: 20px;
padding: 1.6%;
border: 1px solid #d6dbed;
margin: 2% 1% 0;
background: #ffffff;
box-shadow: 0 0 8px 0 rgba(72, 119, 236, 0.1);
border-radius: 4px;
}
.select-content:hover span {
color: #4877ec;
}
.select-content:hover {
cursor: pointer;
background: #f8faff;
border: 1px solid #3e75f4;
}
.select-text {
font-size: 15px;
color: #2e2f36;
text-align: center;
font-weight: 400;
}
.select-text-X {
font-size: 15px;
color: #4877ec;
letter-spacing: 0;
font-weight: 400;
margin-left: 12px;
cursor: pointer;
}
</style>

效果图:

三、Vue 拖拽组件 vuedraggable

vuedraggable 是标准的组件式封装,并且将可拖动元素放进了 transition-group 上面,过渡动画都比较好。

使用方式:

yarn add vuedraggable

import vuedraggable from 'vuedraggable';

在使用的时候,可以通过 v-model 来双向绑定本地 data,如果需要更新或者是触发父组件监听的事件,可以在 updated() 中去 emit。

案例:

<template>
<div>
<div>{{ drag ? "拖拽中" : "拖拽停止" }}</div>
<!--使用draggable组件-->
<draggable
v-model="myArray"
chosenClass="chosen"
forceFallback="true"
group="people"
animation="1000"
@start="onStart"
@end="onEnd"
>
<transition-group>
<div class="item" v-for="element in myArray" :key="element.id">
{{ element.name }}
</div>
</transition-group>
</draggable>
<div class="color-list">
<div
class="color-item"
v-for="color in colors"
v-dragging="{ item: color, list: colors, group: 'color' }"
:key="color.text"
>
{{ color.text }}
</div>
</div>
</div>
</template>
<style scoped>
/*被拖拽对象的样式*/
.item {
padding: 6px;
background-color: #fdfdfd;
border: solid 1px #eee;
margin-bottom: 10px;
cursor: move;
}
/*选中样式*/
.chosen {
border: solid 1px #3089dc !important;
}
</style>
<script>
//导入draggable组件
import draggable from "vuedraggable";
export default {
//注册draggable组件
components: {
draggable,
},
data() {
return {
drag: false,
//定义要被拖拽对象的数组
myArray: [
{ people: "cn", id: 10, name: "www.itxst.com" },
{ people: "cn", id: 20, name: "www.baidu.com" },
{ people: "cn", id: 30, name: "www.taobao.com" },
{ people: "us", id: 40, name: "www.yahoo.com" },
],
colors: [
{
text: "Aquamarine",
},
{
text: "Hotpink",
},
{
text: "Gold",
},
{
text: "Crimson",
},
{
text: "Blueviolet",
},
{
text: "Lightblue",
},
{
text: "Cornflowerblue",
},
{
text: "Skyblue",
},
{
text: "Burlywood",
},
],
};
},
methods: {
//开始拖拽事件
onStart() {
this.drag = true;
},
//拖拽结束事件
onEnd() {
this.drag = false;
},
},
};
</script>

四、Awe-dnd指令封装

vue-dragging 的 npm 包的名字是 awe-dnd ,并不是 vue-dragging,这个库的特点是封装了 v-dragging 全局指令,然后通过全局指令去数据绑定等。

相比及 vuedraggable 来说, awe-dnd 是没有双向绑定(这里没有双向绑定并不是很严谨,准确的来说没有暴露双向绑定的方式),因此提供了事件,在拖拽结束的时候用来更新列表(不需要手动更新列表,其实内部是实现了双向绑定的)或者是去触发父组件监听的事件。

安装依赖:

npm install awe-dnd --save
yarn add awe-and

main.js

import VueDND from 'awe-dnd'

Vue.use(VueDND)

案例:

<template>
<div>
<div class="color-list">
<div
class="color-item"
v-for="color in colors"
v-dragging="{ item: color, list: colors, group: 'color' }"
:key="color.text"
>
{{ color.text }}
</div>
</div>
</div>
</template>
<style scoped>
/*被拖拽对象的样式*/
.item {
padding: 6px;
background-color: #fdfdfd;
border: solid 1px #eee;
margin-bottom: 10px;
cursor: move;
}
/*选中样式*/
.chosen {
border: solid 1px #3089dc !important;
}
</style>
<script>
export default {
data() {
return {
drag: false,
colors: [
{
text: "Aquamarine",
},
{
text: "Hotpink",
},
{
text: "Gold",
},
{
text: "Crimson",
},
{
text: "Blueviolet",
},
{
text: "Lightblue",
},
{
text: "Cornflowerblue",
},
{
text: "Skyblue",
},
{
text: "Burlywood",
},
],
};
},
methods: {},
};
</script>

若对您有帮助,请点击跳转到B站一键三连哦!感谢支持!!!

Vue实现拖拽穿梭框功能四种方式的更多相关文章

  1. ASP.NET MVC之下拉框绑定四种方式(十)

    前言 上两节我们讲了文件上传的问题,关于这个上传的问题还未结束,我也在花时间做做分割大文件处理以及显示进度的问题,到时完成的话再发表,为了不耽误学习MVC其他内容的计划,我们今天开始好好讲讲关于MVC ...

  2. [HTML]HTML隐藏文本框的四种方式

    .<input type="hidden" value=""></input>对所有的文本框都起作用(隐藏域,多用于存数据) .< ...

  3. elementUI 弹出框添加可自定义拖拽和拉伸功能,并处理边界问题

    开发完后台管理系统的弹出框模块,被添加拖拽和拉伸功能,看了很多网上成熟的帖子引到项目里总有一点问题,下面是根据自己的需求实现的步骤: 首先在vue项目中创建一个js文件eg:dialog.js imp ...

  4. 基于Vue实现拖拽效果

    参考地址:基于Vue实现拖拽效果 参考链接中讲的比较详细,我只使用了其中自定义指令的方法.整体代码如下: <template> <!-- 卡片 --> <div clas ...

  5. Javascript实现鼠标框选元素后拖拽被框选的元素

    之前需要做一个框选元素后拖拽被框选中的元素功能,在网上找资料做了一些修改,基本达到了需要的效果,希望对也需要实现框选后拖拽元素功能的人有用. 页面加载后效果 框选后的内容可以拖拽,如下图: 代码下载

  6. 基于jquery-ui及bootstrap的可拖拽模态框

    可直接使用代码 <!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <t ...

  7. Vue2 实现时空穿梭框功能模块

    前言 这篇文章主要是分享一个时空穿梭框功能,也就是我们平时用的选择功能.勾选了的项就会进入到另一个框中. 时空穿梭框之旅 示例演示: 这个时空穿梭框实现了: 1.可以全选.反选 2.没有选中时,不可以 ...

  8. vue使用element Transfer 穿梭框实现ajax请求数据和自定义查询

    vue使用element Transfer 穿梭框实现ajax请求数据和自定义查询 基于element Transfer http://element-cn.eleme.io/#/zh-CN/comp ...

  9. Android 仿微信朋友圈发表图片拖拽和删除功能

    朋友圈实现原理 我们使用 Android Device Monitor 来分析朋友圈发布图片的界面实现原理.如果需要分析其他应用的界面实现也是采用这种方法哦. 打开 Android Device Mo ...

随机推荐

  1. Docker详解(上)

    Docker 学习 Docker概述 Docker安装 Docker命令 镜像命令 容器命令 操作命令 ... Docker镜像 容器数据卷 DockerFile Docker网络原理 IDEA整合D ...

  2. ETL工具 Flume (一)

    分布式日志采集系统Flume学习 一.Flume架构 1.1 Hadoop业务开发流程 1.2 Flume概述 flume是一个分布式.可靠.和高可用的海量日志采集.聚合和传输的系统. 支持在日志系统 ...

  3. 这样优化Spring Boot,启动速度快到飞起!

    微服务用到一时爽,没用好就呵呵啦,特别是对于服务拆分没有把控好业务边界.拆分粒度过大等问题,某些 Spring Boot 启动速度太慢了,可能你也会有这种体验,这里将探索一下关于 Spring Boo ...

  4. Codeforces Round #796 (Div. 2)(A~E题题解)

    文章目录 原题链接: A.Cirno's Perfect Bitmasks Classroom 思路 代码 B.Patchouli's Magical Talisman 思路 代码 C.Manipul ...

  5. 3.Android高仿网易云音乐-首页复杂发现界面布局和功能/RecyclerView复杂布局

    0.效果图 效果图依次为发现界面顶部,包含首页轮播图,水平滚动的按钮,推荐歌单:然后是发现界面推荐单曲,点击单曲就是直接进入播放界面:最后是全局播放控制条上点击播放列表按钮显示的播放列表弹窗. 1.整 ...

  6. javascript 原生class操作

    <script type="text/javascript"> function hasClass(elements, cName) { return elements ...

  7. 上穷碧落下凡尘:Win10系统下基于Docker配置Elasticsearch7配合Python3进行全文检索交互

    原文转载自「刘悦的技术博客」https://v3u.cn/a_id_166 基于文档式的全文检索引擎大家都不陌生,之前一篇文章:使用Redisearch实现的全文检索功能服务,曾经使用Rediseac ...

  8. 2021年5月15日海外 Meetup 演讲内容分享

    北京时间 2021 年 5 月 16 日 05:00-08:00 我们与Apache ShardingSphere 联合举办了第一场海外Meetup,感谢各位小伙伴的参与,让本次活动圆满结束. 同时我 ...

  9. DolphinScheduler 1.2.0 源码解析之 MasterServer

    这一篇主要讲解的是dolphinscheduler 1.2.0 的master部分的源码,从主类MasterServer开始,从启动到运行,master主要做了以下三件事情 Zookeeper 节点初 ...

  10. .net 温故知新:【7】IOC控制反转,DI依赖注入

    IOC控制反转 大部分应用程序都是这样编写的:编译时依赖关系顺着运行时执行的方向流动,从而生成一个直接依赖项关系图. 也就是说,如果类 A 调用类 B 的方法,类 B 调用 C 类的方法,则在编译时, ...