我只是想捕获一个“ zoom”事件并对其做出响应(类似于window.onresize事件)。
谢谢。
#1 楼
无法主动检测是否有变焦。我在这里找到了如何实现它的好方法。我发现了两种检测
缩放级别的方法。检测缩放级别变化的一种方法取决于以下事实:百分比值未缩放。
百分比值是相对于
视口宽度的,因此不受
页面缩放的影响。如果您插入两个元素,
一个位置以百分比表示,
而一个位置相同的像素以
像素为单位,则当缩放
页面时,它们将分开。找到两个元素的位置之间的比率,然后
获得缩放级别。请参阅测试
案例。
http://web.archive.org/web/20080723161031/http://novemberborn.net/javascript/page-zoom-ff3
您也可以使用以上帖子中的工具进行操作。问题是您正在或多或少地对页面是否已缩放进行有根据的猜测。在某些浏览器中,这将比其他浏览器更好。
如果缩放时加载了页面,则无法判断页面是否已缩放。
评论
可以在主体的onload处理程序中检查size参数。奇怪的是,在调试IE8 vs. 9时,似乎主体的onresize处理函数是在IE8中传递文档的,而IE9则是传递窗口的,Chrome也是。
– Walter K
2012年8月8日在21:57
如果将两个元素放置在完全相同的位置,并且页面在缩放时加载,那么两个元素之间不会有位移吗?这不能告诉页面是否已经缩放吗?
–vijayant
17年6月27日在15:06
也是document.body.offsetWidth
–Samy Bencherif
17年7月5日在22:23
使用这样的方法在用户调整窗口大小时也会触发,那么为什么不只使用resize事件侦听器呢?在这种情况下,这也是可行的解决方案。
– hewiefreeman
17年8月19日在4:22
#2 楼
我正在使用这段JavaScript来对Zoom“事件”做出反应。它会轮询窗口宽度。
(如本页所建议(Ian Elliott链接到此页面):http:// novemberborn .net / javascript / page-zoom-ff3 [archive])
已在Chrome,Firefox 3.6和Opera(而非IE)上进行了测试。
关于Magnus的问候,
var zoomListeners = [];
(function(){
// Poll the pixel width of the window; invoke zoom listeners
// if the width has been changed.
var lastWidth = 0;
function pollZoomFireEvent() {
var widthNow = jQuery(window).width();
if (lastWidth == widthNow) return;
lastWidth = widthNow;
// Length changed, user must have zoomed, invoke listeners.
for (i = zoomListeners.length - 1; i >= 0; --i) {
zoomListeners[i]();
}
}
setInterval(pollZoomFireEvent, 100);
})();
评论
调整窗口大小的误报怎么办?
– gcb
2010-12-10 19:30
但是,当您还实现onresize处理程序时,可以过滤掉这些情况。因此,我要说的是解决方案的基础。
– Stijn de Witt
2012年11月9日12:54
@StijndeWitt在阅读本文之后,我开始理解建议的路径,现在我正在研究一种过滤掉大小调整事件的解决方案,尤其是在移动设备上。任何人?
–lowtechsun
17年1月25日,0:45
也许您可以使用间隙值来区分大小和缩放?我的意思是缩放将立即将窗口宽度更改> x像素。
–塞巴斯蒂安
17年3月23日16:00
误报是个问题,是的。通过检查宽高比是否保持不变,是否可以消除99.99%的误报?让脚本记住上一个比率并计算新比率并检查是否相同。结合宽度有所不同,您应该有一个良好的基础
– Biepbot Von Stirling
17年12月30日在12:35
#3 楼
大家好消息!更改缩放比例时,较新的浏览器将触发窗口调整大小事件。评论
适用于Android的Chrome和Firefox不会触发缩放事件。
–lowtechsun
17年1月25日在18:43
如果您不希望缩放触发大小调整事件,则这不是好消息。
– Reahreic
17年2月1日在22:26
更好的消息是与缩放事件不同的实际缩放事件。
– Vincent
17年2月15日在3:41
两者都是对的。编辑。
–本
17年9月15日在21:02
是否可以通过某种方式设置缩放?
–老男孩
19年5月18日在1:58
#4 楼
让我们定义px_ratio如下:px ratio =物理像素与css px的比率。
如果任意缩放页面,则视口pxes(px与pixel不同)减小并且应该适合屏幕因此比率(物理像素/ CSS_px)必须变大。
但是在“窗口调整大小”中,屏幕尺寸会减小,并且会降低pxes。因此比例将保持不变。
缩放:触发windows.resize事件->并更改px_ratio
,但
调整大小:触发windows.resize事件->不会更改px_ratio
//for zoom detection
px_ratio = window.devicePixelRatio || window.screen.availWidth / document.documentElement.clientWidth;
$(window).resize(function(){isZooming();});
function isZooming(){
var newPx_ratio = window.devicePixelRatio || window.screen.availWidth / document.documentElement.clientWidth;
if(newPx_ratio != px_ratio){
px_ratio = newPx_ratio;
console.log("zooming");
return true;
}else{
console.log("just resizing");
return false;
}
}
关键是CSS PX和Physical Pixel之间的区别。
https://gist.github.com/abilogos/66aba96bb0fb27ab3ed4a13245817d1e
评论
这应该是IMO接受的答案。到目前为止工作正常,谢谢!如果有人感兴趣,请将其包装到自定义事件中。gist.github.com/ souporserious / b44ea5d04c38c2e7ff32cd1912a17cd0。
–令人惊讶
19-10-15在22:01
#5 楼
这对我有用: var deviceXDPI = screen.deviceXDPI;
setInterval(function(){
if(screen.deviceXDPI != deviceXDPI){
deviceXDPI = screen.deviceXDPI;
... there was a resize ...
}
}, 500);
仅在IE8上需要。所有其他浏览器自然会生成一个调整大小事件。
#6 楼
从yonran
构建了一个漂亮的插件,可以进行检测。这是他先前在StackOverflow上回答的问题。它适用于大多数浏览器。应用程序很简单:window.onresize = function onresize() {
var r = DetectZoom.ratios();
zoomLevel.innerHTML =
"Zoom level: " + r.zoom +
(r.zoom !== r.devicePxPerCssPx
? "; device to CSS pixel ratio: " + r.devicePxPerCssPx
: "");
}
演示
评论
在Android 4.4.2的Firefox上不起作用。同样在移动版FF中,在“辅助功能”选项中勾选“始终启用缩放”按钮。该演示不会对更改做出反应。
–lowtechsun
17年1月25日在1:10
#7 楼
我想建议对以前的解决方案进行改进,以跟踪窗口宽度的变化。除了保留自己的事件侦听器数组之外,您还可以使用现有的javascript事件系统并在宽度更改时触发您自己的事件,并将事件处理程序绑定到它。$(window).bind('myZoomEvent', function() { ... });
function pollZoomFireEvent()
{
if ( ... width changed ... ) {
$(window).trigger('myZoomEvent');
}
}
/ debounce可以帮助降低处理程序的调用率。
评论
油门/去抖仅在轮询是由其他一些事件(例如鼠标移动或键入)触发时才有用。
–fuzzyTew
2011年10月15日,0:49
#8 楼
您还可以通过注入至少包含一个不可破坏空间(可能是隐藏的)的div并定期检查其高度来获取文本调整大小事件和缩放系数。如果高度发生变化,则文字大小也发生了变化((您知道多少-顺便说一句,如果窗口以全页模式缩放,这也会触发),并且您仍将获得正确的缩放系数,且高度/高度比例)。#9 楼
<script>
var zoomv = function() {
if(topRightqs.style.width=='200px){
alert ("zoom");
}
};
zoomv();
</script>
#10 楼
在iOS 10上,可以将事件侦听器添加到touchmove
事件,并检测页面是否被当前事件放大。 var prevZoomFactorX;
var prevZoomFactorY;
element.addEventListener("touchmove", (ev) => {
let zoomFactorX = document.documentElement.clientWidth / window.innerWidth;
let zoomFactorY = document.documentElement.clientHeight / window.innerHeight;
let pageHasZoom = !(zoomFactorX === 1 && zoomFactorY === 1);
if(pageHasZoom) {
// page is zoomed
if(zoomFactorX !== prevZoomFactorX || zoomFactorY !== prevZoomFactorY) {
// page is zoomed with this event
}
}
prevZoomFactorX = zoomFactorX;
prevZoomFactorY = zoomFactorY;
});
#11 楼
尽管这是一个有9年历史的问题,但问题仍然存在!我在检测缩放时不排除项目的缩放,所以我编辑了代码以使其能够同时检测缩放和缩放。它在大多数情况下都有效,因此,如果大多数都对您的项目足够好,那么这应该会有所帮助!到目前为止,它可以检测到100%的缩放比例。唯一的问题是,如果用户发疯(即对窗口进行大小调整)或窗口滞后,则可能会以缩放而不是窗口大小的方式触发。
通过检测
window.outerWidth
的变化来工作或window.outerHeight
作为窗口调整大小,同时检测到window.innerWidth
或window.innerHeight
的变化与窗口调整为缩放无关。 //init object to store window properties
var windowSize = {
w: window.outerWidth,
h: window.outerHeight,
iw: window.innerWidth,
ih: window.innerHeight
};
window.addEventListener("resize", function() {
//if window resizes
if (window.outerWidth !== windowSize.w || window.outerHeight !== windowSize.h) {
windowSize.w = window.outerWidth; // update object with current window properties
windowSize.h = window.outerHeight;
windowSize.iw = window.innerWidth;
windowSize.ih = window.innerHeight;
console.log("you're resizing"); //output
}
//if the window doesn't resize but the content inside does by + or - 5%
else if (window.innerWidth + window.innerWidth * .05 < windowSize.iw ||
window.innerWidth - window.innerWidth * .05 > windowSize.iw) {
console.log("you're zooming")
windowSize.iw = window.innerWidth;
}
}, false);
注意:我的解决方案类似于KajMagnus的解决方案,但这对我来说效果更好。
评论
我不会投反对票,因为我可以看到您有一个可行的解决方案,并且我了解您的代码可以执行的操作,但是我建议您在没有提供充分说明的情况下,建议使用诸如0.05之类的幻数。 ;-)例如,我知道在Chrome中,无论如何,浏览器在任何情况下都会缩放的最小量为10%,但尚不清楚其他浏览器是否如此。供您参考,始终确保您的代码已经过测试,并准备捍卫或改进它。
– Nolo
18-10-21在14:24
有趣的方法
–老男孩
19年5月18日在2:04
#12 楼
这是一个干净的解决方案: // polyfill window.devicePixelRatio for IE
if(!window.devicePixelRatio){
Object.defineProperty(window,'devicePixelRatio',{
enumerable: true,
configurable: true,
get:function(){
return screen.deviceXDPI/screen.logicalXDPI;
}
});
}
var oldValue=window.devicePixelRatio;
window.addEventListener('resize',function(e){
var newValue=window.devicePixelRatio;
if(newValue!==oldValue){
// TODO polyfill CustomEvent for IE
var event=new CustomEvent('devicepixelratiochange');
event.oldValue=oldValue;
event.newValue=newValue;
oldValue=newValue;
window.dispatchEvent(event);
}
});
window.addEventListener('devicepixelratiochange',function(e){
console.log('devicePixelRatio changed from '+e.oldValue+' to '+e.newValue);
});
评论
这似乎是一个非常不错的解决方案,并且使用代理服务器,您甚至都不需要使用拦截器破坏寡妇属性-我们是否确定更新DPR是用户缩放后所有浏览器都应该/应该做的事情? er ..刮掉这个主意-窗口无法被代理,也许存在使用“ matchMedia”的解决方案,但是由于这是对/错的事情,所以我不确定如何测试模拟值的变化DPR ...
– Jon z
3月11日15:47
#13 楼
通过将事件附加到window
,然后读取body
或其他元素(例如,带有(.getBoundingClientRect())的元素)的值,调整大小事件在现代浏览器上可以工作。 在某些早期的浏览器中,可以在任何HTML元素上注册调整大小事件处理程序。仍然可以设置onresize
属性或使用addEventListener()在任何元素上设置处理程序。
但是,调整大小事件仅在窗口对象上触发(即,文档返回的
)。默认视图)。只有在
窗口对象上注册的处理程序将接收调整大小事件。
window.addEventListener("resize", getSizes, false)
function getSizes(){
let body = document.body
console.log(body.clientWidth +"px x "+ body.clientHeight + "px")
}
另一个替代方法:ResizeObserver API
根据您的布局,您可以注意调整特定元素的大小。
此在“响应式”布局上效果很好,因为缩放时容器框的大小会调整。
function watchBoxchange(e){
// console.log(e[0].contentBoxSize.inlineSize+" "+e[0].contentBoxSize.blockSize)
info.textContent = e[0].contentBoxSize.inlineSize+" * "+e[0].contentBoxSize.blockSize + "px"
}
new ResizeObserver(watchBoxchange).observe(fluid)
#fluid {
width: 200px;
height:100px;
overflow: auto;
resize: both;
border: 3px black solid;
display: flex;
flex-direction: column;
justify-content: center;
align-items: center;
font-size: 8vh
}
<div id="fluid">
<info id="info"></info>
</div>
请注意不要使用户手势事件中的javascript任务超载。需要重绘时,请使用requestAnimationFrame。
#14 楼
根据MDN的说法,“ matchMedia”是执行此操作的正确方法https://developer.mozilla.org/zh-CN/docs/Web/API/Window/devicePixelRatio#Monitoring_screen_resolution_or_zoom_level_changes有点有点挑剔,因为每个实例一次只能观看一个MQ,因此,如果您对任何缩放级别更改感兴趣,则需要进行一系列匹配。.但是由于浏览器负责发出事件,因此它的性能可能更高而不是轮询,您可以限制或取消回调的回调,或者将其固定到动画帧或其他内容-这是一个看起来非常敏捷的实现,可以随意切换_throttle或如果您已经依赖它的话。
运行代码片段并在浏览器中放大和缩小,注意标记中的更新值-我仅在Firefox中进行了测试!莱姆知道您是否发现任何问题。
const el = document.querySelector('#dppx')
if ('matchMedia' in window) {
function observeZoom(cb, opts) {
opts = {
// first pass for defaults - range and granularity to capture all the zoom levels in desktop firefox
ceiling: 3,
floor: 0.3,
granularity: 0.05,
...opts
}
const precision = `${opts.granularity}`.split('.')[1].length
let val = opts.floor
const vals = []
while (val <= opts.ceiling) {
vals.push(val)
val = parseFloat((val + opts.granularity).toFixed(precision))
}
// construct a number of mediamatchers and assign CB to all of them
const mqls = vals.map(v => matchMedia(`(min-resolution: ${v}dppx)`))
// poor person's throttle
const throttle = 3
let last = performance.now()
mqls.forEach(mql => mql.addListener(function() {
console.debug(this, arguments)
const now = performance.now()
if (now - last > throttle) {
cb()
last = now
}
}))
}
observeZoom(function() {
el.innerText = window.devicePixelRatio
})
} else {
el.innerText = 'unable to observe zoom level changes, matchMedia is not supported'
}
<div id='dppx'>--</div>
#15 楼
这是一种本机方式(主要框架无法放大Chrome,因为它们不支持被动事件行为)。
//For Google Chrome
document.addEventListener("mousewheel", event => {
console.log(`wheel`);
if(event.ctrlKey == true)
{
event.preventDefault();
if(event.deltaY > 0) {
console.log('Down');
}else {
console.log('Up');
}
}
}, { passive: false });
// For Mozilla Firefox
document.addEventListener("DOMMouseScroll", event => {
console.log(`wheel`);
if(event.ctrlKey == true)
{
event.preventDefault();
if(event.detail > 0) {
console.log('Down');
}else {
console.log('Up');
}
}
}, { passive: false });
#16 楼
我正在回复一个3岁的链接,但我想这是一个更可接受的答案,将.css文件创建为,
@media screen and (max-width: 1000px)
{
// things you want to trigger when the screen is zoomed
}
EG:-
@media screen and (max-width: 1000px)
{
.classname
{
font-size:10px;
}
}
当屏幕缩放到大约125%时,上述代码使字体的大小为'10px'。您可以通过更改“ 1000px”的值来检查不同的缩放级别。
评论
最大宽度和缩放比例之间有什么关系?
–seebiscuit
16年1月11日在22:56
该代码将在每个<1000px屏幕上执行,与缩放无关
– Artur Stary
16-2-17在9:52
@ArturStary无法检测浏览器是否已缩放,但是有许多解决方法,其中之一就是我在回答中提到的方法。此外,我确实说过您可以更改1000px的值以检查不同的屏幕尺寸,这会产生不同的缩放级别
–索米尔
16年2月17日在20:58
评论
我相信较新的浏览器在页面缩放时会触发onresize事件。我有一个类似的问题,但我不仅想知道何时更改缩放,还想知道页面加载时缩放的值。
真的不是重复的。这里的问题是关于捕获事件,而不是确定缩放级别。
@epascarello-是的,但这不会使我的评论无效
我想确认一下在最新的浏览器中是否发生“大小调整”。到目前为止,我看到最新的Chrome(33),FF(28),IE(在第9模式下为11和11)在放大或缩小时都可以正确触发事件。