惯性聚合 高效追踪和阅读你感兴趣的博客、新闻、科技资讯
阅读原文 在惯性聚合中打开

推荐订阅源

S
Secure Thoughts
Spread Privacy
Spread Privacy
S
Securelist
D
Darknet – Hacking Tools, Hacker News & Cyber Security
Project Zero
Project Zero
G
GRAHAM CLULEY
Stack Overflow Blog
Stack Overflow Blog
爱范儿
爱范儿
Scott Helme
Scott Helme
S
Security Affairs
freeCodeCamp Programming Tutorials: Python, JavaScript, Git & More
博客园_首页
Exploit-DB.com RSS Feed
Exploit-DB.com RSS Feed
T
The Exploit Database - CXSecurity.com
The Hacker News
The Hacker News
雷峰网
雷峰网
N
News and Events Feed by Topic
宝玉的分享
宝玉的分享
O
OpenAI News
小众软件
小众软件
C
Cybersecurity and Infrastructure Security Agency CISA
奇客Solidot–传递最新科技情报
奇客Solidot–传递最新科技情报
V
Visual Studio Blog
I
Intezer
Martin Fowler
Martin Fowler
S
Security @ Cisco Blogs
A
Arctic Wolf
Engineering at Meta
Engineering at Meta
U
Unit 42
L
Lohrmann on Cybersecurity
Google Online Security Blog
Google Online Security Blog
Last Week in AI
Last Week in AI
T
Threat Research - Cisco Blogs
WordPress大学
WordPress大学
M
MIT News - Artificial intelligence
Schneier on Security
Schneier on Security
V2EX - 技术
V2EX - 技术
IT之家
IT之家
The Register - Security
The Register - Security
T
Tailwind CSS Blog
GbyAI
GbyAI
量子位
人人都是产品经理
人人都是产品经理
Recorded Future
Recorded Future
W
WeLiveSecurity
AWS News Blog
AWS News Blog
B
Blog RSS Feed
腾讯CDC
Hacker News - Newest:
Hacker News - Newest: "LLM"
Microsoft Security Blog
Microsoft Security Blog

张鑫旭-鑫空间-鑫生活

1分钟速度了解text-align match-parent声明 « 张鑫旭-鑫空间-鑫生活 光标的形状也能设置了,就是CSS caret-shape属性 « 张鑫旭-鑫空间-鑫生活 pretext与文字四面环绕效果的实现 « 张鑫旭-鑫空间-鑫生活 JSON.rawJSON方法的作用是什么? « 张鑫旭-鑫空间-鑫生活 如何使用CSS判断鼠标从哪个方向进入元素? « 张鑫旭-鑫空间-鑫生活 借助mediabunny纯JS实现视频水印、剪裁、合成等功能 « 张鑫旭-鑫空间-鑫生活 务必谨慎使用JS WeakRef弱引用 « 张鑫旭-鑫空间-鑫生活 CSS六边形头像的实现与蜂巢布局 « 张鑫旭-鑫空间-鑫生活 CSS corner-shape与背景底纹技术 « 张鑫旭-鑫空间-鑫生活 浅学WebTransport API:下一代Web双向通信技术 « 张鑫旭-鑫空间-鑫生活 HTML dialog元素新支持了closedBy属性 « 张鑫旭-鑫空间-鑫生活 HTML interestfor属性与悬停popover交互效果 « 张鑫旭-鑫空间-鑫生活 CSS3模拟window7炫酷界面效果展示 « 张鑫旭-鑫空间-鑫生活 图片旋转+剪裁js插件(兼容各浏览器) « 张鑫旭-鑫空间-鑫生活 纯js无图片无外链CSS图片幻灯片播放插件 « 张鑫旭-鑫空间-鑫生活 CSS border三角、圆角图形生成技术简介 « 张鑫旭-鑫空间-鑫生活 CSS “渐进增强”在web制作中常见应用举例 « 张鑫旭-鑫空间-鑫生活 让IE6/IE7/IE8浏览器支持CSS3属性 « 张鑫旭-鑫空间-鑫生活 jQuery – 高亮动态显示页面HTML代码插件 « 张鑫旭-鑫空间-鑫生活 翻译 – 逐渐消失的Flash网站 « 张鑫旭-鑫空间-鑫生活 CSS reset的重新审视 – 避免样式重置 « 张鑫旭-鑫空间-鑫生活 新浪微博插入话题后部分文字选中的js实现 « 张鑫旭-鑫空间-鑫生活 JavaScript实现http地址自动检测并添加URL链接 « 张鑫旭-鑫空间-鑫生活 CSS实现兼容性的渐变背景(gradient)效果 « 张鑫旭-鑫空间-鑫生活 CSS content内容生成技术以及应用 « 张鑫旭-鑫空间-鑫生活 CSS gradient渐变之webkit核心浏览器下的使用 « 张鑫旭-鑫空间-鑫生活 CSS渐变之CSS3 gradient在Firefox3.6下的使用 « 张鑫旭-鑫空间-鑫生活 区分IE8/IE7/IE6及其他浏览器-CSS “\9″hack « 张鑫旭-鑫空间-鑫生活 CSS实现跨浏览器兼容性的盒阴影效果 « 张鑫旭-鑫空间-鑫生活 CSS3&HTML5各浏览器支持情况一览表 « 张鑫旭-鑫空间-鑫生活 翻译 – CSS Sprites:实用技术还是生厌之物? « 张鑫旭-鑫空间-鑫生活 纯CSS实现易拉罐3D滚动效果 « 张鑫旭-鑫空间-鑫生活 纯CSS实现侧边栏/分栏高度自动相等 « 张鑫旭-鑫空间-鑫生活 CSS+JavaScript实现页面不同布局的切换 « 张鑫旭-鑫空间-鑫生活 JavaScript实现最简单的拖拽效果 « 张鑫旭-鑫空间-鑫生活 自己写的无图片版jQuery zxxbox弹出框插件 « 张鑫旭-鑫空间-鑫生活 中国古代道家思想与网页重构的思考 « 张鑫旭-鑫空间-鑫生活 让所有浏览器支持HTML5 video视频标签 « 张鑫旭-鑫空间-鑫生活 纯CSS实现各类气球泡泡对话框效果 « 张鑫旭-鑫空间-鑫生活 JS HEX十六进制与RGB, HSL颜色的相互转换 « 张鑫旭-鑫空间-鑫生活 CSS实现兼容性的渐变、高光等文字效果 « 张鑫旭-鑫空间-鑫生活 去除冗余 – 精简您的CSS样式代码 « 张鑫旭-鑫空间-鑫生活 对overflow与zoom”清除浮动”的一些认识 « 张鑫旭-鑫空间-鑫生活 jQuery Pagination Ajax分页插件中文详解 « 张鑫旭-鑫空间-鑫生活 absolute绝对定位的非绝对定位用法 « 张鑫旭-鑫空间-鑫生活 网页布局思想浅议-淘宝新版首页为实例 « 张鑫旭-鑫空间-鑫生活 回流与重绘:CSS性能让JavaScript变慢? « 张鑫旭-鑫空间-鑫生活 CSS float浮动的深入研究、详解及拓展(二) « 张鑫旭-鑫空间-鑫生活 CSS float浮动的深入研究、详解及拓展(一) « 张鑫旭-鑫空间-鑫生活 60个极富创造性的震撼的电影海报设计 « 张鑫旭-鑫空间-鑫生活 jQuery Lightbox(balupton版)图片展示插件讲解 « 张鑫旭-鑫空间-鑫生活 博客内嵌flash音乐播放器代码、下载与使用 « 张鑫旭-鑫空间-鑫生活 CSS3 animate实现图片墙3D翻转效果 « 张鑫旭-鑫空间-鑫生活 图片旋转效果的一些研究、jQuery插件及实例 « 张鑫旭-鑫空间-鑫生活 CSS3 border-image详解、应用及jQuery插件 « 张鑫旭-鑫空间-鑫生活 jQuery-两款不同原理的圆角插件讲解 « 张鑫旭-鑫空间-鑫生活 页面可用性之outline轮廓外框的一些研究 « 张鑫旭-鑫空间-鑫生活 CSS3 transition实现超酷图片墙动画效果 « 张鑫旭-鑫空间-鑫生活 HTML CSS列表元素ul,ol,dl的研究与应用 « 张鑫旭-鑫空间-鑫生活 jQuery图片文本滚动切换插件jCarousel中文翻译与详解 « 张鑫旭-鑫空间-鑫生活 酷酷的jQuery鼠标悬停图片放大切换显示效果 « 张鑫旭-鑫空间-鑫生活 IE6下z-index犯癫不起作用bug的初步研究 « 张鑫旭-鑫空间-鑫生活 checkbox复选框的一些深入研究与理解 « 张鑫旭-鑫空间-鑫生活 jQuery之使用slideToggle实现垂直下拉菜单 « 张鑫旭-鑫空间-鑫生活 jQuery-innerfade内部列表自动淡入淡出插件 « 张鑫旭-鑫空间-鑫生活 jQuery-火焰灯效果导航菜单 « 张鑫旭-鑫空间-鑫生活 IE下css bug集合-翻译自haslayout.net « 张鑫旭-鑫空间-鑫生活 翻译-IE7/8@font-face嵌入字体与文字平滑 « 张鑫旭-鑫空间-鑫生活 jQuery-马化腾产品设计与用户体验的一些技术实现 « 张鑫旭-鑫空间-鑫生活 像素的世界及其在web开发制作中的应用 « 张鑫旭-鑫空间-鑫生活 css行高line-height的一些深入理解及应用 « 张鑫旭-鑫空间-鑫生活 CSS实现圆角六色渐变自适应按钮详解 « 张鑫旭-鑫空间-鑫生活 我熟知的三种三栏网页宽度自适应布局方法 « 张鑫旭-鑫空间-鑫生活 jQuery照片图像剪裁插件Jcrop中文翻译详解 « 张鑫旭-鑫空间-鑫生活 Ajax Upload多文件上传插件翻译及中文演示 « 张鑫旭-鑫空间-鑫生活 告别图片—使用字符实现兼容性的圆角尖角效果beta版 « 张鑫旭-鑫空间-鑫生活 大小不固定的图片、多行文字的水平垂直居中 « 张鑫旭-鑫空间-鑫生活 jQuery boxy弹出层对话框插件中文演示及讲解 « 张鑫旭-鑫空间-鑫生活 JavaScript实现新浪微博文字放大显示动画效果 « 张鑫旭-鑫空间-鑫生活 翻译:让网络更快一些——最小化浏览器中的回流(reflow) « 张鑫旭-鑫空间-鑫生活 jQuery之addClasas与removeClass使用实例 « 张鑫旭-鑫空间-鑫生活 关于Google圆角高光高宽自适应按钮及其拓展 « 张鑫旭-鑫空间-鑫生活 JavaScript实现图片幻灯片滚动播放动画效果 « 张鑫旭-鑫空间-鑫生活 jQuery-鼠标经过显示大图并跟随鼠标效果插件 « 张鑫旭-鑫空间-鑫生活 关于gif图片(或png8)杂边锯齿的问题 « 张鑫旭-鑫空间-鑫生活 对html与body的一些研究与理解 « 张鑫旭-鑫空间-鑫生活 鲜为人知的一个解决兼容性问题的利器——小数 « 张鑫旭-鑫空间-鑫生活 搜狐白社会似iphone短信对话框效果的优化 « 张鑫旭-鑫空间-鑫生活 关于文字内容溢出用点点点(…)省略号表示 « 张鑫旭-鑫空间-鑫生活 jquery之append与insertBefore使用实例 « 张鑫旭-鑫空间-鑫生活 jQuery之图片关联伸缩效果 « 张鑫旭-鑫空间-鑫生活 jquery之图片左右切换动画效果 « 张鑫旭-鑫空间-鑫生活 jQuery之replace字符串替换实现不同尺寸图片切换 « 张鑫旭-鑫空间-鑫生活 jQuery-实现图片的放大镜显示效果 « 张鑫旭-鑫空间-鑫生活 jQuery-单击文字或图片内容放大显示效果插件 « 张鑫旭-鑫空间-鑫生活 reflection.js-实现图片投影倒影效果js插件 « 张鑫旭-鑫空间-鑫生活 jQuery-很酷的弹出层效果js插件 « 张鑫旭-鑫空间-鑫生活 复选框单选框与文字对齐问题的研究与解决 « 张鑫旭-鑫空间-鑫生活 css margin的相关属性,问题及应用 « 张鑫旭-鑫空间-鑫生活 IE6下png背景不透明问题的综合拓展 « 张鑫旭-鑫空间-鑫生活
如何使用JS检测用户是否缩放了页面? « 张鑫旭-鑫空间-鑫生活
张鑫旭,zhangxinxu · 2021-02-15 · via 张鑫旭-鑫空间-鑫生活

by zhangxinxu from https://www.zhangxinxu.com/wordpress/?p=9832
本文欢迎分享与聚合,全文转载就不必了,尊重版权,圈子就这么大,若急用可以联系授权。

页面缩放占位图

介绍我自己知道的几个检测用户是否缩放了页面的方法,这些方法都不算完美,大家根据实际场景自行抉择该使用哪个方法。

一、resize事件 + devicePixelRatio

如果希望知道用户是否执行了缩放行为,则可以在resize事件事件中检测设备像素比的变化,也就是window.devicePixelRatio的返回值。

代码示意:

let lastPixelRatio = window.devicePixelRatio;
window.addEventListener('resize', function () {
    let currentPixelRatio = window.devicePixelRatio;

    if (currentPixelRatio !== lastPixelRatio) {
        console.log('页面缩放变化了');
    }

    lastPixelRatio = currentPixelRatio;
});

当用户缩放页面的时候会触发窗体的resize事件,以及设备的devicePixelRatio也会跟着变化,于是,我们可以在resize事件中检测devicePixelRatio和缩放事件之前的devicePixelRatio值进行对比,如果变化,则可以认为页面发生了缩放。

但是,上面的方法是有明显的不足的,那就是只能知道页面缩放变化了,但是页面究竟缩放了多少并不知道。

例如,页面原来放大到了120%,然后用户还原到了100%,此时,也认为页面缩放变化了,实际上,此时页面1:1显示,是正常状态,需求上往往是不需要做处理的,但是上面的判断无法识别当前是100%缩放。

那有没有什么法子判断页面真实的缩放比例呢?

还挺难的,因为浏览器会记住当前域名下浏览器的缩放比例,并没有固定的基准devicePixelRatio参照值,因此,使用devicePixelRatio是没法计算页面的缩放比例的。

只能一定程度上进行判断

如果不是追求100%的精准,其实可以配合localStorage本地存储一定程度上判断浏览器的缩放比例,完整JS代码如下:

// 初始缩放比例
let originPixelRatio = localStorage.devicePixelRatio;
if (!originPixelRatio) {
    originPixelRatio = window.devicePixelRatio;
    // 整数才保存
    if (Number.isInteger(originPixelRatio)) {
        localStorage.devicePixelRatio = originPixelRatio;
    }
}

let lastPixelRatio = originPixelRatio;
window.addEventListener('resize', function () {
    let currentPixelRatio = window.devicePixelRatio;
    if (currentPixelRatio !== lastPixelRatio) {
        console.log('缩放比例是:' + Math.round(1000 * (currentPixelRatio / originPixelRatio)) / 10 + '%');
    }
    // 记住上一次的设备像素比
    lastPixelRatio = currentPixelRatio;
});

上面的JS代码效果可以狠狠地点击这里进行体验:resize事件加devicePixelRatio检测是否缩放demo

例如我自己电脑的Chrome浏览器下有如下所示的效果(Ctrl+/Ctrl-改变页面的比例试试):

缩放实现效果示意

可以准备识别用户进行了页面缩放,并准确显示了缩放比例。

但是,上面的实现并不严谨。

如果用户首次进入页面的时候,浏览器的视窗本身就是缩放状态,且此时的设备像素比是整数,则相关的判断就会出问题;虽然这种情况发生概率并不大,但是,理论上,就是会有这样的问题。

所以说,这个方法只能在一定程度上进行缩放比例的判断。

二、matchMedia检测devicePixelRatio变化

resize事件进行判断页面是否缩放会伴随一些不必要的消耗,因为当用户改变窗体的尺寸,或者设备发生旋转,或者设备打开了开发者工具等,都会触发resize事件,但是,显然,这些触发resize事件的场景和页面缩放是没有关系的,而且这些场景才是真正的常态发生的,缩放才是小众发生的。

那有没有其他什么办法更高效地检测浏览器是否发生的页面缩放呢?

此时可以试试matchMedia()方法,语法如下:

let mql = window.matchMedia(mediaString);

mql这个对象包含若干属性和方法,例如:

mql.matches
布尔值,表示当前是否匹配指定的媒体查询。
mql.media
字符串,返回编译后的媒体查询字符串。
mql.onchange
媒体查询改变时候的回调。
mql.addListener(fn)
fn参数是事件函数,媒体查询匹配状态变化时候执行。(此API已经不推荐使用)
mql.removeListener(fn)
fn参数是事件函数,移除绑定的事件。(此API已经不推荐使用)

在本例中,我们使用onchange方法,代码如下所示,初始设备像素比的处理逻辑和上面的resize事件处理一致,大家注意力可以从let mqListener…这行语句开始:

let originPixelRatio = localStorage.devicePixelRatio;
if (!originPixelRatio) {
    originPixelRatio = window.devicePixelRatio;
    if (Number.isInteger(originPixelRatio)) {
        localStorage.devicePixelRatio = originPixelRatio;
    }
}
// 设备相似比变化时候的处理函数
let mqListener = function () {
    let currentPixelRatio = window.devicePixelRatio;
    console.log('缩放比例是:' + currentPixelRatio / originPixelRatio);

    // 移除之前的查询检测
    this.removeEventListener('change', mqListener);
    // 使用新的查询检测
    matchMedia(`(resolution: ${currentPixelRatio}dppx)`).addEventListener('change', mqListener);
};
// 添加媒体查询匹配变化事件
matchMedia(`(resolution: ${originPixelRatio}dppx)`).addEventListener('change', mqListener);

为何要不断移除事件?

matchMedia()绑定的change事件,只会在查询状态改变时候触发,例如,原始的设备像素比(单位就是dppx)是1,则浏览器第一次放大和缩小的时候,change事件会执行,因为状态从匹配变成了不匹配,但是,如果继续放大和缩小,则change事件不再触发,因为状态一直是不匹配。

因此,逻辑实现的时候,需要试试更新媒体查询语句,绑定新的change事件,这样,任意的设备像素比变化都可以被检测到。

眼见为实,您可以狠狠地点击这里:matchMedia + dppx查询检测是否缩放demo

例如,在我的Windows 10 Firefox 85浏览器下的效果:

Firefox浏览器下的缩放与设备像素比

//zxx: 如果你看到这段文字,说明你现在访问是体验糟糕的垃圾盗版网站,你可以访问原文获得很好的体验:https://www.zhangxinxu.com/wordpress/?p=9832(作者张鑫旭)

三、outerWidth/innerWidth方法

浏览器的缩放比例还可以使用下面的公式:

let zoom = window.outerWidth / window.innerWidth;

此方法的JS代码比较简洁,如下示意:

window.addEventListener('resize', function () {
    console.log('当前页面缩放比例应该是:' + Math.round(1000 * (outerWidth / innerWidth)) / 10 + '%');
});

也就是把浏览器外部尺寸和窗体内部尺寸的比例作为缩放比例。

这个方法靠谱吗?

我特意整了个demo,您可以狠狠地点击这里:outerWidth/innerWidth与页面缩放demo

在我的Chrome浏览器下,缩放效果如下GIF所示:

缩放实现效果示意

再看看Safari浏览器,如下图所示:

Safari浏览器截图

卧槽,好像很牛逼的样子,居然都可以识别。

然而……致命的缺陷

首先是小缺陷,那就是Firefox浏览器此方法无效,页面缩放的时候,innerWidth尺寸似乎没有明显变化,例如下图是页面放大150%时候的效果,但是outerWidth / innerWidth计算值还是接近与1.

比例是1在Firefox下

考虑到Firefox用户在国内的占比,此问题算是小缺陷,真正的致命的缺陷是下面这个:

当开发开发者工具,同时浏览器侧面定位的时候,缩放比例计算会有严重的偏差,因为此时innerWidth的尺寸严重缩水。

比方说下图所示的场景,Chrome浏览器下,页面并未缩放,但是开发者工具在侧边框打开,显示的缩放比例远远大于100%:

侧边框显示缩放比例不对

然后有些国产浏览器会有自己的侧边栏,里面放了些收藏夹或者其他乱七八糟东西,也会影响innerWidth的尺寸。

因此outerWidth/innerWidth方法虽然简单,但是却有使用风险。

活跃在移动端?

如果不需要考虑Firefox浏览器,以及浏览器绝不会出现侧边栏,则outerWidth/innerWidth方法真是一个上上之选。

嘿,貌似移动端项目就符合这一点。

手机屏幕本来宽度就有限,是不可能多出侧边栏的,也不用考虑Firefox浏览器。

于是我就自己扫码测了下,结果是……resize事件没触发?

Android 微信、原生浏览器、Chrome和iOS中的微信浏览器都是如此,只有iOS Safari浏览器双指缩放页面时候可以触发计算。

算了算了,移动端应该没戏,移动端不要多想了,还是老老实实使用下面的visualViewport API吧。

因此,此方法不建议单独使用,可以配合前面的matchMedia()方法进行交叉验证,提高用户缩放行为判断的准确性。

四、visualViewport与手势缩放识别

实际上,页面的缩放比例,浏览器是提供了原生的API的,那就是window.visualViewport.scale

visualViewport对象包括很多属性,例如宽高、偏移大小等,其中,我认为最稀缺的属性就是scale,可以返回当前页面因为双指缩放带来的缩放比例。

移动设备专享

visualViewport.scale看起来给浏览器缩放识别带来了曙光,确实如此,但是,如果大家在PC端进行测试,会发现visualViewport.scale永远发挥的是1,无论页面通过 Ctrl+/Ctrl-组合键如何的缩小放大,都是1

这是bug吗?

不是的,因为返回的虚拟视区的pinch-zoom缩放比例,表示手势缩放。

因此,visualViewport.scale只能在移动端使用,正好上面的几个方法均不适用于移动端。

整了个demo,您可以狠狠地点击这里:visualViewport与手势缩放比例demo

也可以扫码体验:

demo二维码

例如,在我的Android微信中,缩放页面就可以看到实时的比例变化,截屏效果如下:

缩放比例移动端截图

相应的JS很简单:

window.visualViewport.addEventListener('resize', function () {
    result.innerHTML = '手势缩放比例:' + this.scale;
});

兼容性

从实用角度讲,兼容性还是可以的,除了Firefox暂时不能使用外,其他现代浏览器均可以使用VisualViewport这个API,详见下图:

VisualViewport兼容性

由于在国内移动端开发不考虑Firefox,以及visualViewport.scale就是给移动端用的,因此,只要项目可以不支持iOS 12,此API都是可以用起来的。

五、最后总结一下

在桌面端,用户缩放浏览器页面的时候,devicePixelRatio设备像素比的值是会跟着变化的,因此,我们可以通过观察devicePixelRatio的变化判断用户是否缩放了浏览器。

如何观察呢?

可以使用resize事件,或者使用matchMedia()方法返回的change事件进行观察,其中,后者针对性更强。

除此之外,如果不考虑Firefox浏览器以及认为用户不会以侧边栏的方式打开开发者工具,则还可以使用outerWidth/innerWidth方法判断当前页面的缩放比例。

以上这些判断均指适用于桌面端浏览器,移动端页面的缩放判断可以使用visualViewport.scale这个只读属性完成,目前iOS和Android操作系统均支持。

好,以上就是我知道的检测页面缩放的方法。

一个人所积累的知识毕竟有限,如果有其他更好的方法,希望不吝赐教!

如果文中有表述不准确的地方,也欢迎以评论形式进行指正。

感谢阅读,如果您觉得本文内容还挺不错,欢迎分享到朋友圈或者各类咨询群,感谢感谢!

本文为原创文章,欢迎分享,勿全文转载,如果实在喜欢,可收藏,永不过期,且会及时更新知识点及修正错误,阅读体验也更好。
本文地址:https://www.zhangxinxu.com/wordpress/?p=9832

(本篇完)