react-component/menu

SubMenu 水平模式 在IE 浏览器下面 不弹出二级菜单

ikonan opened this issue · 17 comments

SubMenu 水平模式 在IE 浏览器下面 不弹出二级菜单,只有第一个菜单有二级菜单能够正确弹出,后面其他菜单有二级菜单的情况都不会弹出, 我多次测试后发现在8.x 版本水平模式在IE 都能正确的弹出二级菜单,一旦升级到9.x 版本就不能正确兼容IE。

image

same problem here.
我也遇到了……从antd 4.11升级到4.20

@yiminghe 大神帮忙看哈这个兼容性问题撒

有啥报错么?

@afc163
应该不是 includes polyfill 的问题,在IE浏览器下面第一个二级菜单是能够正常显示的, 但是后面的二级菜单都不能正常显示。 onOpenChange 这个方法也不会执行。
image

来个 PR 吧

原因可能跟rc-overflow相关,在ie11下,rc-overflow的base案例,渲染和chromium内核/firefox不一致。
debug中,争取这两天一个PR

表面原因是:overflow非第0项,display被设置为false,https://github.com/react-component/overflow/blob/v1.2.5/src/Overflow.tsx#L316 ,rest项的高度被设置为了0

  1. 然后布局占用为 0,IE11下没触发ResizeObserver的onResize
  2. 没触发Overflow的registerOverflowSize
  3. restWidth始终为 0
  4. mergedRestWidth始终为 0
  5. useLayoutEffect内的流程判断不需要进入
  6. displayCount得不到更新,始终为 0
  7. 绕回原点,mergedDisplayCount始终为 0
  8. 状态无变更,不进行后续刷新,于是第0项之后的内容,处于隐藏状态。

目前绕过的方法是将上述流程打断。
譬如将Item的useEffect

  React.useEffect(
    () => () => {
      internalRegisterSize(null);
    },
    [],
  );

改成

React.useEffect(
     () => {
      internalRegisterSize(1);
    },
    [],
  )

又或者将prevRestWidth初始值改为1

深层的原因应该是跟ResizeObserver相关,正确的修复应该是保证ResizeObserver在ie11上的行为。
我继续找找正确的修复方法。

正确的修复应该是保证ResizeObserver在ie11上的行为。

+1

根据spec,目前确定为是polyfill的bug

Observation will fire when observation starts if Element is being rendered, and Element’s size is not 0,0.

将rc-resize-observer的bug验证代码微微修改一下,

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>ResizeObserver IE11 bug</title>
    <style>
        .hidden {
            height: 0;
            overflow: hidden;
        }
    </style>
    <script src="dist/ResizeObserver.global.js"></script>
</head>
<body>
<div id="parent">
    <div class="hidden">label 1</div>
    <div class="hidden">label 2</div>
    <div class="hidden">label 3</div>
</div>
<script>
    function pResize() {
        console.log('resize in Parent');
    }

    function cResize(entries) {
        var i;
        for (i = 0; i < entries.length; i++) {
            console.log('resize in Child', entries[i].target.innerText);
        }
    }

    var p = document.querySelector('#parent');
    var children = document.querySelectorAll('.hidden');
    var obp = new ResizeObserver(pResize);
    var obc = new ResizeObserver(cResize);
    obp.observe(p);
    var i, el;
    for (i = 0; i < children.length; i++) {
        el = children[i];
        obc.observe(el);
    }
</script>
</body>
</html>

继续往下挖,resize-observer-polyfill的实现,在IE11上使用的是mutation observer,
这该咋整……patch ie11的MutationObserver实现么?

emmm……现在挖出来是,height: 0; overflow: hidden;,在ie11下,clientWidth为0,与chromium不一致。

已给上游提交quick fix

等待合并,或者正式的修复……

等上游估计是遥遥无期了,用webpack.NormalModuleReplacementPlugin先凑合本地解决了。