vue項(xiàng)目左右布局(右側(cè)布局是iframe) 中分線可拖拽及卡頓問題解決

image.png

功能需求:頁面左右布局,左邊初始定寬512px,右側(cè)寬度 flex:1,分割線中間有拖拽按鈕,拖拽時(shí) 左側(cè)的寬度最大寬度是現(xiàn)在寬度+現(xiàn)在寬的的50%。最小寬度是初始寬度的一半 。

解決思路:在mounted生命周期,監(jiān)聽分割線DOM的onmousedown事件,在拖拽過程中動(dòng)態(tài)計(jì)算,然后賦值改變左右DOM元素的寬度。

實(shí)現(xiàn)代碼:(class類里用的tailwindcss)

<!--template-->
 <div class={['flex h-full']}>
     <div class={[style.subject__left_container, 'relative']} ref='leftDom'>
        左側(cè)內(nèi)容區(qū)
      </div>
   <div class='flex-1 flex h-full relative'>
       {this.envHost && <iframe src={this.envHost} style='height:100%; width:100%'/>}
       {!this.envHost && <Empty/>
   </div>
</div>

<!--css-->
.subject__left_container {
  width: 512px;
  border-right: 1px solid #e8e8e8;
}

<!--js-->
  // mounted生命周期
  public mounted() {
    this.leftDom = this.$refs.leftDom;
    let moveDom = this.$refs.moveDom;
    (moveDom as any).onmousedown = (e: any) => {
      this.clientStartX = e.clientX;
      e.preventDefault();
  
      document.onmousemove = (e) => {
        this.moveHandle(e.clientX, this.leftDom);
      };

      document.onmouseup = () => {
        document.onmouseup = null;
        document.onmousemove = null;
      };
    };
  }

 public moveHandle(nowClientX: number, letfDom: any) {
    let computedX = nowClientX - this.clientStartX;
    let leftBoxWidth = parseInt(letfDom.clientWidth);
    let changeWidth = leftBoxWidth + computedX;
    if (changeWidth < 256) {
      changeWidth = 256;
    }

    if (changeWidth > 768) {
      changeWidth = 768;
    }
    letfDom.style.width = changeWidth + 'px';
    this.clientStartX = nowClientX;
  }

??注意: 以上代碼對(duì)左右布局都是div的話 是ok的,但是當(dāng)我們右邊的布局里有iframe,單純這么寫,拖拽時(shí)鼠標(biāo)移入右側(cè)iframe區(qū)時(shí)會(huì)拖不動(dòng),或者無法根據(jù)鼠標(biāo)移動(dòng),快速響應(yīng),甚至在監(jiān)聽鼠標(biāo)的按下和松開事件上都有明顯的卡頓問題。

解決方法:在拖動(dòng)的時(shí)候,在iframe上方添加一個(gè)透明的遮罩層,然后在停止拖拽的時(shí)候讓其消失。

<!--template-->
 <div class={['flex h-full']}>
     <div class={[style.subject__left_container, 'relative']} ref='leftDom'>
        左側(cè)內(nèi)容區(qū)
      </div>
   <div class='flex-1 flex h-full relative'>
      <div class={style.iframe__div} ref='iframeDiv'/>
       {this.envHost && <iframe src={this.envHost} style='height:100%; width:100%'/>}
       {!this.envHost && <Empty/>
   </div>
</div>

<!--css-->
.subject__left_container {
  width: 512px;
  border-right: 1px solid #e8e8e8;
}

.iframe__div {
  width:100%;
  height: 100%;
  position: absolute;
  z-index: 999;
  filter: alpha(opacity=0);
  opacity: 0;
  background: transparent;
  display: none;
}

<!--js-->
  // mounted生命周期
  public mounted() {
    this.leftDom = this.$refs.leftDom;
    let moveDom = this.$refs.moveDom;
    var iframeDiv = this.$refs.iframeDiv;
    (moveDom as any).onmousedown = (e: any) => {
      this.clientStartX = e.clientX;
      e.preventDefault();
      if (iframeDiv) {
        (iframeDiv as any).style.display = 'block';
      }
      document.onmousemove = (e) => {
        this.moveHandle(e.clientX, this.leftDom);
      };

      document.onmouseup = () => {
       if (iframeDiv) {
          (iframeDiv as any).style.display = 'none';
        }
        document.onmouseup = null;
        document.onmousemove = null;
      };
    };
  }

 public moveHandle(nowClientX: number, letfDom: any) {
    let computedX = nowClientX - this.clientStartX;
    let leftBoxWidth = parseInt(letfDom.clientWidth);
    let changeWidth = leftBoxWidth + computedX;
    if (changeWidth < 256) {
      changeWidth = 256;
    }

    if (changeWidth > 768) {
      changeWidth = 768;
    }
    letfDom.style.width = changeWidth + 'px';
    this.clientStartX = nowClientX;
  }
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容