ant-design-vue icon indicating copy to clipboard operation
ant-design-vue copied to clipboard

detectZoom设置body的style.zoom自适应适配,下拉选择,日期选择等相关选择控件偏移

Open WhatXiao opened this issue 1 year ago • 21 comments
trafficstars

  • [ ] I have searched the issues of this repository and believe that this is not a duplicate.

Version

undefined

Environment

Reproduction link

https://www.jb51.net/article/267677.htm

Steps to reproduce

无地址

What is expected?

export const detectZoom = () => { let ratio = 0, screen = window.screen, ua = navigator.userAgent.toLowerCase(); if (window.devicePixelRatio !== undefined) { ratio = window.devicePixelRatio; } else if (~ua.indexOf("msie")) { if (screen.deviceXDPI && screen.logicalXDPI) { ratio = screen.deviceXDPI / screen.logicalXDPI; } } else if ( window.outerWidth !== undefined && window.innerWidth !== undefined ) { ratio = window.outerWidth / window.innerWidth; } if (ratio) { ratio = Math.round(ratio * 100); } return ratio; }; // 屏幕自适应适配 import { detectZoom } from "/@/utils/detectZoom.js"; const m = detectZoom(); document.body.style.zoom = String((window.screen.width * (m / 100) / 1920) * (100 / Number(m)))

电脑控制面板-显示设置-缩放与布局为150%,在谷歌浏览器128版本下页面正常显示,但下拉选择,日期选择等相关选择控件弹出位置偏移错乱。

What is actually happening?

下拉选择,日期选择等相关选择控件位置正常显示,不要偏移

WhatXiao avatar Aug 27 '24 10:08 WhatXiao

N7IWSF%6}5D00~BNZ}KK1BW

WhatXiao avatar Aug 27 '24 10:08 WhatXiao

~2`A4GO868I~71~~BFX7DSP

O2~{3DJN{FG9PB{6)M7W06B WD( GH7){Y1X3YI9N2B%54T

WhatXiao avatar Aug 27 '24 10:08 WhatXiao

我也是这个问题, 谷歌128版本 css:zoom 有个变化

studyisnotsimple avatar Aug 28 '24 09:08 studyisnotsimple

我也是的, 不知道是浏览器的bug, 还是有了新的标准

WinFred2016 avatar Aug 28 '24 13:08 WinFred2016

大佬们有解法了么?

Benjaminbai avatar Aug 29 '24 03:08 Benjaminbai

俺也一样 目前临时的解决方案是 判断浏览器版本 大于等于128的把组件的getPopupContainer绑定到body上,小于128继续不变绑定到父元素上

function getPopupContainer(triggerNode) {
  const userAgent = navigator.userAgent;
  const index = userAgent.indexOf('Chrome/')
  const chromeVersion = userAgent.substring(index + 7);
  const versionParts = chromeVersion.split(' ');
  const majorVersion = parseInt(versionParts[0], 10);

  if (index > -1 && majorVersion >= 128) {
    return document.body
  }
  return triggerNode.parentNode
}

yaokaiqd avatar Aug 29 '24 08:08 yaokaiqd

俺也一样 目前临时的解决方案是 判断浏览器版本 大于等于128的把组件的getPopupContainer绑定到body上,小于128继续不变绑定到父元素上

function getPopupContainer(triggerNode) {
  const userAgent = navigator.userAgent;
  const index = userAgent.indexOf('Chrome/')
  const chromeVersion = userAgent.substring(index + 7);
  const versionParts = chromeVersion.split(' ');
  const majorVersion = parseInt(versionParts[0], 10);

  if (index > -1 && majorVersion >= 128) {
    return document.body
  }
  return triggerNode.parentNode
}

我遇到的是128上,zoom了之后,getPopupContainer绑定到body和parentNode定位都不准

Benjaminbai avatar Aug 29 '24 09:08 Benjaminbai

俺也一样 目前临时的解决方案是 判断浏览器版本 大于等于128的把组件的getPopupContainer绑定到body上,小于128继续不变绑定到父元素上

function getPopupContainer(triggerNode) {
  const userAgent = navigator.userAgent;
  const index = userAgent.indexOf('Chrome/')
  const chromeVersion = userAgent.substring(index + 7);
  const versionParts = chromeVersion.split(' ');
  const majorVersion = parseInt(versionParts[0], 10);

  if (index > -1 && majorVersion >= 128) {
    return document.body
  }
  return triggerNode.parentNode
}

我遇到的是128上,zoom了之后,getPopupContainer绑定到body和parentNode定位都不准

是不是你们的zoom绑定到body上了?把zoom绑定到body下面得元素试试呢

yaokaiqd avatar Aug 29 '24 09:08 yaokaiqd

俺也一样 目前临时的解决方案是 判断浏览器版本 大于等于128的把组件的getPopupContainer绑定到body上,小于128继续不变绑定到父元素上

function getPopupContainer(triggerNode) {
  const userAgent = navigator.userAgent;
  const index = userAgent.indexOf('Chrome/')
  const chromeVersion = userAgent.substring(index + 7);
  const versionParts = chromeVersion.split(' ');
  const majorVersion = parseInt(versionParts[0], 10);

  if (index > -1 && majorVersion >= 128) {
    return document.body
  }
  return triggerNode.parentNode
}

试了下,可以,,感谢~~ 谷歌128更新 人都麻了

studyisnotsimple avatar Aug 29 '24 09:08 studyisnotsimple

俺也一样 目前临时的解决方案是 判断浏览器版本 大于等于128的把组件的getPopupContainer绑定到body上,小于128继续不变绑定到父元素上

function getPopupContainer(triggerNode) {
  const userAgent = navigator.userAgent;
  const index = userAgent.indexOf('Chrome/')
  const chromeVersion = userAgent.substring(index + 7);
  const versionParts = chromeVersion.split(' ');
  const majorVersion = parseInt(versionParts[0], 10);

  if (index > -1 && majorVersion >= 128) {
    return document.body
  }
  return triggerNode.parentNode
}

我遇到的是128上,zoom了之后,getPopupContainer绑定到body和parentNode定位都不准

是不是你们的zoom绑定到body上了?把zoom绑定到body下面得元素试试呢

醍醐灌顶!

Benjaminbai avatar Aug 29 '24 09:08 Benjaminbai

俺也一样 目前临时的解决方案是 判断浏览器版本 大于等于128的把组件的getPopupContainer绑定到body上,小于128继续不变绑定到父元素上

function getPopupContainer(triggerNode) {
  const userAgent = navigator.userAgent;
  const index = userAgent.indexOf('Chrome/')
  const chromeVersion = userAgent.substring(index + 7);
  const versionParts = chromeVersion.split(' ');
  const majorVersion = parseInt(versionParts[0], 10);

  if (index > -1 && majorVersion >= 128) {
    return document.body
  }
  return triggerNode.parentNode
}

我遇到的是128上,zoom了之后,getPopupContainer绑定到body和parentNode定位都不准

是不是你们的zoom绑定到body上了?把zoom绑定到body下面得元素试试呢

醍醐灌顶!

不过这样绑定到body,滚动的时候是不是就不跟随父元素了

Benjaminbai avatar Aug 29 '24 09:08 Benjaminbai

俺也一样 目前临时的解决方案是 判断浏览器版本 大于等于128的把组件的getPopupContainer绑定到body上,小于128继续不变绑定到父元素上

function getPopupContainer(triggerNode) {
  const userAgent = navigator.userAgent;
  const index = userAgent.indexOf('Chrome/')
  const chromeVersion = userAgent.substring(index + 7);
  const versionParts = chromeVersion.split(' ');
  const majorVersion = parseInt(versionParts[0], 10);

  if (index > -1 && majorVersion >= 128) {
    return document.body
  }
  return triggerNode.parentNode
}

我遇到的是128上,zoom了之后,getPopupContainer绑定到body和parentNode定位都不准

是不是你们的zoom绑定到body上了?把zoom绑定到body下面得元素试试呢

醍醐灌顶!

不过这样绑定到body,滚动的时候是不是就不跟随父元素了

是的 这个只能说是个临时的办法

yaokaiqd avatar Aug 29 '24 11:08 yaokaiqd

俺也一样 目前临时的解决方案是 判断浏览器版本 大于等于128的把组件的getPopupContainer绑定到body上,小于128继续不变绑定到父元素上

function getPopupContainer(triggerNode) {
  const userAgent = navigator.userAgent;
  const index = userAgent.indexOf('Chrome/')
  const chromeVersion = userAgent.substring(index + 7);
  const versionParts = chromeVersion.split(' ');
  const majorVersion = parseInt(versionParts[0], 10);

  if (index > -1 && majorVersion >= 128) {
    return document.body
  }
  return triggerNode.parentNode
}

我遇到的是128上,zoom了之后,getPopupContainer绑定到body和parentNode定位都不准

是不是你们的zoom绑定到body上了?把zoom绑定到body下面得元素试试呢

醍醐灌顶!

请问你绑定到下面元素可以了吗?设置getgetPopupContainer是在对应组件上配置的,还是全局设置的?

WhatXiao avatar Aug 29 '24 12:08 WhatXiao

俺也一样 目前临时的解决方案是 判断浏览器版本 大于等于128的把组件的getPopupContainer绑定到body上,小于128继续不变绑定到父元素上

function getPopupContainer(triggerNode) {
  const userAgent = navigator.userAgent;
  const index = userAgent.indexOf('Chrome/')
  const chromeVersion = userAgent.substring(index + 7);
  const versionParts = chromeVersion.split(' ');
  const majorVersion = parseInt(versionParts[0], 10);

  if (index > -1 && majorVersion >= 128) {
    return document.body
  }
  return triggerNode.parentNode
}

试了下,可以,,感谢~~ 谷歌128更新 人都麻了

设置getgetPopupContainer是在对应组件上配置的,还是全局设置的?方便贴一下具体的代码吗?

WhatXiao avatar Aug 29 '24 12:08 WhatXiao

俺也一样 目前临时的解决方案是 判断浏览器版本 大于等于128的把组件的getPopupContainer绑定到body上,小于128继续不变绑定到父元素上

function getPopupContainer(triggerNode) {
  const userAgent = navigator.userAgent;
  const index = userAgent.indexOf('Chrome/')
  const chromeVersion = userAgent.substring(index + 7);
  const versionParts = chromeVersion.split(' ');
  const majorVersion = parseInt(versionParts[0], 10);

  if (index > -1 && majorVersion >= 128) {
    return document.body
  }
  return triggerNode.parentNode
}

我遇到的是128上,zoom了之后,getPopupContainer绑定到body和parentNode定位都不准

是不是你们的zoom绑定到body上了?把zoom绑定到body下面得元素试试呢

一定要要把zoom设置到body下一级上吗?getPopupContainer配置是在单个组件上配置?还是全局配置呢?是否方便贴一下对应设置片段的代码呢?

WhatXiao avatar Aug 29 '24 13:08 WhatXiao

俺也一样 目前临时的解决方案是 判断浏览器版本 大于等于128的把组件的getPopupContainer绑定到body上,小于128继续不变绑定到父元素上

function getPopupContainer(triggerNode) {
  const userAgent = navigator.userAgent;
  const index = userAgent.indexOf('Chrome/')
  const chromeVersion = userAgent.substring(index + 7);
  const versionParts = chromeVersion.split(' ');
  const majorVersion = parseInt(versionParts[0], 10);

  if (index > -1 && majorVersion >= 128) {
    return document.body
  }
  return triggerNode.parentNode
}

我遇到的是128上,zoom了之后,getPopupContainer绑定到body和parentNode定位都不准

是不是你们的zoom绑定到body上了?把zoom绑定到body下面得元素试试呢

醍醐灌顶!

请问你绑定到下面元素可以了吗?设置getgetPopupContainer是在对应组件上配置的,还是全局设置的?

我还没试,理论上应该是可以的,只不过要给每个select添加getPopupContainer,比较麻烦,最优方案我觉的还是不使用zoom

Benjaminbai avatar Aug 30 '24 03:08 Benjaminbai

俺也一样 目前临时的解决方案是 判断浏览器版本 大于等于128的把组件的getPopupContainer绑定到body上,小于128继续不变绑定到父元素上

function getPopupContainer(triggerNode) {
  const userAgent = navigator.userAgent;
  const index = userAgent.indexOf('Chrome/')
  const chromeVersion = userAgent.substring(index + 7);
  const versionParts = chromeVersion.split(' ');
  const majorVersion = parseInt(versionParts[0], 10);

  if (index > -1 && majorVersion >= 128) {
    return document.body
  }
  return triggerNode.parentNode
}

试了下,可以,,感谢~~ 谷歌128更新 人都麻了

设置getgetPopupContainer是在对应组件上配置的,还是全局设置的?方便贴一下具体的代码吗?

我是在每个组件上写的,有的默认就是body。

studyisnotsimple avatar Aug 30 '24 07:08 studyisnotsimple

遇到同样的场景,看来是浏览器标准变化

Eastboat avatar Aug 30 '24 10:08 Eastboat

同样的给body设置了zoom所有悬浮弹窗都发生偏移了

lingfeng123z avatar Aug 30 '24 11:08 lingfeng123z

俺也一样 目前临时的解决方案是 判断浏览器版本 大于等于128的把组件的getPopupContainer绑定到body上,小于128继续不变绑定到父元素上

function getPopupContainer(triggerNode) {
  const userAgent = navigator.userAgent;
  const index = userAgent.indexOf('Chrome/')
  const chromeVersion = userAgent.substring(index + 7);
  const versionParts = chromeVersion.split(' ');
  const majorVersion = parseInt(versionParts[0], 10);

  if (index > -1 && majorVersion >= 128) {
    return document.body
  }
  return triggerNode.parentNode
}

我们的css样式做了大量定制 这样改变dom节点位置会导致样式问题

AkonXI avatar Sep 11 '24 06:09 AkonXI

俺也一样 目前临时的解决方案是 判断浏览器版本 大于等于128的把组件的getPopupContainer绑定到body上,小于128继续不变绑定到父元素上

function getPopupContainer(triggerNode) {
  const userAgent = navigator.userAgent;
  const index = userAgent.indexOf('Chrome/')
  const chromeVersion = userAgent.substring(index + 7);
  const versionParts = chromeVersion.split(' ');
  const majorVersion = parseInt(versionParts[0], 10);

  if (index > -1 && majorVersion >= 128) {
    return document.body
  }
  return triggerNode.parentNode
}

我遇到的是128上,zoom了之后,getPopupContainer绑定到body和parentNode定位都不准

是不是你们的zoom绑定到body上了?把zoom绑定到body下面得元素试试呢

醍醐灌顶!

请问你绑定到下面元素可以了吗?设置getgetPopupContainer是在对应组件上配置的,还是全局设置的?

我还没试,理论上应该是可以的,只不过要给每个select添加getPopupContainer,比较麻烦,最优方案我觉的还是不使用zoom

zoom现在还是不可替代的 想要在同等物理屏幕上显示一致且不能用相对单位的时候 就必须用zoom了

AkonXI avatar Sep 11 '24 06:09 AkonXI

监听窗口变化每次缩放的时候执行这个方法handleResize, 来改变元素的属性,原生getBoundingClientRect是会叠加的,所以每次传进去的zoom比例要计算好达到初始化的值的缩放效果,计算好这个x即可,比如: 100(元素宽度) / 0.8(zoom) = 125(元素宽度) 100(元素宽度) / 0.5(zoom) = 200(元素宽度) 这个是我们想要的一个比例,目前就是 100(元素宽度) / 0.8(zoom) = 125(元素宽度) 125(元素宽度) / 0.5(zoom) / x = 200(元素宽度) 目前效果可以解决这个情况

App.vue

import { zoomPlugin } from './utils/zoomPlugin';
let zoom = (1 - (1920 - window.innerWidth) / 1920);
onMounted(() => {
 window.addEventListener('resize', handleResize);
 autoSelf();
})
const oldZoom = {
 value:1
};
const handleResize = () => {
 autoSelf();
};
const autoSelf = ()=> {
 let screenWidth: any = window.innerWidth;

 if (screenWidth < 1024) {
  screenWidth = 1024;
 } else if (screenWidth > 1920) {
  screenWidth = 1920;
 }
 zoom = (1 - (1920 - screenWidth) / 1920);
 zoomPlugin(zoom,oldZoom.value);
 oldZoom.value = zoom;
 (document).body.style.zoom = (1 - (1920 - screenWidth) / 1920) * 100 + '%';
}

zoomPlugin.ts

const isChromeHighVersion = () => {
const ua = navigator.userAgent.toLowerCase();
const chromeIndex = ua.indexOf("chrome");
if (chromeIndex > -1) {
const version = ua.substring(chromeIndex + 7);
const majorVersion = parseInt(version.split(".")[0], 10);
return majorVersion > 127;
}
return false;
};

export function zoomPlugin(newZoom: number, currentZoom: number) {
const originalGetBoundingClientRect = Element.prototype.getBoundingClientRect;

if (!isChromeHighVersion()) {
return;
}

// 计算累积缩放比例
const cumulativeZoom = currentZoom / newZoom;

Element.prototype.getBoundingClientRect = function (this: Element) {
const rect = originalGetBoundingClientRect.call(this);
const newRect = new DOMRect(
      rect.x * cumulativeZoom,
      rect.y * cumulativeZoom,
      rect.width * cumulativeZoom,
      rect.height * cumulativeZoom
    );
    return newRect;
  };
}

songdengwei avatar Oct 24 '24 10:10 songdengwei

This issue is stale because it has been open 60 days with no activity. Remove stale label or comment or this will be closed in 7 days

github-actions[bot] avatar Dec 24 '24 02:12 github-actions[bot]