1

I want to use a simple function to hide/show content only on mobile devices.
The function itself is pretty straightforward. I use this code here for that:

    $('.toggleMobile').click(function() {
        var hideableContent = $(this).parent().find('.hideable');
        hideableContent.slideToggle('medium');
    });

So... nothing fancy, i know.

It gets more complicated as i try to detect the browser viewport.
I think I took care of that by using the following lines (you probably will find ways to improve it):

    function whatMedia() {

        var viewport = $(window).width();
        var mediaType;

        if ( viewport < 767 )
            mediaType = 'mobile';
        else if ( (viewport >= 767) && (viewport < 991) )
            mediaType = 'tablet';
        else
            mediaType = 'desktop';

        return mediaType;
   }

Now i just need a function that gets triggered only when the viewport is mobile (maybe the problem is here?):

   function toggleMobile(mediaType) {

        if ( mediaType === 'mobile' ) {
            $('.toggleMobile').click(function() {
                var hideableContent = $(this).parent().find('.hideable');
                hideableContent.slideToggle('medium');
            });
        }
    }

I have no problem checking for the viewport the first time the page is loaded. I just use this (very simple bit of code):

    // Check media type and activate accordingly
    var mT = whatMedia();
    toggleMobile(mT);

So far so good. Now comes the fun part:
I want to be able to detect if a user resizes the browser window and activate/deactive the toggleMobile() function accordingly..

I could do this:

    $(window).resize(function() {
        var mT = whatMedia();
        toggleMobile(mT);
    }

As you perhaps already know, this $(window).resize thing makes Webkit and other browsers go a bit crazy, and repeat the function as long as the user resizes the window.
This is good or bad depending on your take on it.
I personally don't want this to happen, so i use this function i found on the forums:

    var waitForFinalEvent = (function () {

        var timers = {};

        return function (callback, ms, uniqueId) {
            if (!uniqueId) {
                uniqueId = "Don't call this twice without a uniqueId";
        }
            if (timers[uniqueId]) {
                clearTimeout (timers[uniqueId]);
            }
            timers[uniqueId] = setTimeout(callback, ms);
        }

   })();

My resize event looks like this:

    $(window).resize(function() {
        waitForFinalEvent(function() {
            var mT = whatMedia();
            toggleMobile(mT);
        }, 500, '1');         
    }

This certainly does delay the calculation of the browser window on resize but i can't make the function inside it work.
I don't know what the problem is :(
Th function gets triggered two or more times, and even when the viewport is recognized as desktopor tablet.

Community
  • 1
  • 1
  • I think you should have a look at [Modernizr](http://www.modernizr.com/). – Pointy Aug 30 '11 at 03:38
  • 1
    Every time you call `toggleMobile` you add another `click` event handler (if `mediaType` is 'mobile'), without ever removing the old ones. You should just have one event handler, and check `mediaType` inside it. – sje397 Aug 30 '11 at 03:46
  • @Pointy I wasn't aware of that feature of Modernizr. Will definitely be checking that out. – el_carlismo Aug 31 '11 at 04:48
  • @sje397 Thank you for pointing that out. My function now looks like this: `function toggleMobile(mediaType) { $('.toggleMobile').click(function() { if (mediaType === 'mobile') { var hideableContent = $(this).parent().find('.hideable'); hideableContent.slideToggle('medium'); } }); }` It still doesn't work. The same problem arises (it gets triggered every time). Is this what you meant or am i getting it wrong? thanks. again. – el_carlismo Aug 31 '11 at 04:56
  • Can you please elaborate on the "I can't make the function inside it work"? I didn't try the code, but looking at it, it seems good (except for the ever growing number of events that was already pointed out). To fix that, you can simply remove all the click events on the element before adding the new one, given that no other part of the code adds a click event to the same `.hideable` elements. – diego nunes Apr 29 '13 at 23:02

1 Answers1

0

In the togglemobile function, you just register the click event but nothing else, if you want to trigger it you could do

   $('.toggleMobile').click(function() {
        var hideableContent = $(this).parent().find('.hideable');
        hideableContent.slideToggle('medium');
   }).trigger('click');

this would trigger the click event and run the code, alternatively you could hide the element immediately instead.

EDIT: I'll revise my answer a bit. First we register the click event for the element that while slideToggle the content:

   $('.toggleMobile').click(function() {
        if(whatMedia() === "mobile") {
           var hideableContent = $(this).parent().find('.hideable');
           hideableContent.slideToggle('medium');
        }
   });

then in the toggleMobile(mt); function we now hide the content if the size goes over to mobile media

function toggleMobile(mediaType) {

    if ( mediaType === 'mobile' ) {
        var hideableContent = $(".toggleMobile").parent().find('.hideable');
        hideableContent.slideToggle('medium');
    }
}

this is if i understand, what you want?

I see that this is probably what @sje397 meant.

Joakim
  • 2,217
  • 15
  • 20
  • Hi @Joakim. Thank you for your answer. I'm not sure i understand you. The function gets always triggered. Actually it gets triggered more times than i need it to. I tried adding what you advised and this made it triggered even more times. Have any idea why? – el_carlismo Aug 31 '11 at 05:03
  • It may be what @sje397 meant... I'll try your approach and give you the heads up on it :) – el_carlismo Aug 31 '11 at 05:54