JavaScriptを使用して、ユーザーがページのズームを変更したことを検出することはできますか?「ズーム」イベントをキャッチしてそれに応答したいだけです(window.onresizeイベントに似ています)。
ありがとう。
JavaScriptを使用して、ユーザーがページのズームを変更したことを検出することはできますか?「ズーム」イベントをキャッチしてそれに応答したいだけです(window.onresizeイベントに似ています)。
ありがとう。
回答:
ズームがあるかどうかを積極的に検出する方法はありません。私はあなたがそれをどのように実装しようと試みることができるかについての良いエントリーをここに見つけました。
ズームレベルを検出する方法は2つあります。ズームレベルの変更を検出する1つの方法は、パーセント値がズームされないという事実に依存しています。パーセンテージ値はビューポートの幅を基準にしているため、ページズームの影響を受けません。2つの要素を挿入する場合、1つはパーセンテージでの位置、もう1つは同じ位置でのピクセルで、ページがズームされると離れます。両方の要素の位置の比率を見つけると、ズームレベルがわかります。テストケースを参照してください。 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 [archive])
IEではなく、Chrome、Firefox 3.6、Operaでテスト済み。
よろしく、マグナス
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比率= CSSピクセルに対する物理ピクセルの比率。
いずれかのズームページの場合、ビューポートピクセル(pxはピクセルとは異なります)が減少し、画面にフィットするため、比率(物理ピクセル/ CSS_px)を大きくする必要があります。
しかし、ウィンドウのサイズ変更では、画面サイズとピクセルが縮小されます。したがって、比率は維持されます。
だが
サイズ変更: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
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
[ユーザー補助]オプションのボタンをチェックします。デモは変更に反応しません。
ウィンドウ幅の変更を追跡することで、以前のソリューションを改善することを提案します。独自のイベントリスナーの配列を保持する代わりに、既存のJavaScriptイベントシステムを使用して、幅が変更されたときに独自のイベントをトリガーし、それにイベントハンドラーをバインドできます。
$(window).bind('myZoomEvent', function() { ... });
function pollZoomFireEvent()
{
if ( ... width changed ... ) {
$(window).trigger('myZoomEvent');
}
}
スロットル/デバウンスは、ハンドラーの呼び出し率を減らすのに役立ちます。
<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%検出されます。唯一の問題は、ユーザーがクレイジーになった場合(つまり、ウィンドウのサイズを大幅に変更した場合)、またはウィンドウが遅れた場合に、ウィンドウのサイズ変更ではなくズームとして起動する可能性があることです。
これは、の変化を検出することによって動作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);
});
resizeイベントは、にイベントをアタッチし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>
ユーザーのジェスチャーイベントからJavaScriptタスクをオーバーロードしないように注意してください。再描画が必要な場合は常にrequestAnimationFrameを使用してください。
MDNによると、「matchMedia」はこれを行う適切な方法ですhttps://developer.mozilla.org/en-US/docs/Web/API/Window/devicePixelRatio#Monitoring_screen_resolution_or_zoom_level_changes
各インスタンスは一度に1つのMQを見ることができるので、あなたが興味を持っているそうだとすれば、それは、ビット気難しいだ任意のあなたはマッチャーの束を作るために必要なズームレベルの変更..しかし、ブラウザがイベントを発するに担当しているので、それはおそらくですポーリングよりもさらにパフォーマンスが高く、コールバックを抑制またはデバウンスしたり、アニメーションフレームなどに固定したりできます。ここでは、実装がかなりスッキリしているようです。_throttleなどに既に依存している場合は、自由に入れ替えてください。
コードスニペットを実行し、ブラウザーでズームインおよびズームアウトします。マークアップの更新された値に注意してください-これはFirefoxでのみテストしました!lemmeは、問題があるかどうかを確認します。
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;
}
}
上記のコードは、画面が約125%にズームされたときにフォントのサイズを「10px」にします。「1000px」の値を変更することで、さまざまなズームレベルを確認できます。
max-width
ズーム比の関係は何ですか?