Omega 4.x & matchMedia

Submitted by swim on Fri, 08/16/2013 - 04:08

I love Omega; even more so after recently developing a number of sites using 4.x. While the changes from 3.x have left many site builders unhappy; developers should be ecstatic. Ultimately Omega doesn't make as many assumptions & in turn provides a much blanker canvas than before. One of these freedoms is allowing devs to set their own (breakpoints) media queries. Not like you couldn't override those already setup in 3.x; most people just used the predefined ones as it served an easy win.

Now with the onus back on the developer to set the appropriate breakpoints, where & how do we react to these in JavaScript? Omega 3.x provided this functionality through binding & reacting on the responsivelayout body class.

As such;


(function($) {
  Drupal.behaviors.customBehavior = {
    attach: function(context) {
      $('body').bind('responsivelayout', function(e) {
        if ($('body').hasClass('responsive-layout-mobile')) {
          console.log(e);
        }
      });
    }
  };
})(jQuery);

Simple & clean.

Omega 4.x has a slightly different approach but one which provides much better support via matchMedia pollyfill. Please see Fubhy's example in the Omega issue queue. Extending this further below is an example illustrating very simple matchMedia by replacing the main menu with a mobile wrapper.


(function ($) {
  /**
   * Attach mobile menu.
   */
  function widthChange(mq) {
    if (mq.matches != true) {
      $('#block-main-menu').hide();
      var thediv = $('< l i class="mobile-menu" >< a id="mobile-menu-toggle" >MENU< / a >{C}{C}{C}');
      thediv.click(function() {
        $('#block-main-menu').slideToggle('fast');
      });
      $(thediv).appendTo('.l-region--navigation');
    }
    else {
      $('.mobile-menu').remove();
      $('#block-main-menu').show();
     }
  }

  /**
   * jQuery Example Behaviors
   */
  Drupal.behaviors.customBehaviors = {
    attach: function (context, settings) {
      var mobile_width = Drupal.settings.omega.mediaQueries['mobile-media-query'];

      // Media Queries Matching
      if (typeof matchMedia != 'undefined') {
        var mq = window.matchMedia(mobile_width);
        mq.addListener(widthChange);
        widthChange(mq);
      }
    }
  };
})(jQuery);

The mobile media query values are provided via a template hook as such. Please refer to caniuse for browser & device support.


/**
 * Implements template_preprocess_html()
 */
function THEME_preprocess_html() {
  $path = drupal_get_path('theme', 'THEME');
  $options = array('group' => JS_THEME);

  // Matchmedia library.
  drupal_add_js($path . '/js/matchMedia.js', $options);
  drupal_add_js($path . '/js/matchMedia.addListener.js', $options);

  drupal_add_js(drupal_get_path('theme', 'omega') . '/js/omega.mediaqueries.min.js', $options);

  drupal_add_js(array('omega' => array('mediaQueries' => array(
    'mobile-media-query' => 'all and (min-width: 768px)',
  ))), 'setting');
}