91超碰碰碰碰久久久久久综合_超碰av人澡人澡人澡人澡人掠_国产黄大片在线观看画质优化_txt小说免费全本

溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務條款》

Element-ui中元素滾動時el-option超出元素區域的問題

發布時間:2021-07-21 11:44:49 來源:億速云 閱讀:449 作者:小新 欄目:web開發

這篇文章主要為大家展示了“Element-ui中元素滾動時el-option超出元素區域的問題”,內容簡而易懂,條理清晰,希望能夠幫助大家解決疑惑,下面讓小編帶領大家一起研究并學習一下“Element-ui中元素滾動時el-option超出元素區域的問題”這篇文章吧。

復現場景, 看圖

Element-ui中元素滾動時el-option超出元素區域的問題

分析原因

為簡單起見, 把選項區域描述為popperEl

  • popperEl的z-index 比較大, 會覆蓋在其他元素上面

  • popperEl默認是插入body元素的(可以將popper-append-to-body設為false后不插入到body)

  • popperEl是在mouseup事件里去做隱藏邏輯的, 而按下鼠標, 移動滾動條的時候, 并沒有觸發mouseup事件.

  • popperEl并沒有監聽滾動事件(沒法監聽, 也沒必要監聽)

解決方案

 方案一

我最初想到的解決方案是通過css解決,通過popper-class屬性給Select下拉框添加類名,然后用css來做, 試了一下這個方案并不可行(只能在某些特定的場景下起作用),遂放棄,可能最優雅最高性能的方法就是用css來搞定, 有踩過這個坑的朋友請指點一下

方案二

通過監聽$root的scroll事件,利用事件冒泡,只需要在根元素上添加scroll事件的監聽就可以了, 測試一番之后, 發現scroll事件根本不支持冒泡, event.bubbles為false)。

方案三

通過查看element-ui 的select.vue, 發現控制popperEl顯隱的是visible 和 emptyText這兩個實例屬性, 很明顯, emptytext是不能動的, 只能在visible上動手腳了. 這里放一小段源碼

<transition
 name="el-zoom-in-top"
 @before-enter="handleMenuEnter"
 @after-leave="doDestroy">
 <el-select-menu
  ref="popper"
  :append-to-body="popperAppendToBody"
  v-show="visible && emptyText !== false">
  <el-scrollbar
   tag="ul"
   wrap-class="el-select-dropdown__wrap"
   view-class="el-select-dropdown__list"
   ref="scrollbar"
   :class="{ 'is-empty': !allowCreate && query && filteredOptionsCount === 0 }"
   v-show="options.length > 0 && !loading">
   <el-option
    :value="query"
    created
    v-if="showNewOption">
   </el-option>
   <slot></slot>
  </el-scrollbar>
  <p
   class="el-select-dropdown__empty"
   v-if="emptyText &&
    (!allowCreate || loading || (allowCreate && options.length === 0 ))">
   {{ emptyText }}
  </p>
 </el-select-menu>
</transition>

全局搜索this.visible, 發現了這個方法

handleClose() {
  this.visible = false;
},

這下好辦了, 按圖索驥, 順藤摸瓜, 找到這個

<template>
 <div
  class="el-select"
  :class="[selectSize ? 'el-select--' + selectSize : '']"
  @click.stop="toggleMenu"
  v-clickoutside="handleClose">
  后面的省略...

找到v-clickoutside指令之后, 豁然開朗 原來點擊其他區域的時候, popperEl會自動關閉的奧秘在這里, 結合方案二的靈感, 現給出如下代碼.

// src/mixins/fackClickOutSide.js
let lock = true;
let el = null;
const MousedownEvent = new Event('mousedown', {bubbles:true});
const MouseupEvent = new Event('mouseup', {bubbles:true});
const fakeClickOutSide = () => {
 document.dispatchEvent(MousedownEvent);
 document.dispatchEvent(MouseupEvent);
 lock = true; // console.log('dispatchEvent');
};
const mousedownHandle = e => {
 let classList = e.target.classList;
 if(classList.contains('el-select__caret') || classList.contains('el-input__inner')) {
  lock = false;
  return;
 }
 if(lock) return;
 fakeClickOutSide();
};
const mousewheelHandle = e => {
 if(lock || e.target.classList.contains('el-select-dropdown__item') || e.target.parentNode.classList.contains('el-select-dropdown__item')) return;
 fakeClickOutSide();
};
const eventListener = (type) => {
 el[type + 'EventListener']('mousedown', mousedownHandle);
 window[type + 'EventListener']('mousewheel', mousewheelHandle);
 window[type + 'EventListener']('DOMMouseScroll', mousewheelHandle); // fireFox 3.5+ 
}
export default {
 mounted() {
  el = this.$root.$el;
  el.addFakeClickOutSideEventCount = el.addFakeClickOutSideEventCount || 0;
  (! el.addFakeClickOutSideEventCount) && this.$nextTick(() => {
   eventListener('add');
  });
  el.addFakeClickOutSideEventCount += 1;
 },
 destroyed() {
  eventListener('remove');
  el.addFakeClickOutSideEventCount -= 1;
 },
}

使用姿勢

建議在根組件上混合進去, 當然,你也可以在需要的組件上去混合(不太建議, 這點代碼性能損耗應該不大吧, 哈哈哈)

// src/App.vue
import fakeClickOutSide from '@/mixins/fakeClickOutSide.js'
export default {
  name: 'App',
  mixins: [fakeClickOutSide],
}

測試

常規基礎用法 和 自定義模板用法(模板內沒有嵌套的標簽) 均完美通過.

自定義模板內如果嵌套多級標簽, 需要在標簽上添加標記,然后在mousewheel事件回調里判斷是否有這個標記.

總結

依然存在的問題(隱患):

  • 在mousewheel事件回調沒有做節流, 考慮到有鎖, 且滾輪事件觸發的頻率也不是很高(相對于mousemove事件來講), 性能消耗并不大, 遂不做節流(主要是懶).

  • 在mousewheel事件回調里,判斷event.target 是否是在popperEl元素內部的方法感覺不是很靠譜, 且效率不高, 在mousedown 事件里判斷是不是el-select元素的方法也存在同樣的隱患, 后期再想辦法修改(修改是不可能修改的, 又不是不能用).

  • 在自定義模板用法里, 如果有嵌套的標簽, 那么在mousewheel事件回調里判斷event.target 是不是在popperEl元素內部的方法就崩潰了(這是個雷), 目前的解決辦法是手動在嵌套的標簽上都加上一個標記, 在事件里,添加這個標記的判斷, 但是這種做法對于已經編寫完成的模板無效, 只能再次修改, 考慮過使用遞歸向上查找, 但是效率不高, 性能消耗太大, 且自定義el-option模板這種情況在我們現階段的業務中幾乎不存在, 所以就沒有考慮這個bug.

以上是“Element-ui中元素滾動時el-option超出元素區域的問題”這篇文章的所有內容,感謝各位的閱讀!相信大家都有了一定的了解,希望分享的內容對大家有所幫助,如果還想學習更多知識,歡迎關注億速云行業資訊頻道!

向AI問一下細節

免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。

AI

启东市| 周宁县| 克什克腾旗| 乾安县| 沂水县| 通城县| 鄂托克前旗| 衡阳县| 祁门县| 河西区| 长武县| 仪征市| 壤塘县| 武邑县| 沈丘县| 且末县| 远安县| 宁南县| 黄大仙区| 永春县| 敦煌市| 南汇区| 来凤县| 水城县| 六盘水市| 镇远县| 翁源县| 衡阳县| 岳阳县| 潜山县| 江源县| 乌审旗| 温泉县| 揭阳市| 天台县| 玛纳斯县| 尉犁县| 恩施市| 奈曼旗| 丁青县| 正蓝旗|