Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

fix: 适配获取shadowDom中html的clientHeight #589

Open
wants to merge 1 commit into
base: master
Choose a base branch
from

Conversation

Xusenbiao
Copy link
Contributor

  • 提交符合commit规范
  • 文档更改
  • 测试用例添加
  • npm run test通过
详细描述

通过clientHeight获取元素高度有个特例:
对于html节点,会拿到窗口高度(viewport height):https://www.w3.org/TR/2016/WD-cssom-view-1-20160317/#dom-element-clientheight

但在shadowDom中,子应用htmlclientHeight拿到的是html节点高度。

document.documentElement.clientHeight // html height

非降级模式下,子应用弹窗可以溢出到全局,但当子应用内的悬浮提示定位依赖这个属性时,就会导致定位不准确。
(我这边出问题的场景是,子应用的弹窗内,表单校验提示的悬浮气泡定位不准)
排查发现是气泡的定位代码依赖了jQuery获取window高度的写法:

jQuery(window).height()

jQuery对应的内部实现为:

if ( isWindow( elem ) ) {
    return funcName.indexOf( "outer" ) === 0 ?
        elem[ "inner" + name ] :
        elem.document.documentElement[ "client" + name ];
}

拿到了html的高度从而导致气泡错位。
此PR针对该场景,处理了shadowDomhtmlclientHeight属性,使其拿到外层htmlclientHeight
对于嵌套场景,会继续传递,拿到最外层的htmlclientHeight
对于降级场景,因弹窗不会溢出到全局,故无需处理。

  • 特性
  • 关联issue

@yiludege
Copy link
Collaborator

yiludege commented Jul 7, 2023

这个地方建议采用插件来解决这个问题,因为不同用户对clientHeight的需求不一致,有一些需求是希望那外面window的,有一些需求是希望拿shadowdom的视窗,这个地方可能就是一个使用wujie的心智负担,没有很好的办法来解决

@NNNNzs
Copy link

NNNNzs commented Aug 1, 2023

我尝试在插件中改写

const plugins = [
  {
    documentPropertyOverride(iframWindow: Window) {
      Object.defineProperty(
        iframWindow.document.documentElement,
        'clientHeight',
        {
          enumerable: true,
          configurable: false,
          get() {
            return window.document.documentElement.clientHeight;
          },
        },
      );
    },
  },
];

子应用中没能拦截成功,且打印时访问不到iframWindow.document.documentElement

@nigiwen
Copy link

nigiwen commented Oct 23, 2023

@NNNNzs 哥你解决没,我也想修改子应用的clientHeight

@NNNNzs
Copy link

NNNNzs commented Oct 24, 2023

@NNNNzs 哥你解决没,我也想修改子应用的clientHeight

import type { plugin } from "wujie";
/**
 *  该插件拦截子应用的clientHeight和clientWidth属性,使子应用中取值的时候,拿到的是主应用的值
 */
export const rewriteChildclientHeightplugin: plugin = {
  windowPropertyOverride: (iframWindow) => {
    iframWindow.addEventListener('load', () => {

      Object.defineProperty(iframWindow.document.documentElement, 'clientHeight', {
        enumerable: true,
        configurable: false,
        get() {
          return window.document.documentElement.clientHeight
        }
      })

      Object.defineProperty(iframWindow.document.documentElement, 'clientWidth', {
        enumerable: true,
        configurable: false,
        get() {
          return window.document.documentElement.clientWidth
        }
      })

    })
  }
}

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants