Skip to content

Instantly share code, notes, and snippets.

@sunzsh
Created December 29, 2023 15:37
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save sunzsh/f69f6cd010c07964e09d3ea0bdd939ae to your computer and use it in GitHub Desktop.
Save sunzsh/f69f6cd010c07964e09d3ea0bdd939ae to your computer and use it in GitHub Desktop.
解决代码修改了网页zoom导致各种popover错位的问题(适配vue2+elementUI)
export default {
install(Vue) {
const delegates = {
'el-select': (component, element) => {
return [component.$refs.reference.$el]
},
'el-pagination': (component, element) => {
const sizesComponent = component.$children.find((child) => child.$options._componentTag === 'sizes');
const eles_ElSelectInSizes = delegates['el-select'](sizesComponent.$children[0], element);
return eles_ElSelectInSizes;
}
}
const getRefEles = (component, element) => {
const tagName = component.$options._componentTag;
const delegate = delegates[tagName];
console.log(`TagName for fix-zoom : ${ tagName }`);
return delegate ? delegate(component, element) : [element]; // 默认返回当前元素
}
Vue.directive('fixZoom', {
inserted: function(element, binding, vnode) {
const refEles = getRefEles(vnode.componentInstance, element);
if (!refEles) {
return;
}
refEles.forEach((refEle) => {
refEle.getBoundingClientRectBak = refEle.getBoundingClientRect;
refEle.getBoundingClientRect = function () {
const rect = refEle.getBoundingClientRectBak()
var zoom = window.getComputedStyle(document.body).zoom
var scrollTop = document.documentElement.scrollTop;
var scrollLeft = document.documentElement.scrollLeft;
var offsetScrollTop = scrollTop - (scrollTop / zoom);
var offsetScrollLeft = scrollLeft - (scrollLeft / zoom);
return new DOMRect(rect.x - offsetScrollLeft, rect.y - offsetScrollTop, rect.width, rect.height);
}
})
}
})
}
};
@boringtu
Copy link

boringtu commented Feb 23, 2024

亲测无效,我猜这段代码应该从来没有生效过。。[doge]
你这段代码里,跟zoom有关联关系的只有scrollTopscrollLeft,就算没这段代码,在页面左半边的下拉也是能正常显示的,只不过右半边就会错位,但你这段代码并没有解决这个问题。。
我刚在源码里debug查到问题了,因为走到了 popper.js 里为了确保 popper 不会从其边界溢出的 Popper.prototype.modifiers.preventOverflow 这个方法里,右半边的下拉就会走到function right里,然后就会发现走进了这个if里:popper.right > data.boundaries.right,然后就会查到 data.boundaries.right 的值,是根据 document.documentElement.clientWidth 得到的,而 document.documentElement.clientWidth 的值是缩放之前的宽度,与zoom无关。所以,解决方案就是重写 Popper.prototype._getBoundaries,把里面跟 document.documentElement.clientWidthdocument.documentElement.clientHeight 改掉即可,亲测有效~

刚刚我在我这边共享了解决方案的文件,有兴趣的可以参考一下(顺便还研究了一下怎么在 gist 上发布内容~)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment