1. 程式人生 > 程式設計 >vue中解決拖拽改變存在iframe的div大小時卡頓問題

vue中解決拖拽改變存在iframe的div大小時卡頓問題

寫在最前

針對於在vue中實現拖拽改變兩左右個div大小的方式,請檢視上一篇文章《vue中實現拖動調整左右兩側div的寬度》。此文章主要針對於實際應用中需要拖拽改變大小的元件中使用iframe框架時存在明顯示卡頓的問題,比如這樣,右側div中使用了一個iframe元件,導致實際操作中出現兩個問題,一個是拖不動,另外一個是無法根據滑鼠移動,快速響應,甚至在監聽滑鼠的按下和鬆開事件上都有明顯的卡頓問題。如果去除右側iframe框架,則沒有問題。

有iframe情況

vue中解決拖拽改變存在iframe的div大小時卡頓問題

無iframe情況

vue中解決拖拽改變存在iframe的div大小時卡頓問題

vue中解決拖拽改變存在iframe的div大小時卡頓問題

問題原因&解決思路

問題原因我不知道,不過這個部落格給了我解決思路《解決jqueryUI的拖拽,如果元素中含有iframe,拖動卡的問題》,還有以下說法,他們的解決思路一樣的。因此我猜想是滑鼠的監聽造成的影響,在我們拖拽的時候,因為拖拽過快,很容易出現滑鼠移動超過拖拽範圍的情況,此時的滑鼠可能已經在iframe上方,從而會同時載入iframe中的內容,導致出現卡頓。

總之,解決的思路就是在拖動的時候,在iframe上方新增一個透明的遮罩層,然後在停止拖拽的時候讓其消失。這樣問題就可以完美解決了。

vue中解決拖拽改變存在iframe的div大小時卡頓問題

解決方式共有兩節,一節包含我解決過程中遇到的問題,一節是直接的解決方式,如果想直接檢視解決方式的,請直接跳轉至解決方式那一節

解決方式(含解決過程中遇到的問題)

HTML元件部分原始碼

這是實現拖拽的元件程式碼,如果不瞭解我原本使用的實現方式,請參考《vue中實現拖動調整左右兩側div的寬度》

<div class="box" ref="box">
   <div class="left" ref="left">

   </div>
   <div class="resize" ref="resize" title="收縮側邊欄">
    ⋮
   </div>
   <div class="mid" ref="mid">
    <!--在此處新增遮罩層-->
    <iframe id="iFrame1" name="iFrame1" width="100%" height="100%" frameborder="0" scrolling="auto"
      :src="iframeUrl">
    </iframe>
   </div>
  </div>

新增遮罩層

在以上標註的地方,新增如下程式碼

<div class="iframeDiv"></div>

再新增遮罩層的css樣式即可,此時最好測試點選一下,是不是原來的ifame部分已經不能點選,而且拖拽起來已經不再卡頓了

/* 新增透明遮罩層 */ 
.iframeDiv {
  width: 100%;
  height: 100%;
  position: absolute;
  z-index: 1111;
  filter: alpha(opacity=0);
  opacity: 0;
  background: transparent;
  margin-top: 30px;
  /*display: none;*/
 }

實現遮罩層在拖拽時出現

我的解決辦法是直接在拖拽區域新增監聽滑鼠的按下和鬆開事件,按下後遮罩層出現,鬆開後消失,因此修改resize部分,新增onmouseup&mousedown,分別傳入引數,用於修改iframeDiv的css樣式中的display屬性值

<div class="resize" ref="resize" @mousedown="changeIframeDivStyle('')" @onmouseup="changeIframeDivStyle('none')" >
  ⋮
 </div>

然後新增changeIframeDivStyle方法,因為getElementByClassName返回的是個陣列集合,但是我又確認自己頁面只有一個iframeDiv,所以選擇了iframe[0],如果想使用getElementById也可以

changeIframeDivStyle(display) {
    var iframeDiv = document.getElementsByClassName('iframeDiv');
    iframeDiv[0].style.display = display;
   },

到此基本就算完成大半了,mousedown為滑鼠按下事件,按下後設置display為空,即遮罩層出現,onmouseup為滑鼠鬆開事件,鬆開後遮罩層消失,達到不影響使用者操作檢視iframe中內容的目的

頁面初始化時遮罩層設定問題

按照實際來講,初始化進入頁面時,我們就不應該留有遮罩層,所以按照我的想法來講,就是直接在css中修改樣式,但是如上所見,我把它註釋掉了,至於為什麼,先賣個關子,大家修改後嘗試一下,看看拖拽時卡頓不卡頓

display: none;

在我本以為這樣就可以解決問題時,我發現,首次進入頁面,直接進行拖拽,依舊會存在卡頓,但是拖拽過一次之後,就不會再有問題了。這個問題,,我又不知道為什麼了,於是,既然它需要拖拽一次之後才不會卡頓,那我就直接註釋掉了css中這個display樣式,反而在 mounted中新增方法,這樣反而成功了,雖然搞不明白兩者的差距,但是問題總算是解決了,如果有知道原因的朋友,可以在評論中分享出來,供大家學習學習。

this.changeIframeDivStyle('none');

解決方式

在iframe上新增透明遮罩層樣式

<div class="box" ref="box">
   <div class="left" ref="left">

   </div>
   <div class="resize" ref="resize" title="收縮側邊欄">
    ⋮
   </div>
   <div class="mid" ref="mid">
    <!--在此處新增遮罩層-->
   <div class="iframeDiv"></div>
    <iframe id="iFrame1" name="iFrame1" width="100%" height="100%" frameborder="0" scrolling="auto"
      :src="iframeUrl">
    </iframe>
   </div>
  </div>  

新增CSS樣式

 .iframeDiv {
  width: 100%;
  height: 100%;
  position: absolute;
  z-index: 1111;
  filter: alpha(opacity=0);
  opacity: 0;
  background: transparent;
  margin-top: 30px;
  /*display: none;*/
 }

新增滑鼠的監聽事件

在拖拽區新增滑鼠的按下事件和鬆開事件

 <div class="resize" ref="resize" @mousedown="changeIframeDivStyle('')" @onmouseup="changeIframeDivStyle('none')" >
  ⋮
 </div>

新增方法

changeIframeDivStyle(display) {
    var iframeDiv = document.getElementsByClassName('iframeDiv');
    iframeDiv[0].style.display = display;
   },

設定頁面初始化載入

this.changeIframeDivStyle('none');

到此這篇關於vue中解決拖拽改變存在iframe的div大小時卡頓問題的文章就介紹到這了,更多相關vue拖拽div卡頓內容請搜尋我們以前的文章或繼續瀏覽下面的相關文章希望大家以後多多支援我們!