最新公告
  • 欢迎您光临起源地模板网,本站秉承服务宗旨 履行“站长”责任,销售只是起点 服务永无止境!立即加入钻石VIP
  • el-select框在页面滚动时el-option超出元素区域

    正文概述 掘金(到了冬天以后)   2021-01-25   1376

    问题场景:有页面内嵌了表格(含滚动条),内嵌了大量input和select,在点击select出现下拉框时,正常的情况是图1,但是在滚动表格内的滚动条时,会出现图二的情况。

    导致原因:select的下拉框的元素标签不是跟随在select之后,而是在body标签下面,并且z-index较高,如图3。

    el-select框在页面滚动时el-option超出元素区域

    图1

    el-select框在页面滚动时el-option超出元素区域 图2

    el-select框在页面滚动时el-option超出元素区域 图3

    解决办法

    首先,尝试popper-append-to-body属性设置为false之后无效。

    有效的解决办法来自https://www.e-learn.cn/topic/2821254,但是应用于公司的组件实现存在一定的问题。

    该文章的核心思想是,

    • 监听鼠标按下事件;
    • 当鼠标按下时,判断点击元素是不是select,如果是置lock为false;如果不是直接返回;
    • 当鼠标再次点击时,点击非select元素且lock为false,则强制执行鼠标按下、抬起事件(目的时让select下拉框收起),置lock为true;
    • 监听滚轮事件;
    • 当鼠标位置下方的元素是select,select内置滚动条,则直接返回;
    • 当鼠标位置下方的元素非select,则强制执行鼠标按下、抬起事件(目的时让select下拉框收起),置lock为true;

    1. 创建js文件

    // 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 => {
      const classList = e.target.classList;
      // 该判断条件是用来判断点击的是否为下拉框
      // el-select__caret代表是点击小三角出现下拉框,el-input__inner代表点击的整个input框
      // 如果公司组件的类名不同,对应修改即可
      if (
        (classList && classList.contains('el-select__caret')) ||
        (classList && classList.contains('el-input__inner'))
      ) {
        lock = false;
        return;
      }
      if (lock) return;
      fakeClickOutSide();
    };
    const mousewheelHandle = e => {
      // 如果当前select本身有滚动条,则直接返回
      // 原文对于classList没有判空,会报错
      if (
        lock ||
        (e.target.classList.length !== 0 &&
          e.target.classList.contains('el-select-dropdown__item')) ||
        (e.target.parentNode.classList !== undefined &&
          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;
      }
    };
    
    

    2. 使用

    在想要引入的组件内

    import fackClickOutSide from '@/mixin/fackClickOutSide.js';
    export default {
      name: 'FormWithAnchor',
      mixins: [fackClickOutSide],
    }
    

    3.知识点

    1. Event

    Event()构造函数创建一个新的Event。

    event = new Event(typeArg,eventInit);
    

    typeArg:事件名称;

    eventInit:这是一个对象,包含以下字段:

    • bubbles:(可选)Boolean指示事件是否冒泡。默认是false
    • cancelable:(可选)a Boolean表示是否可以取消该事件。默认是false

    2. document.dispatch

    dispatchEvent() 就是触发执行,

    dom.dispatchEvent(eventObject),参数eventObject 表示事件对象,是createEvent()方法返回的创建的Event对象。

    作用:触发执行。例如:鼠标未按下,触发鼠标按下的event函数,能达到和鼠标按下一样的效果。

    3. DOM addEventListener添加事件监听函数

    element.addEventListener(event, function, useCapture)

    event:必须。字符串,指定事件名。

    function: 必须。指定要事件触发时执行的函数。

    useCapture:可选。布尔值,指定事件是否在捕获或冒泡阶段执行。可能值:

    • true:事件句柄在捕获阶段执行
    • false-:默认。事件句柄在冒泡阶段执行

    4. e.target

    谁触发事件代表的就是谁。

    target 属性规定哪个 DOM 元素触发了该事件; target 事件属性可返回事件的目标节点(触发该事件的节点),如生成事件的元素、文档或窗口。


    起源地下载网 » el-select框在页面滚动时el-option超出元素区域

    常见问题FAQ

    免费下载或者VIP会员专享资源能否直接商用?
    本站所有资源版权均属于原作者所有,这里所提供资源均只能用于参考学习用,请勿直接商用。若由于商用引起版权纠纷,一切责任均由使用者承担。更多说明请参考 VIP介绍。
    提示下载完但解压或打开不了?
    最常见的情况是下载不完整: 可对比下载完压缩包的与网盘上的容量,若小于网盘提示的容量则是这个原因。这是浏览器下载的bug,建议用百度网盘软件或迅雷下载。若排除这种情况,可在对应资源底部留言,或 联络我们.。
    找不到素材资源介绍文章里的示例图片?
    对于PPT,KEY,Mockups,APP,网页模版等类型的素材,文章内用于介绍的图片通常并不包含在对应可供下载素材包内。这些相关商业图片需另外购买,且本站不负责(也没有办法)找到出处。 同样地一些字体文件也是这种情况,但部分素材会在素材包内有一份字体下载链接清单。
    模板不会安装或需要功能定制以及二次开发?
    请QQ联系我们

    发表评论

    还没有评论,快来抢沙发吧!

    如需帝国cms功能定制以及二次开发请联系我们

    联系作者

    请选择支付方式

    ×
    迅虎支付宝
    迅虎微信
    支付宝当面付
    余额支付
    ×
    微信扫码支付 0 元