เป็นไปได้ไหมที่จะตรวจจับโดยใช้ JavaScript เมื่อผู้ใช้เปลี่ยนการซูมในหน้า? ฉันเพียงแค่ต้องการที่จะจับ "ซูม" เหตุการณ์และตอบสนองต่อมัน (คล้ายกับ window.onresize เหตุการณ์)
ขอบคุณ
เป็นไปได้ไหมที่จะตรวจจับโดยใช้ JavaScript เมื่อผู้ใช้เปลี่ยนการซูมในหน้า? ฉันเพียงแค่ต้องการที่จะจับ "ซูม" เหตุการณ์และตอบสนองต่อมัน (คล้ายกับ window.onresize เหตุการณ์)
ขอบคุณ
คำตอบ:
ไม่มีวิธีใดที่จะตรวจจับหากมีการซูม ฉันพบรายการที่ดีที่นี่เกี่ยวกับวิธีที่คุณสามารถใช้งานได้
ฉันพบวิธีการตรวจจับระดับการซูมสองวิธี วิธีหนึ่งในการตรวจสอบการเปลี่ยนแปลงระดับการซูมขึ้นอยู่กับความจริงที่ว่าค่าร้อยละไม่ได้ซูม ค่าเปอร์เซ็นต์นั้นสัมพันธ์กับความกว้างของวิวพอร์ตและไม่ได้รับผลกระทบจากการซูมหน้า หากคุณแทรกองค์ประกอบสองรายการหนึ่งรายการที่มีตำแหน่งเป็นเปอร์เซ็นต์และอีกองค์ประกอบที่มีตำแหน่งเดียวกันเป็นพิกเซลองค์ประกอบเหล่านั้นจะย้ายออกจากกันเมื่อหน้าซูม ค้นหาอัตราส่วนระหว่างตำแหน่งขององค์ประกอบทั้งสองและคุณมีระดับการย่อ / ขยาย ดูกรณีทดสอบ http://web.archive.org/web/20080723161031/http://novemberborn.net/javascript/page-zoom-ff3
คุณสามารถทำได้โดยใช้เครื่องมือของโพสต์ด้านบน ปัญหาคือคุณคาดเดาได้มากขึ้นหรือน้อยลงว่าหน้านั้นซูมหรือไม่ วิธีนี้จะใช้งานได้ดีกว่าในเบราว์เซอร์บางตัว
ไม่มีวิธีที่จะบอกได้ว่าหน้าเว็บถูกซูมหรือไม่หากพวกเขาโหลดหน้าเว็บของคุณในขณะที่ซูม
document.body.offsetWidth
ฉันใช้ JavaScript ชิ้นนี้เพื่อตอบสนองต่อการซูม "เหตุการณ์"
มันสำรวจความกว้างของหน้าต่าง (ตามที่แนะนำในหน้านี้ (ซึ่ง Ian Elliott เชื่อมโยงกับ): http://novemberborn.net/javascript/page-zoom-ff3 [เก็บถาวร] )
ทดสอบกับ Chrome, Firefox 3.6 และ Opera ไม่ใช่ IE
ขอแสดงความนับถือแมกนัส
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);
})();
ข่าวดี ทุกคนบางคน! เบราว์เซอร์ที่ใหม่กว่าจะทริกเกอร์เหตุการณ์การปรับขนาดหน้าต่างเมื่อเปลี่ยนการซูม
ให้กำหนด px_ratio ดังนี้:
px ratio = อัตราส่วนของฟิสิคัลพิกเซลต่อ css px
หากซูมหน้าใดหน้าหนึ่งวิวพอร์ต pxes (px แตกต่างจากพิกเซล) จะลดลงและควรพอดีกับหน้าจอดังนั้นอัตราส่วน (ฟิสิคัลพิกเซล / CSS_px) จะต้องใหญ่ขึ้น
แต่ในการปรับขนาดหน้าต่างขนาดหน้าจอจะลดลงเช่นเดียวกับ pxes ดังนั้นอัตราส่วนจะรักษา
แต่
การปรับขนาด: ทริกเกอร์ 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 และพิกเซลทางกายภาพ
https://gist.github.com/abilogos/66aba96bb0fb27ab3ed4a13245817d1e
สิ่งนี้ใช้ได้กับฉัน:
var deviceXDPI = screen.deviceXDPI;
setInterval(function(){
if(screen.deviceXDPI != deviceXDPI){
deviceXDPI = screen.deviceXDPI;
... there was a resize ...
}
}, 500);
จำเป็นสำหรับ IE8 เท่านั้น เบราว์เซอร์อื่น ๆ ทั้งหมดจะสร้างเหตุการณ์การปรับขนาด
มีปลั๊กอินที่ดีที่สร้างขึ้นจาก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
: "");
}
Always enable zoom
ปุ่มในตัวเลือกการช่วยสำหรับการเข้าถึง ตัวอย่างจะไม่ตอบสนองต่อการเปลี่ยนแปลง
ฉันต้องการแนะนำการปรับปรุงวิธีแก้ไขปัญหาก่อนหน้าด้วยการติดตามการเปลี่ยนแปลงความกว้างของหน้าต่าง แทนที่จะเก็บชุดเหตุการณ์ผู้ฟังของคุณเองคุณสามารถใช้ระบบเหตุการณ์จาวาสคริปต์ที่มีอยู่และทริกเกอร์เหตุการณ์ของคุณเองเมื่อมีการเปลี่ยนแปลงความกว้างและผูกตัวจัดการเหตุการณ์ไว้
$(window).bind('myZoomEvent', function() { ... });
function pollZoomFireEvent()
{
if ( ... width changed ... ) {
$(window).trigger('myZoomEvent');
}
}
Throttle / debounceสามารถช่วยลดอัตราการโทรของผู้จัดการของคุณ
นอกจากนี้คุณยังสามารถรับข้อความการปรับขนาดเหตุการณ์และตัวคูณการย่อ / ขยายโดยการฉีด div ที่มีพื้นที่ว่างไม่น้อย (อาจซ่อนอยู่) และตรวจสอบความสูงเป็นประจำ หากความสูงเปลี่ยนไปขนาดของข้อความก็เปลี่ยนไป (และคุณก็รู้ว่ามันมากแค่ไหน - ไฟนี้โดยบังเอิญถ้าหน้าต่างถูกซูมในโหมดเต็มหน้าและคุณยังจะได้รับปัจจัยการซูมที่ถูกต้องด้วยความสูงเดียวกัน / อัตราส่วนความสูง)
<script>
var zoomv = function() {
if(topRightqs.style.width=='200px){
alert ("zoom");
}
};
zoomv();
</script>
ใน 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;
});
แม้ว่านี่จะเป็นคำถามเก่าอายุ 9 ปีปัญหายังคงมีอยู่!
ฉันตรวจพบการปรับขนาดในขณะที่ไม่รวมการซูมในโครงการดังนั้นฉันจึงแก้ไขโค้ดของฉันเพื่อให้สามารถตรวจจับทั้งการปรับขนาดและซูมแบบเอกสิทธิ์จากกัน มันใช้งานได้เกือบตลอดเวลาดังนั้นถ้าส่วนใหญ่ดีพอสำหรับโครงการของคุณนี่จะเป็นประโยชน์! มันตรวจจับการซูม 100% ของเวลาในสิ่งที่ฉันทดสอบ ปัญหาเดียวคือถ้าผู้ใช้บ้า (เช่นการปรับขนาดหน้าต่าง spastically) หรือหน้าต่างล่าช้ามันอาจเริ่มทำงานเมื่อซูมแทนการปรับขนาดหน้าต่าง
มันทำงานโดยการตรวจสอบการเปลี่ยนแปลงใน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% เป็นจำนวนที่น้อยที่สุดที่เบราว์เซอร์จะซูมในทุกกรณี แต่ไม่ชัดเจนว่านี่เป็นจริงสำหรับเบราว์เซอร์อื่น fyi, ตรวจสอบให้แน่ใจเสมอว่าโค้ดของคุณผ่านการทดสอบ, และเตรียมพร้อมที่จะปกป้องหรือปรับปรุงมัน
นี่คือทางออกที่สะอาด:
// 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);
});
เหตุการณ์การปรับขนาดทำงานบนเบราว์เซอร์ที่ทันสมัยโดยแนบเหตุการณ์window
และจากนั้นอ่านค่าของbody
หรือองค์ประกอบอื่น ๆ ด้วยเช่น ( .getBoundingClientRect () )
ในบางเบราว์เซอร์ก่อนหน้านี้เป็นไปได้ที่จะลงทะเบียนปรับขนาดตัวจัดการเหตุการณ์ในองค์ประกอบ HTML ใด ๆ มันยังคงเป็นไปได้ที่จะตั้งค่าคุณสมบัติ onresize หรือใช้ addEventListener () เพื่อตั้งค่าตัวจัดการกับองค์ประกอบใด ๆ อย่างไรก็ตามเหตุการณ์การปรับขนาดจะถูกเรียกใช้บนวัตถุหน้าต่างเท่านั้น (เช่นส่งคืนโดย document.defaultView) เพียงลงทะเบียนบนรถขนวัตถุหน้าต่างจะได้รับเหตุการณ์การปรับขนาด
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>
ระวังอย่าโอเวอร์โหลดงานจาวาสคริปต์จากเหตุการณ์ท่าทางผู้ใช้ ใช้requestAnimationFrameเมื่อใดก็ตามที่คุณต้องการให้วาดใหม่
ตาม MDN "matchMedia" เป็นวิธีที่เหมาะสมในการทำhttps://developer.mozilla.org/en-US/docs/Web/API/Window/devicePixelRatio#Monitoring_screen_resolution_or_zoom_level_changes
มันค่อนข้างจะพิถีพิถันเพราะแต่ละครั้งสามารถดู MQ ได้ครั้งละหนึ่งเท่านั้นดังนั้นหากคุณสนใจที่จะเปลี่ยนระดับการซูมใด ๆคุณจะต้องทำการจับคู่เป็นกลุ่ม .. แต่เนื่องจากเบราว์เซอร์มีหน้าที่เปล่งเหตุการณ์ ยังมีประสิทธิภาพมากกว่าการทำโพลและคุณสามารถเค้นหรือ debounce callback หรือตรึงมันลงในเฟรมภาพเคลื่อนไหวหรือบางสิ่งบางอย่าง - นี่คือการใช้งานที่ดูเหมือนจะค่อนข้างเร็วรู้สึกอิสระที่จะแลกเปลี่ยนใน _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>
ฉันกำลังตอบกลับลิงค์ 3 ปี แต่ฉันเดาว่านี่เป็นคำตอบที่ยอมรับได้มากกว่า
สร้างไฟล์. css เป็น
@media screen and (max-width: 1000px)
{
// things you want to trigger when the screen is zoomed
}
เช่น:-
@media screen and (max-width: 1000px)
{
.classname
{
font-size:10px;
}
}
โค้ดด้านบนทำให้ขนาดของตัวอักษร '10px' เมื่อหน้าจอถูกซูมเป็นประมาณ 125% คุณสามารถตรวจสอบระดับการซูมที่แตกต่างกันโดยเปลี่ยนค่าของ '1000px'
max-width
และอัตราส่วนการซูมคืออะไร?