The "omega-mediaqueries.js" adds classes to the body, depending on the current width of the screen, e.g. "responsive-layout-normal" or "responsive-layout-mobile".

I cannot use those classes if I want to react on them in my own javascript file.
if($("body", context).hasClass("responsive-layout-normal")) ...

It works though, if I use some other class of the body, e.g.
if($("body", context).hasClass("front")) ...

My javascript file is set as follows in the info file:

libraries[custom_js][name] = Custom javascript
libraries[custom_js][description] = Custom javascript files for this theme.
libraries[custom_js][js][0][file] = scripts.js
libraries[custom_js][js][0][options][weight] = -20

In the omega.info file the mediaqueries library is declared as follows:

libraries[omega_mediaqueries][name] = Media queries
libraries[omega_mediaqueries][description] = Provides a tiny JavaScript library that can be used in your custom JavaScript.
libraries[omega_mediaqueries][js][0][file] = omega-mediaqueries.js
libraries[omega_mediaqueries][js][0][options][weight] = -19

I also tried to set my weight to "-18" but that didn't work too...

Thanks for any help!

Comments

himerus’s picture

The mediaqueries.js also implements a trigger that can be used to fire events when a different responsive layout is changed.

$(window).resize(function() {
  $('body.front').one('responsivelayout', function(e, d) {
    if(d.from != d.to) {
      Drupal.YOURFUNCTION(d.to);
    }
  });
});

or

$(window).resize(function() {
  $('body.front').bind('responsivelayout', function(e, d) {
    if(d.from != d.to) {
      Drupal.YOURFUNCTION(d.to);
    }
  });
});
drupov’s picture

Thanks for the quick answer!

The problem I have is that my code does not apply initially - not after resizing the window, but when the page is loaded right away in e.g. normal mode.

If I use the code above, the changes apply after resizing, but not initially. So how can my

if($("body", context).hasClass("responsive-layout-normal")) ...

fire at the start (=when the page has finished loading)?

Can I ask also, what do the parameters "e" and "d" stand for?

P.S. Great functionality BTW!

drupov’s picture

What did the job for me was to add "window.onload = function() {...}" before the if -statement.

(function($) {
  Drupal.behaviors.menuItems = {
    attach: function(context) {
      window.onload = function() {
        if($("body", context).hasClass("responsive-layout-normal")) {
          ...code
        }
      }
    }
  };
})(jQuery);

But is the correct way? Thanks!

drupov’s picture

Funny enough in my scripts.js file which loads last (weight 20) I can check for any of the classes that the body has, like:

<body class="html not-front logged-in admin-menu omega-mediaqueries-processed alpha-debug-processed responsive-layout-normal">

So e.g. if I check if the body tag has the class "html":

(function($) {
  Drupal.behaviors.myCustomBehavior = {
    attach: function(context) {
      if($("body").hasClass("html")) {
        alert("Yes, it has!");
      }
  };
})(jQuery);

I get the "alert".

But if I check the body for the class "responsive-layout-normal"

(function($) {
  Drupal.behaviors.myCustomBehavior = {
    attach: function(context) {
      if($("body").hasClass("responsive-layout-normal")) {
        alert("Yes, it has!");
      }
  };
})(jQuery);

the alert doesn't appear, but the class is there, as firebug says.

Is this class perhaps added somehow later? The other classes are being found...

drupov’s picture

Status:Active» Closed (works as designed)

Found the answer in http://drupal.org/node/1299286#comment-5412342 (thanks @bc and @himerus)

You can bind to the jQuery global event 'responsivelayout':

jQuery('body').bind('responsivelayout', function() { /* handle event */ } );

The global event is defined in omega-mediaqueries.js with $.event.trigger. Because it's global, you can bind a listener to any object in the DOM.

So my custom code should look like:

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

Hope this saves someone an hour or like me a day.

wheatpenny’s picture

This tutorial helped me out a lot to implement jQuery only in the mobile layout:

http://ivanchaquea.com/creating-responsive-menu-omega-subthemes.html

I wanted to note it here as yet another resource.

areikiera’s picture

Closed my own issue http://drupal.org/node/1593320 as a duplicate.

Thank you so much to mrupal for providing this code! I already got lost in the research, and finding this was an enormous help! There is a missing } in the code in comment #5; including the fix below:

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

I would like to expand this conversation to ask how someone could use this behavior to keep a div from loading entirely. Some blocks take a lot of time to load, and to really be optimized for mobile users, it would be great to use the above function to stop a div from loading regardless of the contents. In my example, I've got a Views Slideshow that I'm trying to hide, and as a newbie to jQuery, I've been using:

(function($) {
  Drupal.behaviors.hidediv = {
    attach: function(context) {
      $('body').bind('responsivelayout', function(e, d) {
        if($(this).hasClass("responsive-layout-mobile")) {
      $('#block-views-ec075ba04b7b1118381953f9ad70acc9').remove();
        }
      });
    }
  };
})(jQuery);

But the div doesn't get removed until after the slideshow is loaded. Is this a question for the views issue queue, or is it possible *fingers crossed* to have a blanket function that could be used to disable any div (or region) that we don't want to include on mobile versions for this theme? I know that's a desired feature by a lot of folks.

Thanks for any help! I know I'm asking more for a jQuery tutorial here than specifically Omega support, but I think it would be fantastic to be able to do this in cases where an entirely different theme isn't really needed, but a few little resource heavy or unnecessary blocks could be easily hidden.

Thanks for the awesome theme!

k_’s picture

Category:task» support
Status:Closed (works as designed)» Active

I want to redraw a JS-rendered object as @media width changes. Eventually, I'll draw a _different_ JS object per @media width.

My page markup includes

<div class="splash-wrap">
<div id="splash">
<dl>
...

With mediaqueries enabled, Omega populates the DOM's body classes as,

<body class="html front not-logged-in page-node omega-mediaqueries-processed responsive-layout-wide">

Following advice in this post, the JS init for this page includes,

(function($) {
Drupal.behaviors.fpAcc = {
  attach: function(context,settings) {

   $('body',context).once('splash',function(){
    $('body').bind('responsivelayout', function(e,d) {

     if($(this).hasClass("responsive-layout-wide")) {
      $('#splash',context).eAcc(A);

     } else if($(this).hasClass("responsive-layout-normal")) {
      $('#splash',context).eAcc(B);

     } else if($(this).hasClass("responsive-layout-narrow")) {
      $('#splash',context).eAcc(C);

     }
    });
   })
  }
};
})(jQuery);

With this in place, when I change viewport size across Omega-defined @media transitions, the JS-objects (here, eAcc) does render/change.

BUT ... something's not quite right about its behavior. Animations lag and are jerky, click actions have unpredictable behaviors, etc.

If I simply complete-reload the page, all's OK again.

I suspect that the DOM needs to be cleared before the re(init) of the eAcc() after a width switch.

I've played with detach(), remove(), detroy(), etc. but only manage to make the entire div's content to hide/disappear -- but not reappear/reload.

Either my syntax is wrong, or bind() gets confused after removal of the DOM element -- I *think* that's a case for delegate() (as live() is deprecated ...).

Simply not sure at this point.

For the Drupal.behavior stanza above, what's the right method to "ud-draw" and re-draw the JS-rendered object to avoid these possible 'collisions'?

Kate

covenantd’s picture

Re: comment 3 -
Tracking this down, it seems like a really odd issue. For some reason the $(window).load() chained call is never made in omega-mediaqueries.js. For some reason the load event is never triggered. The really bizarre thing is one of our domains - with the exact same code-base - does trigger it.

And even weirder...I dropped this in at the top of my sub-theme custom JS file and voila, now the $(window).load() is called even inside omega-mediaqueries.js

$(window).load(function () {
  // doesn't make any sense, but this causes it to be called elsewhere
});
Nick Lewis’s picture

Status:Active» Needs review

Please respond #8, and #9 if this solves your issue.
Re: #9 - I'm guessing window.load has already been called by the time media queries fires?
Re: #8 you're using Drupal.behaviors which is great in most circumstances, but not this one, I think...

The deal is that you want to bind this stuff to window.load or window.resize. Drop this badboy in your script, and it should give you the info you need to make your adjustments.

$(window)
  .resize(function() {
    $('body').bind('responsivelayout', function(e, d) {
      else {
        console.log(d.from, 'previous layout');
        console.log(d.to, 'to new layout');
        // Drupal.doWhatYouWill(d.from, d.to);
    });
  })
  .load( function() {
    $('body').bind('responsivelayout', function(e, d) {
      console.log(d.from, 'previous layout');
      console.log(d.to, 'to new layout');
      // Drupal.doWhatYouWill(d.from, d.to);
    });
  });
covenantd’s picture

Bingo! Two notes on it:

  1. There is a rogue "else" on line 4 above
  2. I only needed .load() because .resize() was already working for me

Now that we've established your genius-ness, any thoughts on why window.load would be called by this time? I've searched my entire sites directory for anything calling "(window).load" but only found one disabled module (ajaxblocks) which I've deleted and no change. No biggie since it is working, but seems peculiar.

covenantd’s picture

I take back :)

Just noticed while working on another part of the site, that I'm getting:

Uncaught TypeError: Property 'fpSlideshowize' of object #<Object> is not a function my_js_file_name.js:357
   (anonymous function) my_js_file_name.js:357
   c.event.handle jquery.js:64
   c.event.add.h.handle.o jquery.js:57
   c.event.trigger jquery.js:62
   c.event.trigger.a.result jquery.js:61
   b.extend.each jquery.js:33
   c.event.trigger jquery.js:61
   setCurrentLayout omega-mediaqueries.js:24
   Drupal.behaviors.omegaMediaQueries.attach omega-mediaqueries.js:106
   c.event.handle jquery.js:64
   c.event.add.h.handle.o jquery.js:57
   c.event.trigger jquery.js:62
   c.fn.extend.trigger jquery.js:75
   b.extend.each jquery.js:34
   b.fn.b.each jquery.js:27
   c.fn.extend.trigger jquery.js:75
   Drupal.behaviors.omegaMediaQueries.attach omega-mediaqueries.js:108
   c.event.handle jquery.js:64
   c.event.add.h.handle.o jquery.js:57
   (anonymous function)

I tried moving this to the bottom of everything enclosed in (function ($) { as well as flat out below it (replacing $ with jQuery of course). No dice.

So now with the behavior not yet loaded when $(window).load is called, I'm stumped.

Exact code to ensure non-craziness:

jQuery(window)
    .load( function() {
        jQuery('body').bind('responsivelayout', function(e, d) {
        console.log(d.from, 'previous layout');
        console.log(d.to, 'to new layout');
        Drupal.behaviors.mySiteBehaviorName(d.from, d.to);
        });
});
devitate’s picture

Careful what we are telling people here.

"$('body.front').bind " only needs to fire once. "onresize" will just add a lot more work for the browser.