Search code examples
javascriptjqueryretinahighdpi

jQuery detect DPI change


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?


Solution

  • 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>