Hello and welcome to our community! Is this your first visit?
Register
Enjoy an ad free experience by logging in. Not a member yet? Register.
Results 1 to 7 of 7
  1. #1
    New Coder
    Join Date
    Jan 2006
    Posts
    89
    Thanks
    3
    Thanked 0 Times in 0 Posts

    Unhappy .resize() & window.width(); calculations giving different results on various browsers

    I am having a nightmare with a function which tries to resize images according to the browser height and then position them accordingly. It takes into account the aspect ratio of the image too.

    I have tried various solutions. Wrapping the function in a timeout didn't seem to work even though various sources said this should fix it in IE, and I've also tried this plugin http://benalman.com/projects/jquery-resize-plugin/ with no success.

    Here is my code which initialises the bxslider and calls the resize function:

    Code:
    var slider = $('.bxslider');
    slider.length && slider.bxSlider({
        speed               :   2000,
        pager               :   false,
        controls            :   true,
        auto                :   true,
        autoHover           :   true,
        mode                :   'horizontal',
        pause               :   6000
    });
    
    $('#slider-wrapper').length && main.fullScreenImages();
    The main resize function is called on page load, and then on resize above 768px wide:

    Code:
    main.fullScreenImages = function() {
        main.resizeSlider();
    
        $(window).resize(function() {
            if ($(window).width() > 768) {
                main.resizeSlider();
            }
        });
    },
    
    main.resizeSlider = function() {
        var slides              = $('#slider-wrapper').find('li'),
            images              = $('.resize-img'),
            windowWidth         = $(window).width(),
            windowHeight        = $(window).height(),
            windowAspectRatio   = windowWidth/windowHeight;
    
        // resize li height to full screen
        slides.each(function() {
            var $this           = $(this),
                image           = $this.find('img'),
                imgWidth        = image.width(),
                imgAspectRatio  = image.width() / image.height(),
                imgHeight       = imgWidth / imgAspectRatio,
                widthRatio      = windowWidth / imgWidth,
                heightRatio     = windowHeight / imgHeight,
                widthDiff       = heightRatio * imgWidth,
                heightDiff      = widthRatio * imgHeight;
    
            $this.css('height', windowHeight);
    
            if (heightDiff > windowHeight) {
                image.css({
                    width   : windowWidth + 'px',
                    height  : heightDiff + 'px',
                    top     : (imgHeight - windowHeight) / -2 + 'px',
                    left    : '0'
                });
            } else {
                image.css({
                    width   : widthDiff + 'px',
                    height  : windowHeight + 'px',
                    top     : '0',
                    left    : (imgWidth - windowWidth) / -2 + 'px'
                });
            }
        });
    },
    Everything works fine in Chrome on resize, but it goes slightly wrong in IE and Firefox. It seems to be the top CSS calculation that those browsers don't like and the image is being positioned in the wrong place. It also seems to be much worse when the browser is maximised and minimised and not actually dragged around to resize.

    Can anyone help please? Any help is much appreciated.

  • #2
    Supreme Master coder! glenngv's Avatar
    Join Date
    Jun 2002
    Location
    Philippines
    Posts
    11,042
    Thanks
    0
    Thanked 251 Times in 247 Posts
    window.resize is called multiple times (in different frequencies for each browser) as window is being resized. Try using the debounce function to make sure that resize is only called once.

    http://davidwalsh.name/function-debounce
    http://unscriptable.com/2009/03/20/d...cript-methods/

  • Users who have thanked glenngv for this post:

    jpmad4it (11-07-2013)

  • #3
    New Coder
    Join Date
    Jan 2006
    Posts
    89
    Thanks
    3
    Thanked 0 Times in 0 Posts
    Quote Originally Posted by glenngv View Post
    window.resize is called multiple times (in different frequencies for each browser) as window is being resized. Try using the debounce function to make sure that resize is only called once.

    http://davidwalsh.name/function-debounce
    http://unscriptable.com/2009/03/20/d...cript-methods/
    Hi there thanks for the advice.

    I'm using a jQuery version for the debounce (https://github.com/louisremi/jquery-smartresize/), the code for which is as follows:

    Code:
    (function($) {
    
    var $event = $.event,
            $special,
            resizeTimeout;
    
    $special = $event.special.debouncedresize = {
            setup: function() {
                    $( this ).on( "resize", $special.handler );
            },
            teardown: function() {
                    $( this ).off( "resize", $special.handler );
            },
            handler: function( event, execAsap ) {
                    // Save the context
                    var context = this,
                            args = arguments,
                            dispatch = function() {
                                    // set correct event type
                                    event.type = "debouncedresize";
                                    $event.dispatch.apply( context, args );
                            };
    
                    if ( resizeTimeout ) {
                            clearTimeout( resizeTimeout );
                    }
    
                    execAsap ?
                            dispatch() :
                            resizeTimeout = setTimeout( dispatch, $special.threshold );
            },
            threshold: 150
    };
    
    })(jQuery);



    I've then wrapped my function in the new resize function:


    Code:
    		
    
    $(window).on("debouncedresize", function( event ) {
    
    			if ($(window).width() >= 768) {
    				$('#slider-wrapper').show();
    				main.resizeSlider();
    			}  else {
    				$('#slider-wrapper').hide();
    				$('#header').css({ height :  189 + 'px' });
    			}
    			
    			$(window).trigger( "debouncedresize" );
    		});

    This seems to work! I've yet to test on IE 9 and below but its looking promising :-)

  • #4
    Supreme Master coder! glenngv's Avatar
    Join Date
    Jun 2002
    Location
    Philippines
    Posts
    11,042
    Thanks
    0
    Thanked 251 Times in 247 Posts
    Wouldn't it recursively execute the debouncedresize event handler because you trigger that event inside the handler?

  • #5
    New Coder
    Join Date
    Jan 2006
    Posts
    89
    Thanks
    3
    Thanked 0 Times in 0 Posts
    Quote Originally Posted by glenngv View Post
    Wouldn't it recursively execute the debouncedresize event handler because you trigger that event inside the handler?
    Hi Glenn, you're right.....but that is the only way I could get it to work properly.

    If I have the trigger anywhere else it doesn't seem to work and I still get the incorrect positioning of the image on maximising the browser.

    Yet if I have the trigger inside, it seems to work properly but it is extremely slow on older browsers and it also seems to crash the browser on an iPad.

    Do you have any ideas on how to implement this a different way? Any help would be great.

    EDIT: would it help if you had the URL to my site?
    Last edited by jpmad4it; 11-08-2013 at 08:19 AM.

  • #6
    Supreme Master coder! glenngv's Avatar
    Join Date
    Jun 2002
    Location
    Philippines
    Posts
    11,042
    Thanks
    0
    Thanked 251 Times in 247 Posts
    Do you need to manually trigger debouncedresize? Wouldn't it be automatically triggered when window is resized?

  • #7
    New Coder
    Join Date
    Jan 2006
    Posts
    89
    Thanks
    3
    Thanked 0 Times in 0 Posts
    Quote Originally Posted by glenngv View Post
    Do you need to manually trigger debouncedresize? Wouldn't it be automatically triggered when window is resized?
    Hi I fixed this using jquery ui position. I'll post my fix when I'm at my pc.


    EDIT: Here's what I did:

    I used the debulked version of the jquery debounce (https://github.com/louisremi/jquery-smartresize/)

    Code:
    // debulked onresize handler
    function on_resize(c,t){onresize=function(){clearTimeout(t);t=setTimeout(c,100)};return c};
    Wrapped my function with the new on resize handler:

    Code:
    on_resize(function() {
    	//$(window).resize(function() {
    	main.resizeSlider();
    });
    Then instead of using .css top and left to position the image, I used jQuery UI position:

    Code:
    image.css({
    	width	: windowWidth + 'px',
    	height	: heightDiff + 'px'
    }).position({
    	of: image.parent(),
    	my: 'center center',
    	at: 'center center',
    	collision: 'none'
    });
    And it works a treat :-)

    Thanks for pointing me in the direction of the debounce code
    Last edited by jpmad4it; 11-09-2013 at 10:58 AM.


  •  

    Tags for this Thread

    Posting Permissions

    • You may not post new threads
    • You may not post replies
    • You may not post attachments
    • You may not edit your posts
    •