mousedown拖拽功能(vue3+ts)

因為項目有rem適配,使用第三方插件無法處理適配問題,所有只能自己寫拖拽功能了
拖拽一般都會想到按下,移動,放開,但是本人親測,就在div綁定一個按下事件就行了(在事件里面寫另外兩個事件),另外兩個綁上,會莫名其妙卡死,那種莫名其妙的問題

推薦幾個開發調試時使用的第三方拖動插件吧,雖然沒用上,但是他們是真的好vue-drag-resizevuedraggable,其中前者更輕量化,后者功能更全

主要功能:

效果圖
在這里插入圖片描述

界面:(就是大的父盒子包著幾個小盒子,盒子里面有圖片和文字)

        <div class="range" id="range" ref="range"><divclass="iconItem"v-for="(item, index) in pointList":key="index"@mousedown.stop.prevent.native="mousedown($event, item)":style="{left: item.dx + 'px',top: item.dy + 'px','z-index': item.zIndex,}"><!--@mousemove.stop.prevent.native="mousemove($event, item)"@mouseup.stop.prevent.native="mouseup($event, item)"--><imgdraggable="false":src="typeList[item.type].src":alt="typeList[item.type].name + item.EName"/><span>{{ typeList[item.type].name + item.EName }}</span></div></div>

邏輯

<script setup lang="ts">
import { ref, reactive, watch, computed, Ref } from "vue";
import { mapPunctuation } from "@/utils/youran";
let rem = ref(0.005208); // 10/1920  做好功能給上面的left top乘上去就行了 left: item.dx * rem + 'px'const range: Ref = ref(null);// 這里只是把存在文件里的base64圖片文件取出來,
let typeList = reactive([{type: 1,src: "",name: "球機-攝像頭",},{type: 2,src: "",name: "搶機-攝像頭",},{type: 3,src: "",name: "無源打卡設備",},{type: 4,src: "",name: "無源打卡設備",},{type: 5,src: "",name: "反向控制",},
]);typeList.forEach((item, index) => {item.src = mapPunctuation[index].src;
});let pointList = ref([{fId: "111",type: 1,EId: "",EName: "",dx: 0,dy: 0,zIndex: 2,},
]);// 鼠標事件
let downType = ref(false);
let disX = 0;
let disY = 0;
let odiv: any = null;
let mousedown = (e: any, item: any) => {downType.value = true;console.log("按下事件");odiv = e.target;disX = e.clientX - odiv.offsetLeft;disY = e.clientY - odiv.offsetTop;document.onmousemove = (e) => {console.log("移動事件");//計算元素位置(需要判斷臨界值)let left = e.clientX - disX;let top = e.clientY - disY;let { offsetHeight: pondModelHeight, offsetWidth: pondModelWidth } =range.value;let { offsetHeight: sonNodeHeight, offsetWidth: sonNodeWidth } = odiv;// 左上角(left)if (left < 0) {left = 0;}if (top < 0) {top = 0;}// 左下角if (top > pondModelHeight - sonNodeHeight) {top = pondModelHeight - sonNodeHeight;}if (left > pondModelWidth - sonNodeWidth) {left = pondModelWidth - sonNodeWidth;}item.dx = left;item.dy = top;item.zIndex = 999;};document.onmouseup = (e) => {console.log("放開事件");document.onmousemove = null;document.onmouseup = null;item.zIndex = 1;odiv = null;};
};
</script>

css:本來不該放出來,但是我在這里踩坑了,覺得其他人也會(img圖片有默認的拖拽,很難禁止,所以拿一個偽元素直接放在img上面,不給點img就不會踩坑)

      .range {width: 960px;height: 540px;background-color: pink;position: relative;.iconItem {position: absolute;left: 10px;top: 10px;z-index: 2;display: flex;align-items: center;cursor: move;user-select: none;width: 32px;height: 32px;background: yellow;img {width: 32px;height: 32px;}// 關鍵&::before {content: " ";width: 100%;height: 100%;position: absolute;top: 0;left: 0;z-index: 3;}&:hover {// span {//   display: block;// }}span {display: none;font-size: 12px;font-family: YouSheBiaoTiHei;color: red;}}}

完整代碼:(建議按照上面的一點點復制吧,有幾個文件是外部的base64圖片)

<template><div class="PastureMap"><div class="mapContent"><div class="mapBox"><div class="range" id="range" ref="range"><divclass="iconItem"v-for="(item, index) in pointList":key="index"@mousedown.stop.prevent.native="mousedown($event, item)":style="{left: item.dx + 'px',top: item.dy + 'px','z-index': item.zIndex,}"><!--@mousemove.stop.prevent.native="mousemove($event, item)"@mouseup.stop.prevent.native="mouseup($event, item)"--><imgdraggable="false":src="typeList[item.type].src":alt="typeList[item.type].name + item.EName"/><span>{{ typeList[item.type].name + item.EName }}</span></div></div></div><div class="operationPanel"><div class="addIConCard"><div class="title"><span>新增圖標</span></div><div class="box"><div class="bgImg"><div class="left"><span>背景圖:</span></div><div class="right"><button>選擇圖片</button><span>建議尺寸:960*540</span></div></div><div class="iconBtnForm"><div class="cell"><div class="left"><span>圈舍</span></div><div class="right"><input type="text" placeholder="請選擇圈舍" /></div></div><div class="cell"><div class="left"><span>設備編號</span></div><div class="right"><input type="text" placeholder="請輸入設備編號" /></div></div><div class="cell"><div class="left"><span>類型</span></div><div class="right"><input type="text" placeholder="請選擇類型" /></div></div></div><div class="addBtn"><button>新增</button></div></div></div><div class="iconList"><div class="item" v-for="(item, index) in pointList" :key="index"><div class="left"><span>類型</span></div><div class="right"><input type="text" placeholder="名稱" /></div><div class="del"><img src="" alt="del" /></div></div></div></div></div></div>
</template><script setup lang="ts">
import { ref, reactive, watch, computed, Ref } from "vue";
import { mapPunctuation } from "@/utils/youran";
let rem = ref(0.005208); // 10/1920const range: Ref = ref(null);
let typeList = reactive([{type: 1,src: "",name: "球機-攝像頭",},{type: 2,src: "",name: "搶機-攝像頭",},{type: 3,src: "",name: "無源打卡設備",},{type: 4,src: "",name: "無源打卡設備",},{type: 5,src: "",name: "反向控制",},
]);typeList.forEach((item, index) => {item.src = mapPunctuation[index].src;
});let pointList = ref([{fId: "111",type: 1,EId: "",EName: "",dx: 0,dy: 0,zIndex: 2,},
]);// 鼠標事件
let downType = ref(false);
let disX = 0;
let disY = 0;
let odiv: any = null;
let mousedown = (e: any, item: any) => {downType.value = true;console.log("按下事件");odiv = e.target;disX = e.clientX - odiv.offsetLeft;disY = e.clientY - odiv.offsetTop;document.onmousemove = (e) => {console.log("移動事件");//計算元素位置(需要判斷臨界值)let left = e.clientX - disX;let top = e.clientY - disY;let { offsetHeight: pondModelHeight, offsetWidth: pondModelWidth } =range.value;let { offsetHeight: sonNodeHeight, offsetWidth: sonNodeWidth } = odiv;// 左上角(left)if (left < 0) {left = 0;}if (top < 0) {top = 0;}// 左下角if (top > pondModelHeight - sonNodeHeight) {top = pondModelHeight - sonNodeHeight;}if (left > pondModelWidth - sonNodeWidth) {left = pondModelWidth - sonNodeWidth;}item.dx = left;item.dy = top;item.zIndex = 999;};document.onmouseup = (e) => {console.log("放開事件");document.onmousemove = null;document.onmouseup = null;item.zIndex = 1;odiv = null;};
};
</script><style lang="less" scoped>
.PastureMap {height: 100%;.mapContent {display: flex;height: 100%;.mapBox {flex: 1;height: 100%;.range {width: 960px;height: 540px;background-color: pink;position: relative;.iconItem {position: absolute;left: 10px;top: 10px;z-index: 2;display: flex;align-items: center;cursor: move;user-select: none;width: 32px;height: 32px;background: yellow;img {width: 32px;height: 32px;}&::before {content: " ";width: 100%;height: 100%;position: absolute;top: 0;left: 0;z-index: 3;}&:hover {// span {//   display: block;// }}span {display: none;font-size: 12px;font-family: YouSheBiaoTiHei;color: red;}}}}.operationPanel {width: 270px;.addIConCard {.title {span {}}.box {.bgImg {display: flex;align-items: center;.left {}.right {}}.iconBtnForm {.cell {display: flex;align-items: center;.left {span {}}.right {input {}}}}}}.iconList {.item {display: flex;align-items: center;position: relative;.left {span {}}.right {input {}}.del {position: absolute;top: 0;right: 0;}}}}}
}
</style>

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/news/34779.shtml
繁體地址,請注明出處:http://hk.pswp.cn/news/34779.shtml
英文地址,請注明出處:http://en.pswp.cn/news/34779.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

爬蟲ip池越大越好嗎?

作為一名資深的程序員&#xff0c;今天我要給大家分享一些關于爬蟲ip池的知識。關于ip代理池的問題&#xff0c;答案是肯定的&#xff0c;池子越大越好。下面跟我一起來盤點一下ip池大的好處吧&#xff01; 1、提高穩定性 爬蟲ip池越大&#xff0c;意味著擁有更多可用的爬蟲ip…

「C/C++」C/C++搭建程序框架

?博客主頁何曾參靜謐的博客&#x1f4cc;文章專欄「C/C」C/C程序設計&#x1f4da;全部專欄「UG/NX」NX二次開發「UG/NX」BlockUI集合「VS」Visual Studio「QT」QT5程序設計「C/C」C/C程序設計「Win」Windows程序設計「DSA」數據結構與算法「File」數據文件格式 目錄 1. 分離職…

Flume原理剖析

一、介紹 Flume是一個高可用、高可靠&#xff0c;分布式的海量日志采集、聚合和傳輸的系統。Flume支持在日志系統中定制各類數據發送方&#xff0c;用于收集數據&#xff1b;同時&#xff0c;Flume提供對數據進行簡單處理&#xff0c;并寫到各種數據接受方&#xff08;可定制&…

使用阿里云服務器搭建Discuz論壇網站教程基于CentOS系統

阿里云百科分享使用阿里云服務器建站教程&#xff0c;本文是搭建Discuz論壇&#xff0c;Discuz!是一款通用的社區論壇軟件系統&#xff0c;它采用PHP和MySQL組合的基礎架構&#xff0c;為您提供高效的論壇解決方案。本文介紹如何在CentOS 7操作系統的ECS實例上搭建Discuz! X3.4…

Nginx 安裝與部署

文章和代碼已經歸檔至【Github倉庫&#xff1a;https://github.com/timerring/front-end-tutorial 】或者公眾號【AIShareLab】回復 nginx 也可獲取。 文章目錄 虛擬機安裝CentOS7.4Linux配置配置上網配置靜態ip Nginx的安裝版本區別備份克隆 安裝編譯安裝報錯解決 啟動Nginx防…

topo 成績排名

題目描述 每到考試后&#xff0c;學校都會發成績表給每個學生&#xff0c;但是很多同學更關心的是自己在班級里的排名&#xff0c;可惜排名信息并沒有公開。 小雯同學很想知道這次期末考試的全班排名情況&#xff0c;但是她的同學卻不愿意告訴她自己的分數&#xff0c;只告訴她…

分布式 - 消息隊列Kafka:Kafka生產者發送消息的方式

文章目錄 1. Kafka 生產者2. kafaka 命令行操作3. kafka 生產者發送消息流程4. Kafka 生產者的創建5. Kafka 生產者發送消息1. 發送即忘記2. 同步發送3. 異步發送 6. Kafka 消息對象 ProducerRecord 1. Kafka 生產者 不管是把Kafka作為消息隊列、消息總線還是數據存儲平臺&…

wpf控件上移下移,調整子集控件顯示順序

頁面代碼: <!-- 導出A2,自定義導出設置列,添加時間:2023-8-9 14:14:18,作者:whl; --><Window x:Class="WpfSnqkGasAnalysis.WindowGasExportA2"xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"xmlns:x="http:/…

git遠程倉庫的創建及使用

1.倉庫的概念&#xff1a; 1.1 本地倉庫&#xff1a; 了解遠程倉庫前我們先了解一下本地倉庫&#xff0c;本地倉庫開發人員在完成部分代碼的編寫之后&#xff0c;可以將這一部分的代碼做一個提交。這個提交完全就是一個新的版本提交&#xff0c;當然這個提交動作是在開發者的電…

CSS革命:用Sass/SCSS引領前端創新

目錄 前言SCSSSassSass 和 SCSS 的區別 前言 在現代的前端開發中&#xff0c;CSS已成為呈現網頁和應用程序樣式的核心。然而&#xff0c;原生的CSS語法在大型項目中可能變得混亂、冗長且難以維護。 為了解決這些問題&#xff0c;SCSS&#xff08;Sass CSS&#xff09;和Sass&am…

Java基礎篇--數組

目錄 聲明和初始化數組&#xff1a; 訪問和修改數組元素&#xff1a; 數組長度&#xff1a; 遍歷數組&#xff1a; 多維數組的遍歷&#xff1a; 數組的常見操作和方法&#xff1a; 拓展小知識&#xff1a; 數組是Java中的一種數據結構&#xff0c;用于存儲相同類型的多個…

B100-技能提升-線程池分布式鎖

目錄 線程池什么是線程池&#xff1f;為什么用線程池?線程池原理常見四種線程池和自定義線程池 線程池 什么是線程池&#xff1f; 池化技術 為什么用線程池? 1 由于設置最大線程數&#xff0c;防止線程過多而導致系統崩潰。 2 線程復用&#xff0c;不需要頻繁創建或銷毀…

包管理機制pip3

pip3 安裝pip3 安裝pip3 apt install python3-pip yum install python3-pip從倉庫出發的命令 查詢倉庫信息 // 獲取默認pip3源 pip3 config get global.index-url查詢所有軟件包 查詢已經安裝的所有軟件包 pip3 list從軟件包出發的命令 從軟件包名出發查詢其他信息 查詢…

230. 二叉搜索樹中第K小的元素

介紹 中序遍歷&#xff1a;左子樹 -> 中 -> 右子樹 二叉搜索樹&#xff1a;中序遍歷可以得到有序的序列 遞歸法 1.使用函數循環遞歸處理 2.使用一個數組來保存 k, 保證在個個遞歸函數中都能看到 看的變化&#xff1b;每訪問一個節點&#xff0c;這個數減一&#xff0c…

軟件測試基礎篇——Redis

Redis Redis數據庫的配置與連接 解壓redis數據庫的安裝包&#xff08;建議把解壓后的安裝包放到磁盤的根目錄&#xff0c;方便訪問操作&#xff09;打開【命令行窗口】&#xff1a;winR在命令行窗口&#xff0c;進入到redis安裝目錄中 ? 格式一&#xff1a;cd /d redis目錄…

Linux安裝Zookeeper

1、Zookeeper簡介 ZooKeeper是一個分布式的&#xff0c;開放源碼的分布式應用程序協調服務&#xff0c;是Google的Chubby一個開源的實現&#xff0c;是Hadoop和Hbase的重要組件。它是一個為分布式應用提供一致性服務的軟件&#xff0c;提供的功能包括&#xff1a;配置維護、域…

自然語言處理從入門到應用——LangChain:記憶(Memory)-[記憶的類型Ⅲ]

分類目錄&#xff1a;《自然語言處理從入門到應用》總目錄 對話令牌緩沖存儲器ConversationTokenBufferMemory ConversationTokenBufferMemory在內存中保留了最近的一些對話交互&#xff0c;并使用標記長度來確定何時刷新交互&#xff0c;而不是交互數量。 from langchain.me…

基于灰狼優化(GWO)、帝國競爭算法(ICA)和粒子群優化(PSO)對梯度下降法訓練的神經網絡的權值進行了改進(Matlab代碼實現)

&#x1f4a5;&#x1f4a5;&#x1f49e;&#x1f49e;歡迎來到本博客????&#x1f4a5;&#x1f4a5; &#x1f3c6;博主優勢&#xff1a;&#x1f31e;&#x1f31e;&#x1f31e;博客內容盡量做到思維縝密&#xff0c;邏輯清晰&#xff0c;為了方便讀者。 ??座右銘&a…

環保行業如何開發廢品回收微信小程序

廢品回收是近年來受到越來越多人關注的環保行動。為了推動廢品回收的普及和方便&#xff0c;我們可以利用微信小程序進行制作&#xff0c;方便人們隨時隨地參與廢品回收。 首先&#xff0c;我們需要注冊并登錄喬拓云賬號&#xff0c;并進入后臺。喬拓云是一個提供微信小程序制作…

數據結構(一):順序表詳解

在正式介紹順序表之前&#xff0c;我們有必要先了解一個名詞&#xff1a;線性表。 線性表&#xff1a; 線性表是&#xff0c;具有n個相同特性的數據元素的有限序列。常見的線性表&#xff1a;順序表、鏈表、棧、隊列、數組、字符串... 線性表在邏輯上是線性結構&#xff0c;但…