web-dev-qa-db-ja.com

最近のすべてのブラウザでページのテーマレベルを検出する方法

  1. 最近のすべてのブラウザでページのズームレベルを検出する方法を教えてください。これ thread はIE7とIE8でそれを行う方法を教えてくれますが、私は良いクロスブラウザソリューションを見つけることができません。

  2. Firefoxは将来のアクセスのためにページのズームレベルを保存します。最初のページの読み込みで、ズームレベルを取得できますか?私が読んだどこかでズームの変更が発生したときに動作しますafterページがロードされています。

  3. 'zoom'イベントをトラップする方法はありますか?

私の計算のいくつかはピクセルベースで、ズームすると変動する可能性があるので、これが必要です。


@tflによる修正サンプル

このページはズーム時にさまざまな高さの値を警告します。 [jsFiddle]

<html>
    <head>
        <script src="http://ajax.googleapis.com/ajax/libs/jquery/1.3.1/jquery.min.js" type="text/javascript"/></script>
    </head>
    <body>
        <div id="xy" style="border:1px solid #f00; width:100px;">Lorem ipsum dolor sit amet, consectetur adipiscing elit. Pellentesque sollicitudin tortor in lacus tincidunt volutpat. Integer dignissim imperdiet mollis. Suspendisse quis tortor velit, placerat tempor neque. Cum sociis natoque penatibus et magnis dis parturient montes, nascetur ridiculus mus. Praesent bibendum auctor lorem vitae tempor. Nullam condimentum aliquam elementum. Nullam egestas gravida elementum. Maecenas mattis molestie nisl sit amet vehicula. Donec semper tristique blandit. Vestibulum adipiscing placerat mollis.</div>
        <button onclick="alert($('#xy').height());">Show</button>
    </body>
</html>
288
understack

今度は、この質問が最初に尋ねられたときよりもさらに大きな混乱です。私が見つけることができたすべての応答とブログ記事を読むことから、これは要約です。私はまた--- ズームレベルを測定するこれらすべての方法をテストするためのこのページ を設定しました。

編集(2011-12-12):複製できるプロジェクトを追加しました。 https://github.com/) tombigel/detect-zoom

  • IE8screen.deviceXDPI / screen.logicalXDPI(または、デフォルトのズームに対するズームレベルの場合はscreen.systemXDPI / screen.logicalXDPI
  • IE7var body = document.body,r = body.getBoundingClientRect(); return (r.left-r.right)/body.offsetWidth;この例 または この答え に感謝します)
  • FF3.5のみscreen.widthmedia query screen width(下記参照)(screen.widthはデバイスピクセルを使用しますが、MQ幅はCSSピクセルを使用するという事実を利用します) - Quirksmode widths )に感謝します
  • FF3.6:知られている方法はありません
  • FF4 +:メディア検索バイナリ検索(下記参照)
  • WebKithttps://www.chromestatus.com/feature/5737866978131968 (コメントでTeoに感謝)
  • WebKit-webkit-text-size-adjust:noneを使ってdivの適切なサイズを測定します。
  • WebKit:( r72591document.width / jQuery(document).width()Dirk van Oosterbosch)に感謝します )。 (デフォルトのズームに対する相対ではなく)デバイスのピクセルで比率を取得するには、window.devicePixelRatioを掛けます。
  • Old WebKit?(未確認):parseInt(getComputedStyle(document.documentElement,null).width) / document.documentElement.clientWidth(から この回答
  • Operadocument.documentElement.offsetWidth/position:fixed; width:100% divの幅。 ここからQuirksmodeのwidthsテーブル これはバグだと言っています; innerWidthはCSS pxであるべきです)。スクロールバーがであるスペースを含むビューポートの幅を取得するには、position:fixed要素を使用します。 document.documentElement.clientWidthはこの幅を除外します。これは2011年のいつか以来壊れています。私はもうOperaのズームレベルを取得する方法を知りません。
  • その他SebastianのFlashソリューション
  • 信頼性が低い:マウスイベントを監視し、screenXの変化/ clientXの変化を測定する

私はそれが公開されている任意の変数を知らないので、これはFirefox 4のための二分探索です。

<style id=binarysearch></style>
<div id=dummyElement>Dummy element to test media queries.</div>
<script>
var mediaQueryMatches = function(property, r) {
  var style = document.getElementById('binarysearch');
  var dummyElement = document.getElementById('dummyElement');
  style.sheet.insertRule('@media (' + property + ':' + r +
                         ') {#dummyElement ' +
                         '{text-decoration: underline} }', 0);
  var matched = getComputedStyle(dummyElement, null).textDecoration
      == 'underline';
  style.sheet.deleteRule(0);
  return matched;
};
var mediaQueryBinarySearch = function(
    property, unit, a, b, maxIter, epsilon) {
  var mid = (a + b)/2;
  if (maxIter == 0 || b - a < epsilon) return mid;
  if (mediaQueryMatches(property, mid + unit)) {
    return mediaQueryBinarySearch(
        property, unit, mid, b, maxIter-1, epsilon);
  } else {
    return mediaQueryBinarySearch(
        property, unit, a, mid, maxIter-1, epsilon);
  }
};
var mozDevicePixelRatio = mediaQueryBinarySearch(
    'min--moz-device-pixel-ratio', '', a, b, maxIter, epsilon);
var ff35DevicePixelRatio = screen.width / mediaQueryBinarySearch(
    'min-device-width', 'px', 0, 6000, 25, .0001);
</script>
264
yonran

私にとっては、Chrome/Webkitではdocument.width / jQuery(document).width()が機能しませんでした。水平スクロールバーが表示されるようにウィンドウを小さくして自分のサイトにズームインしたとき、document.width / jQuery(document).width()がデフォルトのズームで1に等しくありませんでした。これはdocument.widthがビューポートの外側のドキュメントの一部を含むためです。

window.innerWidthwindow.outerWidthの使用はうまくいきました。何らかの理由でChromeでは、outerWidthは画面のピクセルで測定され、innerWidthはCSSのピクセルで測定されます。

var screenCssPixelRatio = (window.outerWidth - 8) / window.innerWidth;
if (screenCssPixelRatio >= .46 && screenCssPixelRatio <= .54) {
  zoomLevel = "-4";
} else if (screenCssPixelRatio <= .64) {
  zoomLevel = "-3";
} else if (screenCssPixelRatio <= .76) {
  zoomLevel = "-2";
} else if (screenCssPixelRatio <= .92) {
  zoomLevel = "-1";
} else if (screenCssPixelRatio <= 1.10) {
  zoomLevel = "0";
} else if (screenCssPixelRatio <= 1.32) {
  zoomLevel = "1";
} else if (screenCssPixelRatio <= 1.58) {
  zoomLevel = "2";
} else if (screenCssPixelRatio <= 1.90) {
  zoomLevel = "3";
} else if (screenCssPixelRatio <= 2.28) {
  zoomLevel = "4";
} else if (screenCssPixelRatio <= 2.70) {
  zoomLevel = "5";
} else {
  zoomLevel = "unknown";
}
45
user800583

あなたが試すことができます

var browserZoomLevel = Math.round(window.devicePixelRatio * 100);

これにより、ブラウザのズーム率レベルがわかります。

ズームイベントをキャッチするにはあなたが使用することができます

$(window).resize(function() { 
// your code 
});
43
user1080381

私の同僚と私は https://github.com/tombigel/detect-zoom からスクリプトを使用しました。さらに、動的にsvg要素を作成し、そのcurrentScaleプロパティを確認しました。それはChromeとおそらくほとんどのブラウザでもうまく動作します。 FFでは、「テキストのみズーム」機能は無効にする必要があります。 SVGは、ほとんどのブラウザで サポートされている です。これを書いている時点では、IE10、FF19、Chrome28でテストされています。

var svg = document.createElementNS('http://www.w3.org/2000/svg', 'svg');
svg.setAttribute('xmlns', 'http://www.w3.org/2000/svg');
svg.setAttribute('version', '1.1');
document.body.appendChild(svg);
var z = svg.currentScale;
... more code ...
document.body.removeChild(svg);
16
Jay
zoom = ( window.outerWidth - 10 ) / window.innerWidth

必要なものはこれだけです。

11
Alex von Thorn

この記事は非常に役に立ちました。ヨンランに感謝します。彼が提供したテクニックのいくつかを実行している間に私が見つけたいくつかの追加の学習を伝えたいと思いました。 FF6とChrome 9では、JSからのメディアクエリのサポートが追加されました。これはFFのズームインを決定するために必要なメディアクエリアプローチを非常に単純化することができます。 MDN こちら のドキュメントを参照してください。私の目的のために、私はブラウザがズームインされたのかズームアウトされたのかを検出するだけでよく、実際のズーム倍率は必要ありませんでした。私は1行のJavaScriptで私の答えを得ることができました:

var isZoomed = window.matchMedia('(max--moz-device-pixel-ratio:0.99), (min--moz-device-pixel-ratio:1.01)').matches;

これと単一行のIE 8+およびWebkitソリューションを組み合わせると、ほんの数行のコードでアプリにアクセスしている大多数のブラウザのズームを検出できました。

11
brianh

私は2016年1月の時点でこの問題に対する解決策を持っています。Chrome、Firefox、そしてMS Edgeブラウザで動作確認済みです。

その原理は以下の通りです。離れている2つのMouseEventポイントを集める。各マウスイベントには、画面座標とドキュメント座標が付属しています。両方の座標系で2点間の距離を測定します。ブラウザの家具による座標系間の可変固定オフセットがありますが、ページがズームされていない場合、ポイント間の距離は同じである必要があります。 「遠く」(これを12ピクセルとします)を指定する理由は、小さなズームの変化(たとえば90%または110%)を検出できるようにするためです。

参照: https://developer.mozilla.org/en/docs/Web/Events/mousemove

ステップ:

  1. マウス移動リスナを追加する

    window.addEventListener("mousemove", function(event) {
        // handle event
    });
    
  2. マウスイベントから4つの測定値をキャプチャします。

    event.clientX, event.clientY, event.screenX, event.screenY
    
  3. クライアントシステムの2点間の距離d_cを測定する

  4. スクリーンシステム内の2点間の距離d_sを測定する

  5. D_c!= d_sの場合、ズームが適用されます。 2つの違いはズームの量を教えてくれます。

N.B.めったに距離計算をしない、例えば前のイベントからかけ離れた新しいマウスイベントをサンプリングできるとき。

制限事項:ユーザーはマウスを少なくとも少し動かすことを想定しています。このときまでズームは認識できません。

6
user1191311

私が思いついたのは、

1)position:fixedid = zoomdiv)で<div>width:100%を作る

2)ページが読み込まれたとき:

zoomlevel=$("#zoomdiv").width()*1.0 / screen.availWidth

そしてそれは私にとってctrl+ctrl-ズーミングのために働きました。

または私はアクティブなズームレベルを取得するために$(window).onresize()イベントに行を追加することができます


コード:

<script>
    var zoom=$("#zoomdiv").width()*1.0 / screen.availWidth;

    $(window).resize(function(){
        zoom=$("#zoomdiv").width()*1.0 / screen.availWidth;
        alert(zoom);    
    });
</script>
<body>
    <div id=zoomdiv style="width:100%;position:fixed;"></div>
</body>

P.S :これは私の最初の投稿です、間違いを許してください

3
Abhishek Borar

これは、Webキットベースのブラウザ(Chrome、Safari)で私にとって非常に役に立ちました。

function isZoomed() {
    var width, mediaQuery;

    width = document.body.clientWidth;
    mediaQuery = '(max-width: ' + width + 'px) and (min-width: ' + width + 'px)';

    return !window.matchMedia(mediaQuery).matches;
}

Firefoxでは動作しないようですが。

これはWebKitでも機能します。

var zoomLevel = document.width / document.body.clientWidth;
3
rudolfrck

Internet Explorer 7、8、9では、これは機能します。

function getZoom() {
    var screen;

    screen = document.frames.screen;
    return ((screen.deviceXDPI / screen.systemXDPI) * 100 + 0.9).toFixed();
}

丸め誤差を防ぐために "+ 0.9"が追加されています(そうでなければ、ブラウザのズームがそれぞれ105%と110%に設定されていると104%と109%になります)。

IE6ではズームが存在しないので、ズームを確認する必要はありません。

3
pench

基本的には、

  • ブラウザレベルのズーム*とシステムのズーム/ピクセル密度の両方を考慮したwindow.devicePixelRatio
    * - Mac/Safariのズームレベルでは考慮されません
  • メディアクエリ
  • vw/vh CSSユニット
  • ズームレベルの変更時にトリガされるresizeイベントにより、ウィンドウの有効サイズ変更が発生します。

これはnormal UXに十分なはずです。あなたがズームレベルを検出する必要があるならば、それは悪いUIデザインのサインかもしれません。

ピッチズームは追跡が難しく、現在は考慮されていません。

2
kirilloid

モバイルデバイス(Chrome for AndroidまたはOpera Mobile)では、window.visualViewport.scaleでズームを検出できます。 https://developer.mozilla.org/en-US/docs/Web/API/Visual_Viewport_API

Safariで検出する:document.documentElement.clientWidth/window.innerWidth(デバイスがズームされていない場合は1を返す)。

2
JIm

Chromeで

var ratio = (screen.availWidth / document.documentElement.clientWidth);
var zoomLevel = Number(ratio.toFixed(1).replace(".", "") + "0");
1

計算はまだいくつかのCSSピクセルに基づいています。彼らは今、画面上でちょうど異なるサイズです。それが全ページズームのポイントです。

192dpiデバイスのブラウザで何をしたいのでしょうか。そのため、通常は画像の各ピクセルに対して4つのデバイスピクセルが表示されます。 50%ズームで、このデバイスは1つのデバイスピクセルに1つのイメージピクセルを表示します。

1
Neil

これは、Chromeuser800583を契機にしています答え ...

私はこの問題に数時間を費やしました、そして、より良いアプローチを見つけませんでした、しかし:

  • 16 'zoomLevel'があり、10はありません
  • Chromeがフルスクリーン/最大化されている場合、比率はwindow.outerWidth/window.innerWidthであり、そうでない場合、比率は(window.outerWidth-16)/window.innerWidthのように見えますが、1番目のケースは2番目のケースに近づくことができます。

それで、私は以下に来ました...

しかし、このアプローチには限界があります。たとえば、アプリケーションウィンドウでアコーディオンを演奏する(ウィンドウの幅をすばやく拡大および縮小する)場合、ズームは変更されませんがズームレベル間にギャップが生じます(outerWidthとinnerWidthは変更されません)。正確に同じ時間に更新されます。

var snap = function (r, snaps)
{
    var i;
    for (i=0; i < 16; i++) { if ( r < snaps[i] ) return i; }
};
var w, l, r;
w = window.outerWidth, l = window.innerWidth;
return snap((w - 16) / l,
            [ 0.29, 0.42, 0.58, 0.71, 0.83, 0.95, 1.05, 1.18, 1.38, 1.63, 1.88, 2.25, 2.75, 3.5, 4.5, 100 ],
);

そしてあなたがその要素が欲しいなら:

var snap = function (r, snaps, ratios)
{
    var i;
    for (i=0; i < 16; i++) { if ( r < snaps[i] ) return eval(ratios[i]); }
};
var w, l, r;
w = window.outerWidth, l = window.innerWidth;
return snap((w - 16) / l,
            [ 0.29, 0.42, 0.58, 0.71, 0.83, 0.95, 1.05, 1.18, 1.38, 1.63, 1.88, 2.25, 2.75, 3.5, 4.5, 100 ],
            [ 0.25, '1/3', 0.5, '2/3', 0.75, 0.9, 1, 1.1, 1.25, 1.5, 1.75, 2, 2.5, 3, 4, 5 ]
);
0
jeum

この回答は、user1080381の回答に誤って戻ってきたdevicePixelRatioに関するコメントに基づいています。

デスクトップ、Surface Pro 3、およびSurface Pro 4を使用しているときにも、このコマンドが誤って戻ってくることがありました。

私が見つけたのは、それが私のデスクトップ上で動作したということですが、SP3とSP4は互いに、そしてデスクトップとは異なる番号を与えていました。

けれども私はSP3が私が期待していたズームレベルの1.5倍として戻って来ていたことに気づきました。ディスプレイの設定を見たとき、SP3は実際にはデスクトップの100%ではなく150%に設定されていました。

したがって、コメントを解決するには、返されたズームレベルを現在使用しているマシンの縮尺で除算する必要があります。

私は次のようにすることでWindowsの設定でスケールを取得することができました:

ManagementObjectSearcher searcher = new ManagementObjectSearcher("SELECT * FROM Win32_DesktopMonitor");
double deviceScale = Convert.ToDouble(searcher.Get().OfType<ManagementObject>().FirstOrDefault()["PixelsPerXLogicalInch"]);
int standardPixelPerInch = 96;
return deviceScale / standardPixelPerInch;

だから私のSP3の場合、これはこのコードが100%ズームでどのように見えるかです:

devicePixelRatio = 1.5
deviceScale = 144
deviceScale / standardPixelPerInch = 1.5
devicePixelRatio / (deviceScale / standardPixelPerInch) = 1

User1080381の元の答えに100を掛けると、100(%)のズームになります。

0
Cameron Weaver

私は---のためのこの解決策を持っていますモバイルのみ(Androidでテスト済み):

jQuery(function($){

zoom_level = function(){

    $("body").prepend('<div class="overlay" ' +
                'style="position:fixed; top:0%; left:0%; ' +
                'width:100%; height:100%; z-index:1;"></div>');

    var ratio = $("body .overlay:eq(0)").outerWidth() / $(window).width();
    $("body .overlay:eq(0)").remove();

    return ratio;
}

alert(zoom_level());

});

あなたがピンチ移動の直後にズームレベルを望むなら、あなたはおそらくレンダリングの遅れのために少しタイムアウトを設定しなければならないでしょう。

0
pmrotule

現在動作していますが、ブラウザごとに分離する必要があります。 Chrome(75)とSafari(11.1)で正常にテストされました(まだFFの方法を見つけていません)。また、Retinaディスプレイで正しいズーム値を取得し、サイズ変更イベントで計算がトリガーされます。

    private pixelRatio() {
      const styleString = "(min-resolution: 2dppx), (-webkit-min-device-pixel-ratio: 1.5),(-moz-min-device-pixel-ratio: 1.5),(min-device-pixel-ratio: 1.5)";
      const chromeRatio = (Math.round((this.window.outerWidth / this.window.innerWidth)*100) / 100);
      const otherRatio = (Math.round(window.devicePixelRatio * 100) / 100);
      const resizeValue = (this.isChrome()) ? chromeRatio : otherRatio;

      return resizeValue || (this.window.matchMedia && this.window.matchMedia(styleString).matches ? 2 : 1) || 1;
    }


  private isChrome():boolean {
    return (!!this.window.chrome && !(!!this.window.opera || this.window.navigator.userAgent.indexOf(' Opera') >= 0))
  }

  private chrome() {
    const zoomChrome = Math.round(((this.window.outerWidth) / this.window.innerWidth)*100) / 100;
    return {
      zoom: zoomChrome,
      devicePxPerCssPx: zoomChrome1 * this.pixelRatio()
    };
  }
0
Yogi

IEではこれをテストしませんでしたが、次のように要素elemを作成したとします。

min-width: 100%

それから

window.document.width / elem.clientWidth

ブラウザのズームレベルを指定します(document.body.style.zoomファクタを含む)。