時(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è)自由拖拽的組件:html5
中新添加的全局屬性 draggable
屬性,該屬性規(guī)定了元素是否可進(jìn)行拖動(dòng)。屬性值如下所示:draggable
屬性時(shí),該元素就可以進(jìn)行拖動(dòng)操作了。<div draggable > 可拖動(dòng)的元素 </div>
(e)
,在拖動(dòng)對(duì)象中我們能獲取到一個(gè)重要的屬性 dataTransfer
,我們可以通過(guò) dataTransfer
的 dropEffect
屬性控制被拖動(dòng)的元素的放置行為,其值的說(shuō)明如下所示。<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
事件,在該事件中我們需要做如下處理:移動(dòng)
,即move
。drop
。不能拖放
,即none
。list2
中,元素所對(duì)應(yīng)的元數(shù)據(jù)記錄也了這個(gè)組件在畫面中的坐標(biāo)位置。dragend
事件中取聽(tīng)以上動(dòng)作。dragstart
和dragend
事件。@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)到畫布中了。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)啦。來(lái)一波關(guān)注
吧。我們會(huì)持續(xù)與大家分享與交流。關(guān)鍵詞:自由,實(shí)現(xiàn)
客戶&案例
營(yíng)銷資訊
關(guān)于我們
客戶&案例
營(yíng)銷資訊
關(guān)于我們
微信公眾號(hào)
版權(quán)所有? 億企邦 1997-2025 保留一切法律許可權(quán)利。