1. 程式人生 > 其它 >框選元素拖動到另一個元素

框選元素拖動到另一個元素

技術標籤:vuedraggablevue-selectomouseH5

場景需求:選中列表中的某一項拖動到目標中

  • 使用工具vue-selecto進行框選
  • 使用H5的draggable屬性進行拖拽放置

使用工具vue-selecto進行框選

git地址:https://github.com/daybrush/selecto
demo地址: https://daybrush.com/selecto/storybook/?path=/story/selecto–select-in-real-time

以下是程式碼,來源是vue-selecto外掛

說明:HTML中vue-selecto主要使用依據是class名稱進行使用,dragContainer

bind:selectableTargets屬性中引用均為操作框選物件的css名稱,在專案中使用時對應原有即可

hitRate屬性是框選物件選中多大範圍算選中,例:100為全部框選為選中

HTML

<!-- 這裡是html程式碼 -->
<div class="container">
	<vue-selecto
	    dragContainer=".elements"
	    v-bind:selectableTargets='[".selecto-area .cube"]'
	    v-bind:
hitRate
='100' v-bind:selectByClick='true' v-bind:selectFromInside='true' v-bind:ratio='0' @select="onSelect" @selectEnd="selectEnd" >
</vue-selecto> <div class="elements selecto-area" id="selecto1"> <div class="
cube"
v-for="(cube,index) in cubes" :key="index" :id="index+1" @mousedown.stop>
{{index+1}}</div> </div> <div class="empty elements"></div> </div>

JS

// 這裡是js程式碼
import { VueSelecto } from 'vue-selecto'
export default {
  components: {
    VueSelecto
  },
  data () {
    return {
      cubes: [],
      selected: [],
    }
  },
  mounted () {
    for (let i = 0; i < 60; ++i) {
      this.cubes.push(i)
    }
  },
  methods: {
    onSelect (e) {
      e.added.forEach(el => {
        el.classList.add('selected')
      })
      e.removed.forEach(el => {
        el.classList.remove('selected')
        this.selected = []
      })
    },
    // 框選結束儲存資料
    selectEnd (e) {
      e.selected.map(item => {
        this.selected.push(item.id)
      })
    },
  }
}

css

/* 這裡是css樣式 */
.container {
   max-width: 800px;
}
.cube {
  display: inline-block;
  border-radius: 5px;
  width: 40px;
  height: 40px;
  margin: 4px;
  background: #eee;
  --color: #4af;
}
h1, .description {
  text-align: center;
}
.elements {
  margin-top: 40px;
  border: 2px solid #eee;
}
.selecto-area {
  padding: 20px;
}
#selecto1 .cube {
  transition: all ease 0.2s;
}
.moveable #selecto1 .cube {
  transition: none;
}
.selecto-area .selected {
  color: #fff;
  background: var(--color);
}
.empty.elements {
   border: none;
}

使用H5的draggable屬性進行拖拽放置

菜鳥教程地址:https://www.runoob.com/html/html5-draganddrop.html

說明:可以使用多個目的地元素,例如:a,b,c 拖動到1號目的地,e,f,g拖動到二號目的地

有坑!!!框選元素與拖拽元素操作衝突導致框選與拖拽失效

解決辦法:給框選元素加上@mousedown.stop,防止操作衝突

HTML

<!-- 拖拽後的目的地元素 -->
<div id="droptarget" @dragover.prevent="allowDrop" @drop.prevent="drop">
  {{selectEndList}}
</div>
<!-- 展示當前狀態文字 -->
<p id="text"></p>
<!-- 給元素新增拖拽屬性 @dragstart="dragStart" draggable="true" -->
 <div class="cube" v-for="(cube,index) in cubes"  @dragstart="dragStart" draggable="true" :key="index" :id="index+1" @mousedown.stop>{{index+1}}</div>

JS

// 這裡是js程式碼
data () {
	return {
	  selectEndList: [] // 展示拖拽到目的地後的資料
	}
},
methods: {
  // 拖拽開始將資料給目標元素
  dragStart () {
    console.log('start')
  },
  // 拖拽元素放置到了目的地元素上面
  allowDrop () {
    document.getElementById('demo').innerHTML = '元素在放置目標上'
  },
  // 拖拽元素結束了操作
  drop () {
    this.selectEndList = this.selected
    this.selected = []
    document.getElementById('demo').innerHTML = '元素被拖動'
  }
}

下面是展示效果:
在這裡插入圖片描述
總結: 專案實現是多個目的地和多個框選元素,專案開始前花了很長的時間去找外掛實現這兩種功能,直到後面發現拖拽H5中有屬性可以直接使用。這裡學到的就是及時去了解已有的新屬性,就算當時不會記住,至少在腦子裡有印象,後期需要用的時候可以憑藉印象去定位一定範圍搜尋合適的技術,避免後續海底撈針似的尋找;當多種功能重疊時,若找不到所有功能都使用的外掛時,應及時分解功能去找對應的技術。