image-20190824183015363.png
1. 點擊事件綁定在要點擊拖動的元素上
<div
class="area"
@mousedown.stop="mouseDown"> // 阻止冒泡
</div>
2. 移動和擡起事件綁定在了最外面的 App 上面
let appDocument = document.getElementById('app')
appDocument.addEventListener('mouseup', function (e) {
// throttle 防抖節流函數 mouseUp 鼠標擡起事件
throttle(that.mouseUp(e), 200, that, true)
})
appDocument.addEventListener('mousemove', function (e) {
// mouseMove 鼠標移動事件
throttle(that.mouseMove(e), 200, that, true)
})
-
######鼠標移動
-
e = window.event || e(因爲我的鼠標移動在多個元素之間,所以我選擇了綁定了 window 全局的事件)
-
保存 e.clientY (同樣的因爲 offectY 是根據當前元素的位置計算的值,因爲在多個元素間移動,所以選用針對視窗定位的 clientY ;也可以直接用不存進變量,因爲之前不瞭解 重繪 的觸發條件,保險起見選擇了保存複用)
-
將當前鼠標位置存進定義的儲存位置的數組裏(如果只有按下時的值,直接push,如果已經存在arr[0],arr[1] 則前移再push
-
是否觸發樣式重設:鼠標按下的開關 & 鼠標位置是否超過一定範圍
-
是: 用位置數組的兩個值相減,計算出鼠標位置的變化,觸發對應事件並且傳入差值
-
模塊
-
this.actionEle = document.getElementsByClassName('fanFan')[0] mouseChange (mouseChange) { // 當前高度是動態的 this.currentTop = parseInt(this.actionEle.style.top || 0) let moveTop = this.currentTop - mouseChange // 雖然限制了鼠標位置的範圍,但是爲了防止各種騷操作最後再限制一下要設置的Top值的範圍 moveTop = moveTop > 384 ? 384 : (moveTop < -253 ? -253 : moveTop) this.actionEle.style.top = moveTop + 'px' }
-
-
-
鼠標擡起
- 關掉鼠標按下的開關
3. 當我們寫好了拖動框之後可能會還想要一個點擊收回的效果
.warpper {
position: relative;
min-height: calc(100vh - 240px);
.main {
position: absolute;
overflow: hidden;
display:flex;
// 主軸方向
flex-direction: columns;
// flex-grow(項目的放大比例,默認爲0,即如果存在剩餘空間,也不放大。)
// flex-shrink(項目的縮小比例,默認爲1,即如果空間不足,該項目將縮小)
// flex-basis(項目的縮小比例,默認爲1,即如果空間不足,該項目將縮小項目佔據的主軸空間)
flex: 1 1 0%;
// 這是一個遮罩
background-color: rgba(0, 0, 0, 0) !important;
// 這是一個框格背景的實現
width: 100%;
height: 100%;
background-size: 50px 50px;
background-image: linear-gradient(0deg, transparent 24%, rgba(0, 0, 0, 0.05) 25%, rgba(0, 0, 0, 0.05) 26%, transparent 27%, transparent 74%, rgba(0, 0, 0, 0.05) 75%, rgba(0, 0, 0, 0.05) 76%, transparent 77%, transparent), linear-gradient(90deg, transparent 24%, rgba(0, 0, 0, 0.05) 25%, rgba(0, 0, 0, 0.05) 26%, transparent 27%, transparent 74%, rgba(0, 0, 0, 0.05) 75%, rgba(0, 0, 0, 0.05) 76%, transparent 77%, transparent);
// 這是拖動框上面的主面板
.middle {
flex: 0 0 auto;
position: relative;
height: 300px;
}
// 點擊添加這個class 展開這個拖動的塊
.open_tabs {
min-height: calc(100vh - 420px);
position: relative;
}
// 點擊添加這個class 收回這個拖動的塊
.close_tabs {
height: 35px;
position: absolute;
bottom: 0;
top: auto !important;
}
// 這是要拖動的塊
.down {
flex: 1 1 0%;
background: white;
}
}
}
- 這時要注意,不要再去修改該塊的top值
- 原因一: 修改之後可能會導致無法拖動
- 原因二:當你回收的時候在css裏並不能知道該塊現在的高度(之所以選擇css做這個事情,是因爲如果想要加上一些動畫效果會方便很多)
- 那怎麼做呢
- 我是去改變要收起元素的高度來解決的,具體 scss 代碼在上面
4. 防抖和節流
// 這個是之前在網上搜的代碼,找不見原鏈接了,如原作者介意,聯繫delete
/**
* 防抖節流
* @param {*} action 回調
* @param {*} delay 等待的時間
* @param {*} context this指針
* @param {Boolean} iselapsed 是否等待上一次
* @returns {Function}
*/
// eslint-disable-next-line no-unused-vars
function throttle (action, delay, context, iselapsed) {
let timeout = null
let lastRun = 0
return function () {
if (timeout) {
if (iselapsed) {
return
} else {
clearTimeout(timeout)
timeout = null
}
}
let elapsed = Date.now() - lastRun
let args = arguments
if (iselapsed && elapsed >= delay) {
runCallback()
} else {
timeout = setTimeout(runCallback, delay)
}
/**
* 執行回調
*/
function runCallback () {
lastRun = Date.now()
timeout = false
action.apply(context, args)
}
}
}
export { throttle }
5. 迴流的發生條件
- add/delete DOM
- 元素的大小、位置、內容發生改變
- offset屬性
- 頁面樣式style發生變化
- 瀏覽器窗口變化
- 固定定位
- 待補充…