2

I try now for half a day to detect a DPI change with jQuery.

The scenario is the following:
I have a MacBook Pro (Retina) and a regular screen connected to it. When I move my browser window from the regular one to the MacBooks I want to detect the DPI change.

Obviously events like

$(window).resize(function() {
  if (window.devicePixelRatio && window.devicePixelRatio >= 1.3) {
    // do retina
  } else {
    // do standard
  }
}

and

$(document).resize(function() {
  if (window.devicePixelRatio && window.devicePixelRatio >= 1.3) {
    // do retina
  } else {
    // do standard
  }
}

dont work for this, since the resolution just changed physically.

Is there any way to realize this?

2 Answers2

0

How about using transition events and a media query

CSS:

body {
  transition:font-size 1ms;
  font-size:1em;
}
@media  only screen and (min-device-pixel-ratio: 2), 
    only screen and (min-resolution: 192dpi) {
      body {
        font-size:1.1em
      }
}

JS:

$("body").bind("transitionend webkitTransitionEnd oTransitionEnd MSTransitionEnd", function(){
  $(document).trigger('dpiChange', {pixelRatio: window.devicePixelRatio})
});

$(document).on('dpiChange', function (e, data) {
  if (data.pixelRatio >= 1.3) {
    // do retina
    console.log('retina')
  } else {
    // do standard
    console.log('standard')
  }
})

JSBIN:
http://jsbin.com/siramo/1/edit?html,css,js,console

Great Retina Specific Media Query Tutorial:
https://css-tricks.com/snippets/css/retina-display-media-query/

Shanimal
  • 11,517
  • 7
  • 63
  • 76
  • The JS solution sadly didn't worked for me.* (Safari, Chrome, Firefox) Would have been so elegant. (* - on Chrome I got 2 times the 'retina' log, but didn't get how to reproduce it) The 'Great Retina Specific Media Query Tutorial' I already read, it's really awesome. Have it in use on the most parts of my site, but some things cant be done with CSS. :/ – Daniel Neubert Aug 24 '16 at 09:20
  • Bummer, what browser are you using? These events should fire for all of them. I have two monitors and was dragging JSBIN example from one monitor to the other and it was working for me. – Shanimal Aug 24 '16 at 16:15
0

I have just tried with my second monitor having a different resolution.

When I move the browser from the first to second screen and back I have to resize the browser so your approach is correct:

var width = screen.width;
var height = screen.height;

$(window).on('resize', function(e) {
  if (screen.width !== width || screen.height !== height) {
    width = screen.width;
    height = screen.height;
    
    console.log('resolution changed!');
  }
});

But, if you don't want to adjust the browser height or width this event will be never triggered. In this case another approach can be used as a workaraound: two functions in order to:

  • on time basis test the current browser resolution against the old one
  • stop this timer
  • use the event

(function ($) {

  var width = screen.width;
  var height = screen.height;
  var idTimer = null;

  $.fn.startCheckResolution = function (interval) {
    interval = interval || 50;
    idTimer = setInterval(function () {
      if (screen.width !== width || screen.height !== height) {
        width = screen.width;
        height = screen.height;
        $(this).trigger('resolutionChanged');
      }
    }.bind(this), interval);
    return this;
  };

  $.fn.stopCheckResolution = function () {
    if (idTimer != null) {
      clearInterval(idTimer);
      idTimer = null;
    }
  };

}(jQuery));

$(window).startCheckResolution(1000).on('resolutionChanged', function(e) {
  console.log('Resolution changed!');
  // $(window).stopCheckResolution();
});
<script src="https://code.jquery.com/jquery-1.12.4.min.js"></script>
gaetanoM
  • 41,594
  • 6
  • 42
  • 61