Kullanıcı bir sayfadaki yakınlaştırmayı değiştirdiğinde JavaScript kullanarak algılamak mümkün müdür? Sadece bir "zoom" olayı yakalamak ve buna yanıt vermek istiyorum (window.onresize olayına benzer).
Teşekkürler.
Kullanıcı bir sayfadaki yakınlaştırmayı değiştirdiğinde JavaScript kullanarak algılamak mümkün müdür? Sadece bir "zoom" olayı yakalamak ve buna yanıt vermek istiyorum (window.onresize olayına benzer).
Teşekkürler.
Yanıtlar:
Bir yakınlaştırma olup olmadığını aktif olarak tespit etmenin bir yolu yoktur. Burada bunu nasıl uygulayabileceğiniz konusunda iyi bir giriş buldum.
Zoom seviyesini tespit etmenin iki yolunu buldum. Zoom seviyesi değişikliklerini tespit etmenin bir yolu yüzde değerlerinin zoom yapılmamasına dayanır. Yüzde değeri görünüm genişliği ile ilişkilidir ve bu nedenle sayfa yakınlaştırmasından etkilenmez. Biri yüzde olarak ve biri piksel olarak aynı konuma sahip iki öğe eklerseniz, sayfa yakınlaştırıldığında birbirlerinden uzaklaşırlar. Her iki öğenin konumları arasındaki oranı bulun ve yakınlaştırma seviyesine sahip olun. Test senaryosuna bakın. http://web.archive.org/web/20080723161031/http://novemberborn.net/javascript/page-zoom-ff3
Bunu yukarıdaki yazının araçlarını kullanarak da yapabilirsiniz. Sorun, sayfanın yakınlaştırılıp büyütülmediğine dair az çok eğitimli tahminler yapmanızdır. Bu, bazı tarayıcılarda diğer tarayıcılardan daha iyi çalışır.
Sayfanızı yakınlaştırılmış durumdayken yüklüyorlarsa, sayfanın büyütülmüş olup olmadığını anlamanın bir yolu yoktur.
document.body.offsetWidth
Bu JavaScript parçasını Zoom "olaylarına" tepki vermek için kullanıyorum.
Pencere genişliğini yoklar. (Bu sayfada bir şekilde önerildiği gibi (Ian Elliott'ın bağlı olduğu): http://novemberborn.net/javascript/page-zoom-ff3 [arşiv] )
IE ile değil Chrome, Firefox 3.6 ve Opera ile test edilmiştir.
Saygılarımızla, 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);
})();
İyi haberler herkesbazı insanlar! Daha yeni tarayıcılar, zum değiştirildiğinde pencere yeniden boyutlandırma olayını tetikler.
Px_ratio'yu aşağıdaki gibi tanımlayalım:
piksel oranı = fiziksel pikselin css piksele oranı.
herhangi bir yakınlaştırma Sayfayı, görüntü alanı pikselleri (piksel pikselden farklıdır) küçültür ve ekrana sığmalıdır, böylece oran (fiziksel piksel / CSS_px) büyür.
ancak Yeniden boyutlandırma penceresinde ekran boyutu piksellerin yanı sıra küçülür. böylece oran korunur.
fakat
yeniden boyutlandırma: trigger windows.resize olayı -> px_ratio'yu değiştirmez
//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;
}
}
Kilit nokta, CSS PX ve Fiziksel Piksel arasındaki farktır.
https://gist.github.com/abilogos/66aba96bb0fb27ab3ed4a13245817d1e
Bu benim için çalışıyor:
var deviceXDPI = screen.deviceXDPI;
setInterval(function(){
if(screen.deviceXDPI != deviceXDPI){
deviceXDPI = screen.deviceXDPI;
... there was a resize ...
}
}, 500);
Yalnızca IE8'de gereklidir. Diğer tüm tarayıcılar doğal olarak bir yeniden boyutlandırma olayı oluşturur.
yonran
Algılamayı yapabilen inşa edilmiş şık bir eklenti var . İşte StackOverflow ile ilgili daha önce cevapladığı soru. Tarayıcıların çoğu için çalışır. Uygulama bu kadar basit:
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
Erişilebilirlik seçeneğindeki düğmeyi işaretleyin . Demo değişime tepki vermeyecek.
Pencere genişliğindeki değişiklikleri izleyerek önceki çözümde bir iyileştirme önermek istiyorum. Kendi olay dinleyicileri dizinizi korumak yerine, mevcut javascript olay sistemini kullanabilir ve genişlik değişikliği üzerine kendi etkinliğinizi tetikleyebilir ve olay işleyicilerini buna bağlayabilirsiniz.
$(window).bind('myZoomEvent', function() { ... });
function pollZoomFireEvent()
{
if ( ... width changed ... ) {
$(window).trigger('myZoomEvent');
}
}
Kısma / geri alma, işleyicinizin arama oranını azaltmaya yardımcı olabilir.
En azından kırılmaz bir alan (muhtemelen, gizli) içeren bir div enjekte ederek ve yüksekliğini düzenli olarak kontrol ederek metin yeniden boyutlandırma olaylarını ve yakınlaştırma faktörünü de alabilirsiniz. Yükseklik değişirse, metin boyutu değiştiyse (ve ne kadar olduğunu biliyorsunuz - bu da, aynı zamanda, pencere tam sayfa modunda yakınlaştırılırsa ve aynı yükseklikte / yükseklik oranı).
<script>
var zoomv = function() {
if(topRightqs.style.width=='200px){
alert ("zoom");
}
};
zoomv();
</script>
İOS 10'da, etkinliğe bir olay dinleyicisi eklemek touchmove
ve sayfanın geçerli etkinlikle yakınlaştırılıp yakınlaştırılmadığını tespit etmek mümkündür.
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;
});
Bu 9 yıllık bir soru olmasına rağmen, sorun devam ediyor!
Bir projede zoom hariçyken yeniden boyutlandırma algıladım, bu yüzden hem yeniden boyutlandırmak hem de birbirinden ayrı zum algılamak için çalışması için kodumu düzenledim. Çoğu zaman işe yarar, bu yüzden çoğu projeniz için yeterince iyiyse, bu yardımcı olacaktır! Şimdiye kadar test ettiğim zamanın% 100'ünü yakınlaştırmayı tespit ediyor. Tek sorun, eğer kullanıcı çıldırırsa (yani pencereyi büyük ölçüde yeniden boyutlandırırsa) veya pencere gecikirse, pencerenin yeniden boyutlandırılması yerine yakınlaştırma olarak tetiklenebilir.
Bu bir değişiklik tespit ederek çalışır window.outerWidth
veya window.outerHeight
bir değişiklik tespit ederken boyutlandırma penceresi olarak window.innerWidth
veya window.innerHeight
bir zoom olarak yeniden boyutlandırma penceresinden bağımsız.
//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);
Not: Çözümüm KajMagnus'unki gibi, ama bu benim için daha iyi çalıştı.
0.05
en azından iyi bir açıklama yapmadan gibi sihirli bir sayı kullanmanızı tavsiye etmem . ;-) Örneğin, Chrome'da, özellikle,% 10'un tarayıcının her durumda yakınlaştırma yapacağı en küçük miktar olduğunu biliyorum, ancak bunun diğer tarayıcılar için geçerli olduğu açık değil. fyi, kodunuzun her zaman test edildiğinden emin olun ve savunmak veya geliştirmek için hazırlıklı olun.
İşte temiz bir çözüm:
// 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);
});
Resize olayı , olayı ekleyerek window
ve ardından body
veya öğesinin veya . ( .GetBoundingClientRect () ) ile başka bir öğenin değerlerini okuyarak modern tarayıcılarda çalışır .
Daha önceki bazı tarayıcılarda, yeniden boyutlandırma olay işleyicilerini herhangi bir HTML öğesine kaydetmek mümkün olmuştur. Onresize özniteliklerini ayarlamak veya herhangi bir öğeye bir işleyici ayarlamak için addEventListener () kullanmak hala mümkündür. Ancak, yeniden boyutlandırma olayları yalnızca pencere nesnesinde tetiklenir (örn. Document.defaultView tarafından döndürülür). Yalnızca pencere nesnesine kayıtlı işleyiciler yeniden boyutlandırma olayları alır .
window.addEventListener("resize", getSizes, false)
function getSizes(){
let body = document.body
console.log(body.clientWidth +"px x "+ body.clientHeight + "px")
}
Başka bir alternatif : ResizeObserver API'sı
Düzeninize bağlı olarak, belirli bir öğeyi yeniden boyutlandırmayı izleyebilirsiniz.
Yakınlaştırma sırasında kap kutusu yeniden boyutlandırıldığı için bu, «duyarlı» düzenlerde iyi çalışır.
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 görevlerini kullanıcı hareketleri olaylarından aşırı yüklememeye dikkat edin . Yeniden çizmeye ihtiyaç duyduğunuzda requestAnimationFrame kullanın .
MDN'ye göre, "matchMedia" bunu yapmanın doğru yoludur https://developer.mozilla.org/en-US/docs/Web/API/Window/devicePixelRatio#Monitoring_screen_resolution_or_zoom_level_changes
bu biraz titiz çünkü her örnek aynı anda sadece bir MQ izleyebilir, bu yüzden herhangi bir yakınlaştırma seviyesi değişikliği ile ilgileniyorsanız, bir grup eşleştirici yapmanız gerekir ... ancak tarayıcı olayları yaymaktan sorumludur. oylamadan daha fazla performans gösterebilir ve geri çağrıyı kısaltabilir veya geri çekebilir veya bir animasyon karesine veya başka bir şeye sabitleyebilirsiniz - işte oldukça çabuk görünen bir uygulama, _throttle veya buna bağlıysanız her neyse değiştirmekten çekinmeyin.
Kod snippet'ini çalıştırın ve tarayıcınızda yakınlaştırın ve uzaklaştırın, biçimlendirmedeki güncellenen değeri not edin - Bunu yalnızca Firefox'ta test ettim! Ben herhangi bir sorun görüyorum biliyorum.
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 yaşındaki bir bağlantıya yanıt veriyorum ama sanırım burada daha kabul edilebilir bir cevap var,
.Css dosyasını şu şekilde oluşturun:
@media screen and (max-width: 1000px)
{
// things you want to trigger when the screen is zoomed
}
ÖRNEĞİN:-
@media screen and (max-width: 1000px)
{
.classname
{
font-size:10px;
}
}
Yukarıdaki kod, ekran yaklaşık% 125'e yakınlaştırıldığında '10px' yazı tipinin boyutunu yapar. '1000px' değerini değiştirerek farklı zoom seviyesini kontrol edebilirsiniz.
max-width
Ve yakınlaştırma oranı arasındaki ilişki nedir ?