基于 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)文章,希望大家以后多多支持腳本之家!