Apakah mungkin mendeteksi, menggunakan JavaScript, ketika pengguna mengubah zoom pada halaman? Saya hanya ingin menangkap acara "zoom" dan menanggapinya (mirip dengan acara window.onresize).
Terima kasih.
Apakah mungkin mendeteksi, menggunakan JavaScript, ketika pengguna mengubah zoom pada halaman? Saya hanya ingin menangkap acara "zoom" dan menanggapinya (mirip dengan acara window.onresize).
Terima kasih.
Jawaban:
Tidak ada cara untuk secara aktif mendeteksi jika ada zoom. Saya menemukan entri yang bagus di sini tentang bagaimana Anda dapat mencoba mengimplementasikannya.
Saya telah menemukan dua cara mendeteksi tingkat zoom. Salah satu cara untuk mendeteksi perubahan level zoom bergantung pada fakta bahwa nilai persentase tidak diperbesar. Nilai persentase relatif terhadap lebar viewport, dan karenanya tidak terpengaruh oleh pembesaran halaman. Jika Anda menyisipkan dua elemen, satu dengan posisi dalam persentase, dan satu dengan posisi yang sama dalam piksel, mereka akan bergerak terpisah ketika halaman diperbesar. Temukan rasio antara posisi kedua elemen dan Anda sudah mendapatkan level zoom. Lihat test case. http://web.archive.org/web/20080723161031/http://novemberborn.net/javascript/page-zoom-ff3
Anda juga bisa melakukannya menggunakan alat dari posting di atas. Masalahnya adalah Anda lebih atau kurang membuat dugaan tentang apakah halaman tersebut diperbesar atau tidak. Ini akan bekerja lebih baik di beberapa browser daripada yang lain.
Tidak ada cara untuk mengetahui apakah halaman diperbesar jika mereka memuat halaman Anda saat diperbesar.
document.body.offsetWidth
Saya menggunakan bagian JavaScript ini untuk bereaksi terhadap Zoom "acara".
Itu polling lebar jendela. (Seperti yang disarankan pada halaman ini (yang dikaitkan dengan Ian Elliott): http://novemberborn.net/javascript/page-zoom-ff3 [arsip] )
Diuji dengan Chrome, Firefox 3.6 dan Opera, bukan IE.
Salam, 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);
})();
Kabar baik semua orangbeberapa orang! Peramban yang lebih baru akan memicu peristiwa pengubahan ukuran jendela saat zoom diubah.
Mari kita mendefinisikan px_ratio seperti di bawah ini:
px rasio = rasio pixel fisik ke css px.
jika ada yang memperbesar Halaman, viewport pxes (px berbeda dari pixel) berkurang dan harus sesuai dengan layar sehingga rasio (pixel fisik / CSS_px) harus menjadi lebih besar.
tetapi di window Resizing, ukuran layar berkurang dan juga pxes. jadi rasio akan dipertahankan.
tapi
mengubah ukuran: memicu windows.resize acara -> tidak mengubah 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;
}
}
Poin kuncinya adalah perbedaan antara CSS PX dan Physical Pixel.
https://gist.github.com/abilogos/66aba96bb0fb27ab3ed4a13245817d1e
Ini bekerja untuk saya:
var deviceXDPI = screen.deviceXDPI;
setInterval(function(){
if(screen.deviceXDPI != deviceXDPI){
deviceXDPI = screen.deviceXDPI;
... there was a resize ...
}
}, 500);
Itu hanya diperlukan di IE8. Semua browser lain secara alami menghasilkan acara pengubahan ukuran.
Ada plugin bagus yang dibangun dari yonran
yang dapat melakukan deteksi. Ini pertanyaannya yang sebelumnya dijawab di StackOverflow. Ini berfungsi untuk sebagian besar browser. Aplikasi sesederhana ini:
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
tombol di opsi Aksesibilitas. Demo tidak akan bereaksi terhadap perubahan.
Saya ingin menyarankan peningkatan solusi sebelumnya dengan melacak perubahan lebar jendela. Alih-alih mempertahankan susunan acara pendengar Anda sendiri, Anda dapat menggunakan sistem acara javascript yang ada dan memicu acara Anda sendiri pada perubahan lebar, dan mengikat pengatur acara untuk itu.
$(window).bind('myZoomEvent', function() { ... });
function pollZoomFireEvent()
{
if ( ... width changed ... ) {
$(window).trigger('myZoomEvent');
}
}
Throttle / debounce dapat membantu mengurangi tingkat panggilan handler Anda.
Anda juga bisa mendapatkan peristiwa pengubahan ukuran teks, dan faktor zoom dengan menyuntikkan div yang berisi setidaknya ruang yang tidak dapat dipecahkan (mungkin, disembunyikan), dan secara teratur memeriksa ketinggiannya. Jika tinggi berubah, ukuran teks telah berubah, (dan Anda tahu berapa banyak - ini juga menyala, secara kebetulan, jika jendela diperbesar dalam mode halaman penuh, dan Anda masih akan mendapatkan faktor zoom yang benar, dengan tinggi yang sama / rasio tinggi).
<script>
var zoomv = function() {
if(topRightqs.style.width=='200px){
alert ("zoom");
}
};
zoomv();
</script>
Di iOS 10 dimungkinkan untuk menambahkan pendengar acara ke touchmove
acara dan untuk mendeteksi, jika halaman diperbesar dengan acara saat ini.
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;
});
Meskipun ini adalah pertanyaan lama 9 tahun, masalahnya tetap ada!
Saya telah mendeteksi ukuran sementara mengecualikan zoom dalam suatu proyek, jadi saya mengedit kode saya untuk membuatnya berfungsi untuk mendeteksi ukuran dan zoom eksklusif satu sama lain. Ini berfungsi sebagian besar waktu, jadi jika sebagian besar cukup baik untuk proyek Anda, maka ini akan sangat membantu! Ini mendeteksi zoom 100% dari waktu dalam apa yang telah saya uji sejauh ini. Satu-satunya masalah adalah bahwa jika pengguna menjadi gila (mis. Mengubah ukuran jendela secara spastik) atau jeda jendela, ia mungkin menyala sebagai zoom alih-alih ukuran jendela.
Ini bekerja dengan mendeteksi perubahan dalam window.outerWidth
atau window.outerHeight
sebagai pengubahan ukuran jendela saat mendeteksi perubahan dalam window.innerWidth
atau window.innerHeight
independen dari pengubahan ukuran jendela sebagai pembesaran.
//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);
Catatan: Solusi saya seperti milik KajMagnus, tetapi ini telah bekerja lebih baik untuk saya.
0.05
tanpa setidaknya memberikan penjelasan yang baik. ;-) Misalnya, saya tahu bahwa di Chrome, khususnya, 10% adalah jumlah terkecil yang akan diperbesar peramban dalam kasus apa pun, tetapi tidak jelas bahwa ini berlaku untuk peramban lain. fyi, selalu pastikan kode Anda diuji, dan bersiaplah untuk mempertahankan atau memperbaikinya.
Ini solusi bersih:
// 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);
});
Acara pengubahan ukuran bekerja pada browser modern dengan melampirkan acara tersebut di window
, dan kemudian membaca nilai-nilai dari body
, atau elemen lain dengan misalnya ( .getBoundingClientRect () ).
Di beberapa browser sebelumnya, dimungkinkan untuk mendaftarkan pengatur acara yang diubah ukurannya pada elemen HTML apa pun. Masih dimungkinkan untuk mengatur atribut yang terlalu besar atau menggunakan addEventListener () untuk mengatur handler pada elemen apa pun. Namun, peristiwa pengubahan ukuran hanya dipecat pada objek jendela (yaitu dikembalikan oleh document.defaultView). Hanya penangan yang terdaftar pada objek jendela yang akan menerima acara pengubahan ukuran .
window.addEventListener("resize", getSizes, false)
function getSizes(){
let body = document.body
console.log(body.clientWidth +"px x "+ body.clientHeight + "px")
}
Alternatif lain : API ResizeObserver
Tergantung tata letak Anda, Anda dapat menonton untuk mengubah ukuran pada elemen tertentu.
Ini berfungsi dengan baik pada tata letak «responsif», karena kotak kontainer diubah ukurannya saat zooming.
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>
Berhati-hatilah untuk tidak membebani tugas javascript dari acara gerakan pengguna. Gunakan requestAnimationFrame kapan pun Anda perlu menggambar ulang.
Menurut MDN, "matchMedia" adalah cara yang tepat untuk melakukan ini https://developer.mozilla.org/en-US/docs/Web/API/Window/devicePixelRatio#Monitoring_screen_resolution_or_zoom_level_changes
ini agak rewel karena setiap instance hanya dapat menonton satu MQ pada satu waktu, jadi jika Anda tertarik pada perubahan level zoom apa pun, Anda perlu membuat banyak pencocokan .. tetapi karena browser bertugas untuk memancarkan peristiwa, mungkin masih lebih berkinerja daripada jajak pendapat, dan Anda bisa mencekik atau melonggarkan panggilan balik atau menyematkannya ke bingkai animasi atau sesuatu - inilah implementasi yang tampaknya cukup tajam, jangan ragu untuk menukar di _throttle atau apa pun jika Anda sudah bergantung pada itu.
Jalankan cuplikan kode dan perbesar dan perkecil di peramban Anda, catat nilai yang diperbarui di markup - Saya hanya menguji ini di Firefox! biar tahu jika Anda melihat masalah.
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>
Saya membalas tautan berusia 3 tahun tetapi saya kira inilah jawaban yang lebih dapat diterima,
Buat file .css sebagai,
@media screen and (max-width: 1000px)
{
// things you want to trigger when the screen is zoomed
}
MISALNYA:-
@media screen and (max-width: 1000px)
{
.classname
{
font-size:10px;
}
}
Kode di atas membuat ukuran font '10px' ketika layar diperbesar menjadi sekitar 125%. Anda dapat memeriksa tingkat zoom yang berbeda dengan mengubah nilai '1000px'.
max-width
rasio zoom dan?