HTML 拖拉功能的實現(xiàn)代碼

基于 vue
此功能核心思想就是通過 JavaScript 代碼控制 node 在頁面上的左邊距與頂邊距,不同的的樣式定位方式有不同的解決方案
本方案采用position: absolute
定位方式的解決方案
css 樣式的核心代碼
// 父容器核心樣式 width: 100%; height: 100%;
// 子容器核心樣式 position: absolute; top: 50%; left: 50%; transform: translate(-50%,-50%);
父容器通過width && height
字段占滿整個瀏覽器的可視范圍,子容器通過position: absolute
屬性開啟在父容器內(nèi)的絕對定位,在通過top && left && transform: translate(-50%, -50%)
屬性控制子容器在父容器內(nèi)的絕對位置
JavaScript 邏輯控制的核心代碼
首先分解下,要實現(xiàn) node 的移動需要哪些步驟和對應(yīng)的 event 事件
- 子容器創(chuàng)建時,在父容器內(nèi)的絕對位置
- 鼠標按鍵按下時,onmousedown 事件
- 鼠標移動時,onmousemove 事件
- 鼠標按鍵彈起時,onmouseup 事件
只要使用 onMousedown、onMousemove和onMouseup 這三個事件,就可以實現(xiàn)最簡單的移動
/* * 在子容器創(chuàng)建的時候獲取子容器相對于父容器的 top 和 left 位置 */ mounted () { this.left = this.$refs.fatherBox.offsetLeft this.top = this.$refs.fatherBox.offsetTop }
/* * 鼠標按下時 * 1. 開啟允許子容器移動的 flag * 2. 記錄鼠標點擊時的位置信息 */ mouseDown (e) { // 設(shè)置允許彈窗移動的 flag this.moveFlag = true // 保存鼠標開始位置 this.startLeft = e.clientX - this.left this.startTop = e.clientY - this.top }
/* * 鼠標移動時 * 1. 判斷 flag 是否允許子容器移動 * 2. 設(shè)置彈框左邊位置 * 3. 設(shè)置彈框右邊位置 */ move (e) { // 判斷 flag 是否允許移動 if (!this.moveFlag) return // 設(shè)置彈框左邊位置 this.left = e.clientX - this.startLeft // 設(shè)置彈框右邊位置 this.top = e.clientY - this.startTop }
/* * 鼠標按鍵彈起時 * 1. 關(guān)閉允許子容器移動的 flag */ mouseUp (e) { this.flag = false }
通過這幾個方法就可以獲取鼠標按下移動時,鼠標的top 和 left 的偏移量,通過把這偏移量暴露出去給父組件,父組件實時設(shè)置子組件的 top 和 left 值,來使得子容器跟隨鼠標的移動
父組件部分代碼
父組件通過設(shè)置子組件的 ref、zIndex 值,而且父組件的 backValue 方法會從子組件接收 zIndex 值,通過 zIndex 來識別具體的子組件實例
/* * 父組件代碼片段 jsx 版 */ export default { props: { playList: { type: Array, required: true } }, render () { return ( <div style={{width: '100%', height: '100%'}} ref={'father'}> { this.playList && this.playList.map((item, index) => { return ( <ChildComponents key={index} ref={index} zIndex={index} visible={true} backValue={this.backValue} info={item} width={600} height={400} /> ) }) } </div> ) }, methods: { backValue (left, top, zIndex) { this.$refs[zIndex].$el.style.top = `${top}px` this.$refs[zIndex].$el.style.left = `${left}px` } } }
<!-- 父組件代碼片段 vue 文件版 --> <template> <div ref="father" style"width: 100%, height: 100%" > <ChildComponents v-for="(item, index) in playList" :key="index" :ref="index" :visible="true" :z-index="index" :back-value="backValue" :info="item" :close="close" :width="600" :height="400" /> </div> </template> <script> export default { components: { VideoPlayerModal }, props: { playList: { type: Array, required: true } }, methods: { backValue (left, top, zIndex) { this.$refs[zIndex][0].$el.style.top = `${top}px` this.$refs[zIndex][0].$el.style.left = `${left}px` } } } </script>
設(shè)置子組件的圍欄范圍
這個功能只需要在 onmousemove 事件中進行判斷 子容器的 top 和 left 是否超出瀏覽器的可視范圍
/* * 1. this.width 數(shù)據(jù)為父組件傳遞進來的 width 值,或者子組件本身設(shè)置的默認值 * 2. this.height 數(shù)據(jù)為父組件傳遞進來的 height 值,或者子組件本身設(shè)置的默認值 */ move (e) { // 判斷 flag 是否允許移動 if (!this.moveFlag) return // 判斷是否超出左邊視圖 if (this.$refs.fatherBox.offsetLeft < this.width / 2) { // 禁止彈框移動 this.moveFlag = false // 設(shè)置彈框左邊位置 this.left = this.width / 2 + 10 // 調(diào)用回調(diào)函數(shù)把偏移量暴露給父組件 this.backValue(this.left, this.top, this.zIndex) return } // 判斷是否超出右邊視圖 if (this.$refs.fatherBox.offsetLeft > document.body.clientWidth - this.width / 2) { // 禁止彈框移動 this.moveFlag = false // 設(shè)置彈框右邊位置 this.left = document.body.clientWidth - this.width / 2 - 10 // 調(diào)用回調(diào)函數(shù)把偏移量暴露給父組件 this.backValue(this.left, this.top, this.zIndex) return } // 判斷是否超出頂部視圖 if (this.$refs.fatherBox.offsetTop < this.height / 2 + 70) { // 禁止彈框移動 this.moveFlag = false // 設(shè)置彈框頂部位置 this.top = this.height / 2 + 70 + 10 // 調(diào)用回調(diào)函數(shù)把偏移量暴露給父組件 this.backValue(this.left, this.top, this.zIndex) return } // 判斷是否超出底部視圖 if (this.$refs.fatherBox.offsetTop > document.body.clientHeight - this.height / 2 - 50) { // 禁止彈框移動 this.moveFlag = false // 設(shè)置彈框底部位置 this.top = document.body.clientHeight - this.height / 2 - 50 - 10 // 調(diào)用回調(diào)函數(shù)把偏移量暴露給父組件 this.backValue(this.left, this.top, this.zIndex) return } // 設(shè)置彈框左邊位置 this.left = e.clientX - this.startLeft // 設(shè)置彈框右邊位置 this.top = e.clientY - this.startTop // 調(diào)用回調(diào)函數(shù)把偏移量暴露給父組件 this.backValue(this.left, this.top, this.zIndex) }
子組件還要設(shè)置一個當鼠標超出子容器時的 onmouseout 事件,用來防止不可預(yù)期的 bug 問題
mouseOut (e) { this.moveFlag = false }
到此這篇關(guān)于HTML 拖拉功能的文章就介紹到這了,更多相關(guān)HTML 拖拉功能內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持腳本之家!
相關(guān)文章
- 本篇文章主要介紹了HTML5拖拉上傳文件的簡單實例,小編覺得挺不錯的,現(xiàn)在分享給大家,也給大家做個參考。一起跟隨小編過來看看吧2017-01-11