拖動框 + 收回展開

image-20190824183015363.png

1. 點擊事件綁定在要點擊拖動的元素上

<div
  class="area"
  @mousedown.stop="mouseDown"> // 阻止冒泡
</div>
  • 鼠標按下
    • 獲取當前的 window.clientY ,並存儲在數組裏(這裏我是用長度爲2的數組,記錄鼠標移動前後的座標)
    • 給一個開關,保證是從點擊當前元素開始

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發生變化
  • 瀏覽器窗口變化
  • 固定定位
  • 待補充…
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章