ant-design-vue
ant-design-vue copied to clipboard
detectZoom设置body的style.zoom自适应适配,下拉选择,日期选择等相关选择控件偏移
- [ ] 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?
下拉选择,日期选择等相关选择控件位置正常显示,不要偏移
我也是这个问题, 谷歌128版本 css:zoom 有个变化
我也是的, 不知道是浏览器的bug, 还是有了新的标准
大佬们有解法了么?
俺也一样 目前临时的解决方案是 判断浏览器版本 大于等于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的把组件的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定位都不准
俺也一样 目前临时的解决方案是 判断浏览器版本 大于等于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下面得元素试试呢
俺也一样 目前临时的解决方案是 判断浏览器版本 大于等于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更新 人都麻了
俺也一样 目前临时的解决方案是 判断浏览器版本 大于等于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下面得元素试试呢
醍醐灌顶!
俺也一样 目前临时的解决方案是 判断浏览器版本 大于等于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,滚动的时候是不是就不跟随父元素了
俺也一样 目前临时的解决方案是 判断浏览器版本 大于等于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,滚动的时候是不是就不跟随父元素了
是的 这个只能说是个临时的办法
俺也一样 目前临时的解决方案是 判断浏览器版本 大于等于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是在对应组件上配置的,还是全局设置的?
俺也一样 目前临时的解决方案是 判断浏览器版本 大于等于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是在对应组件上配置的,还是全局设置的?方便贴一下具体的代码吗?
俺也一样 目前临时的解决方案是 判断浏览器版本 大于等于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配置是在单个组件上配置?还是全局配置呢?是否方便贴一下对应设置片段的代码呢?
俺也一样 目前临时的解决方案是 判断浏览器版本 大于等于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
俺也一样 目前临时的解决方案是 判断浏览器版本 大于等于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。
遇到同样的场景,看来是浏览器标准变化
同样的给body设置了zoom所有悬浮弹窗都发生偏移了
俺也一样 目前临时的解决方案是 判断浏览器版本 大于等于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节点位置会导致样式问题
俺也一样 目前临时的解决方案是 判断浏览器版本 大于等于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了
监听窗口变化每次缩放的时候执行这个方法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;
};
}
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