在 HTML 网站上,您有一个像这样的固定元素:
<div id="fixed">
<p>Some content</p>
</div>
它有这个CSS:
#fixed { height:150px; position:fixed; top:0; left:0; z-index:10000; }
当您在移动设备(或任何支持触摸屏的设备)上查看此页面并捏合屏幕进行放大时,固定元素会与所有其他内容一起放大(它会变大)。当您放大得足够远时,它会变得如此之大,几乎完全覆盖其下方的所有内容。
一个实际的用例是一个 UI,比如顶部的固定导航栏,或屏幕角落的浮动按钮。
如何防止单个元素在浏览器中调整大小,并使其始终保持相同的大小?
演示此答案
我根据这个答案编写的对话框小部件库。
对话框小部件的演示在移动设备上尝试,缩放并点击链接。
虽然手势事件似乎保存了一些关于“某物”的比例因子的元数据,但我们可能最好控制并手动找到它。由于我们希望在用户实时移动时保持效果,因此我们需要在每个滚动事件期间重新计算。
window.addEventListener('scroll', function(e){ /* coming next */ })
我们计算缩放系数并将其作为 CSS3 变换应用于重新缩放的元素:
el.style["transform"] = "scale(" + window.innerWidth/document.documentElement.clientWidth + ")";
这会将元素重新缩放回相对于当前视口缩放比例的缩放 1,但它可能仍然错误地放置在页面上。这意味着我们必须为其位置获取新值。屏幕上实际发生的情况取决于元素的 CSS 位置值,
fixed
的行为与
absolute
不同,特别是在移动 Safari 上,fixed
位置在页面缩放时具有附加的平滑效果,这会产生一些由于这个原因带来的不便问题 - 我建议将 100% 内容高度元素作为您想要缩放的元素的 relative
父元素,然后在脚本中,将元素 absolute
放置在父元素内部。以下值适用于此示例演示:overlay.style.left = window.pageXOffset + 'px';
overlay.style.bottom = document.documentElement.clientHeight - (window.pageYOffset + window.innerHeight) + 'px';
您可能还需要注意使用
transform-origin
CSS 属性,具体取决于您希望缩放从哪个锚点生效 - 这对对齐有直接影响。
1.禁用视口标签中的缩放:
<meta name="viewport" content="user-scalable=no, initial-scale=1, maximum-scale=1, minimum-scale=1" />
2.使用诸如 TouchSwipe.js 之类的插件:https://github.com/mattbryson/TouchSwipe-Jquery-Plugin
我的页面上有 2 个 div(左和右),左侧 div 有一个固定的滚动菜单,右侧有小文本和图像。我想要捏/缩放并且只有正确的 div 缩放,以便用户可以在必要时更好地阅读文本。我没有让整个视口可缩放并禁用左侧 div 的缩放,而是完全相反:通过 TouchSwipe 插件仅使右侧 div 可缩放。
如果有人对我如何实现 TouchSwipe 插件感兴趣,我将在完成后分享我的代码。
resize
事件或各种特定于触摸的 API,但对我来说最有效的是
wheel
事件。它可以跨浏览器工作,但有一点延迟,尽管它在 Safari 中不可靠。告诉您屏幕放大部分的边缘。
#pinned {
position: fixed;
bottom: 0px;
left: 0px;
right: 0px;
width: 100%;
height: 35px;
transform-origin: 0% 100%;
text-align: center;
}
const pinnedElement = document.getElementById('pinned');
const elementHeight = pinnedElement.getBoundingClientRect().height;
const viewport = window.visualViewport;
document.addEventListener('wheel', function(e) {
const elementTop = (viewport.offsetTop + viewport.height - elementHeight);
pinnedElement.style.top = elementTop + 'px';
pinnedElement.style.bottom = elementTop + elementHeight + 'px';
pinnedElement.style.left = viewport.offsetLeft + 'px';
pinnedElement.style.transform = `scale(${1/viewport.scale})`;
});
#fixed { height:150px; width: 200px; max-width: 200px; max-height: 150px; position:fixed; top:0; left:0; z-index:10000; }