weblinc/media-match

Opera Misbehaving

gmclelland opened this issue · 7 comments

I'm running Opera 12.12 on the Mac. I noticed when I used the following everything works fine.

var mqSmallCheck = Media.match('screen and (max-width: 48.75em)');

When I use the code below, the event listeners don't work. The javascript is only executed once for whatever media queries are active.

var mqSmallCheck = window.matchMedia('screen and (max-width: 48.75em)');

var handleMqSmall = function(mql) {
    if (mql.matches) {
        // console.log('Media Small does match');
        // console.log(mql);

        $('#mobile-first-menu').once('mobile-first-menu').tinyNav({
          header: 'I Want To...'
        });

    } else {
        // console.log('Media Small does not match');
        // console.log(mql);
    }
};

handleMqSmall(mqSmallCheck);

mqSmallCheck.addListener(handleMqSmall);

Any thoughts on this? I hope that was clear enough, if not I can provide a better explanation. Basically I'm just switching from Media.match to window.matchMedia

@gmclelland

I just tested you code above in OSX Opera 12.12 and it fired as expected. I did have to stop resizing and release the window for the listener to fire.

Can you give it another try? It may be that Opera is evaluating the viewports state on interval rather than on resize. So when you resize, all intervals are paused until the window is released.

On Fri, Jan 18, 2013 at 8:40 AM, David Knight notifications@github.comwrote:

Can you give it another try? It may be that Opera is evaluating the
viewports state on interval rather than on resize. So when you resize, all
intervals are paused until the window is released.

Even when you stop resize resizing the window it doesn't seem to work. I
guess it's a problem with my js? I've attached my js if your interested.
Note: This js was written to work with the Drupal CMS.

Everything seems to work when I use Media.match instead of
window.matchMedia. With the exception of Opera, the only problem I have in
both cases is that if I resize the browser to much Chrome will crash (that
could be flexslider causing the problem).

Sorry, I didn't realize you can't attach files in github's comments.

// jquery.once documentation
// http://archive.plugins.jquery.com/project/once

// JavaScript should be made compatible with libraries other than jQuery by
// wrapping it with an "anonymous closure". See:
// - http://drupal.org/node/1446420
// - http://www.adequatelygood.com/2010/3/JavaScript-Module-Pattern-In-Depth
(function ($, Drupal, window, document, undefined) {

// find methond is twice as fast as (#tabs-1 .l-tab-inner)
var mainFlexslider = $("#tabs-1").find(".flexslider");
var raw_flexslider = mainFlexslider.html(); // grab the unaltered HTML and store it


var mqSmallCheck = Media.match('screen and (max-width: 48.75em)');
var mqNarrowCheck = Media.match('screen and (min-width: 47.75em) and (max-width: 57.99em)');
var mqMediumCheck = Media.match('screen and (min-width: 58em)');

var handleMqSmall = function(mql) {

    if (mql.matches) {
        // console.log('Media Small does match');
        // console.log(mql);

        $('#mobile-first-menu').once('mobile-first-menu').tinyNav({
          header: 'I Want To...'
        });

        $('#mobile-second-menu').once('mobile-second-menu').tinyNav({
          header: 'Departments...'
        });

        $('#mobile-third-menu').once('mobile-third-menu').tinyNav({
          header: 'Government...'
        });

        $('#mobile-fourth-menu').once('mobile-fourth-menu').tinyNav({
          header: 'Development...'
        });

        $('#mobile-fifth-menu').once('mobile-fifth-menu').tinyNav({
          header: 'Resident...'
        });

        $('#mobile-sixth-menu').once('mobile-sixth-menu').tinyNav({
          header: 'Business...'
        });

        // Init jquery-ui mobile navigation tabs
        $( "#mobile-tabs" ).once('mobile-tabs').tabs({
            collapsible: true,
            selected: -1
        });


    } else {
        // console.log('Media Small does not match');
        // console.log(mql);
    }
};

var handleMqNarrow = function(mql) {

    if (mql.matches) {
        // console.log('Media Narrow does match');
        // console.log(mql);

        // Init jquery-ui main site navigation tabs
        $( "#site-tabs" ).once('site-tabs').tabs({
            fx: {
                height: 'toggle',
                opacity: 'toggle'
            },

            collapsible: true
        });

        // remove the old flexslider (which has attached event handlers and adjusted DOM nodes)
        $("#tabs-1").find(".flexslider").remove();
        $("#tabs-1").find(".flex-viewport").remove();
        $("#tabs-1").find(".flex-control-nav").remove();
        $("#tabs-1").find(".flex-direction-nav").remove();

        // now re-insert clean mark-up so flexslider can run on it properly
        $("#tabs-1").find(".l-tab-inner").append("<div class='flexslider'></div>");
        $("#tabs-1").find(".flexslider").html(raw_flexslider);

        // Init Flexslider
        // $(".flexslider-two-column").flexslider({
        $("#tabs-1").find(".flexslider").flexslider({
          animation: "slide",
          slideshow: false,
          animationLoop: true,
          itemWidth: 300,
          itemMargin: 0,
          minItems: 2,
          controlsContainer: "#tabs-1 .l-tab-footer .l-limiter",
          maxItems: 2
        });

        // Add the animate.css classes
        $("#tabs-1 .flex-prev, #tabs-1 .flex-next").once('flexslider-animate').addClass("animated fadeInUp");

    } else {
        // console.log('Media Narrow does not match');
        // console.log(mql);
    }
};

var handleMqMedium = function(mql) {


    if (mql.matches) {
        // console.log('Media Medium does match');
        // console.log(mql);

        // Init jquery-ui main site navigation tabs
        $( "#site-tabs" ).once('site-tabs').tabs({
            fx: {
                height: 'toggle',
                opacity: 'toggle'
            },

            collapsible: true
        });

        // remove the old flexslider (which has attached event handlers and adjusted DOM nodes)
        $("#tabs-1").find(".flexslider").remove();
        $("#tabs-1").find(".flex-viewport").remove();
        $("#tabs-1").find(".flex-control-nav").remove();
        $("#tabs-1").find(".flex-direction-nav").remove();

        // now re-insert clean mark-up so flexslider can run on it properly
        $("#tabs-1").find(".l-tab-inner").append("<div class='flexslider'></div>");
        $("#tabs-1").find(".flexslider").html(raw_flexslider);

        // Init Flexslider
        // $(".flexslider-two-column").flexslider({
        $("#tabs-1").find(".flexslider").flexslider({
          animation: "slide",
          slideshow: false,
          animationLoop: true,
          itemWidth: 300,
          itemMargin: 0,
          minItems: 3,
          controlsContainer: "#tabs-1 .l-tab-footer .l-limiter",
          maxItems: 3
        });

        // Add the animate.css classes
        $("#tabs-1 .flex-prev, #tabs-1 .flex-next").once('flexslider-animate').addClass("animated fadeInUp");

    } else {
        // console.log('Media Medium does not match');
        // console.log(mql);
    }
};

// Initializes
handleMqSmall(mqSmallCheck);
handleMqNarrow(mqNarrowCheck);
handleMqMedium(mqMediumCheck);

// This illustrates calling a listener
// The listener will fire when the media query matches and then again when it no longer does
mqSmallCheck.addListener(handleMqSmall);
mqNarrowCheck.addListener(handleMqNarrow);
mqMediumCheck.addListener(handleMqMedium);

})(jQuery, Drupal, this, this.document);

I would uncomment those logs. You should see it fire when matched and unmatched.

I uncommented those logs and I see they are firing correctly in Opera. I also commented out all the flexslider code and now my browser doesn't crash any more and opera is working correctly with window.matchMedia.

So now it's time to refactor that flexslider code. Thanks again for helping me troubleshoot this.

FYI... I think Opera 12.12 is buggy when it comes to using window.matchMedia. The reason I say this is because I tested my site in slightly older version of Opera on Windows and everything was working great until it did an automatic update to 12.12. I even simplified the code by disabling the flexslider code.

What's really weird is that it the event listeners work in Opera Win/Mac when I have the console.log statements included. As soon as I comment out the console.log statements, everything stops working.

Very strange...

I can't leave the console.log statements in because they cause errors in older IE browsers.

After more testing it appears that Opera only works when you have the console.log statements AND the Console open when viewing the webpage. If you reload the webpage without the Dragonfly console, the page stops working.

Very strange...