如何使元素支持拖動(dòng)實(shí)現(xiàn)組件的自由拖動(dòng)的核心就是 html5 中新添" />

国产成人精品无码青草_亚洲国产美女精品久久久久∴_欧美人与鲁交大毛片免费_国产果冻豆传媒麻婆精东

15158846557 在線咨詢 在線咨詢
15158846557 在線咨詢
所在位置: 首頁(yè) > 營(yíng)銷資訊 > 網(wǎng)站運(yùn)營(yíng) > web前端---拖拽牛逼,輕松實(shí)現(xiàn)一個(gè)自由拖拽的組件

web前端---拖拽牛逼,輕松實(shí)現(xiàn)一個(gè)自由拖拽的組件

時(shí)間:2023-07-02 23:24:01 | 來(lái)源:網(wǎng)站運(yùn)營(yíng)

時(shí)間:2023-07-02 23:24:01 來(lái)源:網(wǎng)站運(yùn)營(yíng)

web前端---拖拽牛逼,輕松實(shí)現(xiàn)一個(gè)自由拖拽的組件:

前言

那么我們?cè)谶@篇文章中來(lái)分享一下自由布局拖動(dòng)的實(shí)現(xiàn)原理,實(shí)現(xiàn)一個(gè)設(shè)計(jì)器組件自由拖動(dòng)的最簡(jiǎn)demo。

如何使元素支持拖動(dòng)

實(shí)現(xiàn)組件的自由拖動(dòng)的核心就是 html5 中新添加的全局屬性 draggable 屬性,該屬性規(guī)定了元素是否可進(jìn)行拖動(dòng)。屬性值如下所示:

當(dāng)我們?cè)谠卦貥?biāo)簽中添加 draggable 屬性時(shí),該元素就可以進(jìn)行拖動(dòng)操作了。

<div draggable > 可拖動(dòng)的元素 </div>

拖動(dòng)事件

事件分類

元素可以進(jìn)行拖動(dòng)了,我們就可以通過(guò)元素的拖動(dòng)事件進(jìn)行拖動(dòng)開(kāi)始-結(jié)束的一些邏輯控制了,拖動(dòng)事件主要分為兩個(gè)類別,一類是拖動(dòng)元素可以觸發(fā)的:

另一類是,是當(dāng)拖拽元素到某個(gè)目標(biāo)元素時(shí),目標(biāo)元素會(huì)觸發(fā)的:

拖動(dòng)放置行為

在拖動(dòng)事件中,我們會(huì)獲取到拖動(dòng)的事件對(duì)象 (e),在拖動(dòng)對(duì)象中我們能獲取到一個(gè)重要的屬性 dataTransfer ,我們可以通過(guò) dataTransferdropEffect 屬性控制被拖動(dòng)的元素的放置行為,其值的說(shuō)明如下所示。

頁(yè)面設(shè)計(jì)器的實(shí)現(xiàn)

下面我們根據(jù)以上的知識(shí)點(diǎn)來(lái)實(shí)現(xiàn)一下頁(yè)面設(shè)計(jì)器組件拖動(dòng)的最簡(jiǎn)demo。首先我們定義一下組件列表和畫布區(qū)域。

<template> <div> <!-- 左側(cè)組件列表 --> <div class="left"> <div class="left-item" v-for="item in list1" :key="item.code" draggable > {{ item.name }} </div> </div> <!-- 畫布區(qū)域 --> <div class="targetContent" ref="targetContent"> <div class="item" v-for="item in list2" :key="item.id" :ref="item.id" :style="{ top: `${item.top - 16}px`, left: `${item.left - 85}px`, 'z-index': `${item.zIndex}` }" > <template v-if="item.code === 'MyInput'"> <a-input></a-input> </template> </div> </div> </div></template>并將組件列表和畫布中的頁(yè)面分別通過(guò)list1,和list進(jìn)行遍歷渲染。

<script>import _ from "lodash";export default { data() { return { list1: [ { code: "MyInput", name: "輸入框", props: {} } ], list2: [], }; }}</script>下面我們來(lái)分析一下如何實(shí)現(xiàn)將組件列表中的組件拖動(dòng)到畫布中,上文中我們講到,拖動(dòng)的元素以及目標(biāo)元素可以設(shè)置一系列的事件,那么我們就可以在組件列表渲染時(shí),為每個(gè)組件設(shè)置一下 dragstart 事件,在該事件中我們需要做如下處理:

  1. 設(shè)置拖動(dòng)元素的放置行為為移動(dòng),即move。
  2. 組件在目標(biāo)元素經(jīng)過(guò)時(shí),必須要阻止默認(rèn)行為,否則不能觸發(fā)drop
  3. 設(shè)置組件離開(kāi)目標(biāo)元素時(shí)放置行為為不能拖放,即none。
  4. 拖動(dòng)元素在目標(biāo)元素松手時(shí)添加元素到畫布,即將組件元數(shù)據(jù)添加到list2中,元素所對(duì)應(yīng)的元數(shù)據(jù)記錄也了這個(gè)組件在畫面中的坐標(biāo)位置。
然后在dragend事件中取聽(tīng)以上動(dòng)作。

下面我們通過(guò)代碼的方式來(lái)實(shí)現(xiàn)以上過(guò)程。首先在組件列表進(jìn)行遍歷時(shí),添加組件的dragstartdragend事件。

@dragstart="e => dragstart(e, item)"@dragend="dragend"下面是這兩個(gè)事件的實(shí)現(xiàn)。

dragstart(e, item) { this.dragItem = item; // 設(shè)置元素的放置行為——移動(dòng) this.$refs.targetContent.addEventListener("dragenter", this.dragenter); // 在目標(biāo)元素經(jīng)過(guò) 必須要阻止默認(rèn)行為 否則不能觸發(fā)drop this.$refs.targetContent.addEventListener("dragover", this.dragover); // 離開(kāi)目標(biāo)元素時(shí)設(shè)置元素的放置行為——不能拖放 this.$refs.targetContent.addEventListener("dragleave", this.dragleave); // 拖動(dòng)元素在目標(biāo)元素松手時(shí)添加元素到畫布 this.$refs.targetContent.addEventListener("drop", this.drop);},dragend(e) { this.$refs.targetContent.removeEventListener("dragenter", this.dragenter); this.$refs.targetContent.removeEventListener("dragover", this.dragover); this.$refs.targetContent.removeEventListener("dragleave", this.dragleave); this.$refs.targetContent.removeEventListener("drop", this.drop);},dragenter(e) { e.dataTransfer.dropEffect = "move";},dragover(e) { e.preventDefault();},dragleave(e) { e.dataTransfer.dropEffect = "none";},drop(e) { const { code } = this.dragItem; this.list2.push({ top: e.offsetY, left: e.offsetX, zIndex: 1, code: code, id: Date.parse(new Date()) }); this.dragItem = null;}這樣,我們組件列表中的組件就可以拖動(dòng)到畫布中了。

那拖動(dòng)到畫布中的組件又是如何實(shí)現(xiàn)通過(guò)拖動(dòng)靈活的移動(dòng)位置的呢?同樣,我們可以將畫布中的組件添加mousedown事件,在事件中我們添加mousemove事件的監(jiān)聽(tīng),當(dāng)畫布中的組件進(jìn)行移動(dòng)時(shí),我們實(shí)時(shí)的將該被移動(dòng)元素所對(duì)應(yīng)的元數(shù)據(jù)坐標(biāo)進(jìn)行更新。下面是代碼的實(shí)現(xiàn)。

mousedown(e, item) { this.moveItem = item; document.addEventListener("mousemove", this.mousemove); document.addEventListener("mouseup", this.mouseup);},mousemove(e) { const _this = this; let { clientX, clientY } = e; const moveIdx = _.findIndex(this.list2, function(o) { return o.id === _this.moveItem.id; }); let newList2 = _.cloneDeep(this.list2); newList2[moveIdx].top = clientY; newList2[moveIdx].left = clientX; this.list2 = newList2;},mouseup(e) { document.removeEventListener("mousemove", this.mousemove); document.removeEventListener("mouseup", this.mouseup);}這樣畫布中的組件也就支持移動(dòng)啦。

后記

這篇文章中我們實(shí)現(xiàn)了頁(yè)面設(shè)計(jì)器組件自由布局的最簡(jiǎn)demo,讓大家理解自由拖動(dòng)的實(shí)現(xiàn)原理。至于里面還有一些細(xì)節(jié)的處理,大家可以根據(jù)自己的需要自行實(shí)現(xiàn)~對(duì)該系列文章感興趣的小伙伴來(lái)一波關(guān)注吧。我們會(huì)持續(xù)與大家分享與交流。

完整demo代碼已經(jīng)打包好了,有需要的小伙伴們可以來(lái)拿。

關(guān)鍵詞:自由,實(shí)現(xiàn)

74
73
25
news

版權(quán)所有? 億企邦 1997-2025 保留一切法律許可權(quán)利。

為了最佳展示效果,本站不支持IE9及以下版本的瀏覽器,建議您使用谷歌Chrome瀏覽器。 點(diǎn)擊下載Chrome瀏覽器
關(guān)閉