Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Jquery resize() causing screen flickering and div offset

The Background:

I am trying to create a system that allows to scroll through a kind of map using mouse scroll up and mouse scroll down like so:

 -------
|       |
|   1   |
|       |
 -------
 -------    -------   -------   -------
|       |  |       | |       | |       |
|   2   |  |   3   | |   4   | |   5   |
|       |  |       | |       | |       |
 -------    -------   -------   -------
                                -------
                               |       |
                               |   6   |
                               |       |
                                -------

Each of the boxes above is reset in javascript to be the height and width of the browser. When you scroll your mouse up and down, the browser will scroll to the equal position in the map, starting with div 1, and then 2, and so on. This positioning is set via my scroll funciton, which listenes for mouse scrolls and adds the appropriate padding to the top and margin to the left to create the illusion of the map above.

Here is the codepen to it:

http://codepen.io/lorenzoi/pen/mxejJ

And here is the javascript to it:

$(function(){

    $(window).on('resize', function(){
        var $divs = $('.vertical, .horizontal > div'),
        ww =  $(this).width(),
        wh =  $(this).height();

        $divs.css({
            height : wh,
            width : ww
        });

        $('.horizontal').each(function(){
            var $container = $(this),
            nbChildren = $container.children().length;
            posY = $container.offset().top,


            $container.css({
                height: ww*(nbChildren-1) + wh,
                width: ww*(nbChildren)
            });
        });
    }).trigger('resize');

    $(window).on('scroll', function(){
        var wh = $(window).height(),
        scroolTop = $(window).scrollTop();

        $('.horizontal').each(function(){
            var $container = $(this),
            posY = $container.offset().top,
            height = $container.height(),
            nbChildren = $container.children().length,
            marginMax = $container.width()/nbChildren*(nbChildren-1),
            marginL = scroolTop - posY;

            if(marginL<0) marginL = 0;
            else if (marginL>marginMax) marginL = marginMax;
            $container.css('marginLeft', -marginL);
            $container.css('paddingTop', marginL);
        });
    }).trigger('scroll');

});

The Problem:

Resizing the window creates a weird div offset that fixes itself when the scroll function is called for divs 2 to 5. On resizing when in those divs, they seem to offset themselves and then only get fixed when the scroll function is called.

.trigger('resize'); should always be called, yes? I dont know why it only gets called when the scroll function is made.

How can this be remedied?

like image 393
lorenzoid Avatar asked Apr 19 '13 19:04

lorenzoid


2 Answers

Using a timer should just be enough:

$(function(){
    var timeoutResize;

    $(window).on('resize', function(){
        clearTimeout(timeoutResize);
           timeoutResize = setTimeout(function(){
           var $divs = $('.vertical, .horizontal > div'),
           ww =  $(this).width(),
           wh =  $(this).height();

           $divs.css({
               height : wh,
               width : ww
           });

           $('.horizontal').each(function(){
               var $container = $(this),
               nbChildren = $container.children().length;
               posY = $container.offset().top,


               $container.css({
                   height: ww*(nbChildren-1) + wh,
                   width: ww*(nbChildren)
               });
           });
       },100);
    }).trigger('resize');

    ...

});
like image 55
A. Wolff Avatar answered Oct 21 '22 15:10

A. Wolff


. . You need to consider that whenever a user resize the window vertically, the scroll position will be affected and it should also affect your background scrolling (because it is based on the current scroll position).

. . The simplest fix will be simply call $(window).trigger('scroll'); at the end of the resize handler code, so you keep it DRY. I made this change on my CodePen fork. Check it out.

like image 32
diego nunes Avatar answered Oct 21 '22 15:10

diego nunes