foundation / foundation-sites

The most advanced responsive front-end framework in the world. Quickly create prototypes and production code for sites that work on any kind of device.
https://get.foundation
MIT License
29.66k stars 5.48k forks source link

Off Canvas suggestion for Adjusting on Resize (& removing Active class from Body tag) #786

Closed EnigmaSolved closed 11 years ago

EnigmaSolved commented 12 years ago

In 3.0.8 the Off Canvas js code for removing the active class on window resize has been commented out ( https://github.com/zurb/foundation/blob/master/vendor/assets/javascripts/foundation/jquery.offcanvas.js#L27 ). I am speculating this has something to do with an issue with Android since there is an additional bit about ignoring an Android useragent (if (!navigator.userAgent.match(/Android/i)) $('body').removeClass('active');). I don't know the particulars of what is going on there or why exactly this portion of code had to be temporarily disabled, but I think it would be good to have some method of removing the active class from the Body tag, especially for when the window/viewport changes such that a Media Query change takes effect.

With the current incarnation of the code you can end up with instances where the window is made large enough that you're no longer on the Small Screen media query, and so the Off Canvas Sidebar gets hidden, but because the active class still remains on the Body tag the page becomes a bit of mess (and mostly unusable). Now granted this circumstance should hopefully not occur very much in real world scenarios, but as the result is such a mess I've set about exploring some options for what we could use to trigger the active class being removed from the Body tag.

My first thought was to just detect the current window size within the resize event and then if the size was greater then the Small Media Query trigger to remove the active class. However, upon doing some research (see this excellent resource: http://tripleodeon.com/2011/12/first-understand-your-screen/ ) it seemed like reliably detecting the size was a bit questionable. If we were to still go this route I thought about something like the following pseudo-code:

if((touch && (window.outerWidth > (768-20))  ) || ( $(window).width() > (768-20) ) ){ /*remove 'active' class here*/  }

The idea with the above is: if the device supports touch then it might be mobile (though not guaranteed) so use the outerWidth property (since that seems to be the most reliable); subtract some number (I arbitrarily picked 20px) to subtract from our Media Query value to try to account for any browser chrome (especially for desktop); if touch is not supported then in theory we're on desktop, so just use jQuery width() to check.

Since I (understandably) didn't feel great about the above I came up with a 2nd idea that seems much more promising. The following is working code:

var $selector6 = $("[role='complementary']");
if ($selector6.length > 0) {
    //throttle for resize checking.
    var resizeOK = true, 
    resizeTimer = setInterval(function () {
        resizeOK = true;
    }, 250);
    $(window).resize(function() {
        // if (!navigator.userAgent.match(/Android/i)) $('body').removeClass('active');
        if (resizeOK === true) {
            resizeOK = false;
            if( $selector6.css('display') == 'none' ){ $('body').removeClass('active'); }
            console.log( $selector6.css('display') );  //for debugging.
        }
    });
}
// tested in: IE9, Firefox 14.0.1, Google Chrome 21.0.1180.75 m

What the above does is: check for the existence of the sidebar element (which has the role complimentary); then on window resize it checks if that element is still visible, and if it is NOT then the active class is removed from the Body tag; a throttle is added so that things are not firing more than necessary (credits for throttle code, and example of someone else trying to achieve something similar to our goal: http://stackoverflow.com/questions/8671001/trigger-event-using-jquery-on-css-change ).

The idea is that we only need to be sure that the active class is removed when the complimentary element exists, but is currently not displayed (because those are the circumstances where the active class remaining on the Body tag can give wonky results).

Since I don't know the reasons for commenting out the original Off Canvas code (eg, what issues there might be with Android), and since I don't have the ability to test this on various mobile devices I don't know if the above proposal addresses whatever the issues were or not. If the above seems likely to work fine and address whatever the issues were then let me know and I can turn this into a Pull Request. But since I don't know all the backstory I figured I'd start the conversation with the above and see where we go from there. :)

Sean

EnigmaSolved commented 12 years ago

I'm exploring options for using Javascript to detect when there is a Media Query change, which would be applicable to the above (as it could remove the need for the resize event that has been commented out in the source code), as well as for some other things I'm working on where I want certain Javascript behavior at certain screen sizes. So I thought I'd share some of the research I've gathered thus far: https://github.com/harvesthq/harvey http://adactio.com/journal/5429/ http://seesparkbox.com/foundry/breakpoint_checking_in_javascript_with_css_user_values https://github.com/JoshBarr/js-media-queries http://wickynilliams.github.com/enquire.js/ (Walkthrough: http://css-tricks.com/enquire-js-media-query-callbacks-in-javascript/) http://rezitech.github.com/syze/ (appears to be geared toward just testing onload, so would probably still depend on resize event for detecting changes)

It would awesome to have something like the above built into Foundation for detecting Media Query changes. :)

Edit: Added a few more links.

hatefulcrawdad commented 11 years ago

Closing this now since it references a bunch of closed issues. Please submit a new issue if you still see this as an issue we should tackle.