Chrome中打印页面时window.matchMedia事件触发的原因及禁用方法
问题原因与解决方案
为什么打印会触发matchMedia的change事件?
这是因为Chrome等现代浏览器在打印预览阶段会临时调整页面的视口宽度,以此来模拟打印纸张的实际尺寸(比如默认A4纸对应的像素宽度大约是555px)。这个临时的视口变化就会触发你监听的(min-width: 768px)媒体查询的change事件。当打印预览结束(不管是完成打印还是取消预览),浏览器会恢复页面原来的视口宽度,所以又会再次触发一次change事件。
如何禁用这种打印触发的change事件?
你可以通过判断当前是否处于打印流程中,来跳过matchMedia事件的处理逻辑,有两种常用方案:
方案1:通过print媒体查询判断打印状态
在你的matchMedia change事件回调里,先检查当前是否处于打印状态,如果是就不执行后续逻辑:
const mediaQuery = window.matchMedia('only screen and (min-width: 768px)'); const printQuery = window.matchMedia('print'); mediaQuery.addEventListener('change', (e) => { // 如果当前是打印状态,跳过事件处理 if (printQuery.matches) return; console.log('change width event', { innerWidth: window.innerWidth, outerWidth: window.outerWidth }); });
方案2:利用beforeprint和afterprint事件设置标志位
通过这两个事件标记当前是否在打印流程中,在matchMedia回调里根据标志位决定是否执行逻辑:
const mediaQuery = window.matchMedia('only screen and (min-width: 768px)'); let isPrinting = false; // 监听打印开始/结束事件 window.addEventListener('beforeprint', () => { isPrinting = true; }); window.addEventListener('afterprint', () => { isPrinting = false; }); mediaQuery.addEventListener('change', (e) => { // 如果处于打印流程中,跳过处理 if (isPrinting) return; console.log('change width event', { innerWidth: window.innerWidth, outerWidth: window.outerWidth }); });
这两种方案都能有效过滤掉打印操作带来的不必要的matchMedia触发,你可以根据自己的场景选择合适的方式。
内容的提问来源于stack exchange,提问作者Stephane L
相关产品推荐
相关产品推荐

