1252748
1252748

Reputation: 15369

Too cumbersome change div widths with Javascript on window resize

Is re-sizing DIVs on window-resize with Javascript too heavy for most browsers/computers? I'm doing this, because just setting widths in percentages only works in relation to the parent element. I can't seem to make it a percentage of the body, without regard to other parent elements between (on the DOM tree) the elements I would like to resize and the body.

function resize_columns() {
  var d = getWindowSize();
  var body_width = d.x;
  var fch_width = body_width * .15;
  var pnh_width = body_width * .25;
  $('.for_customer_div').css('width', fch_width + 'px');
  $('.for_customer_header').css('width', fch_width + 'px');
  $('.project_name_header, .project_name_div').css('width', pnh_width + 'px');
  $('.line_item_div').css('width', pnh_width + 'px');
}
$(document).ready(function() {
  resize_columns();
});
$(document).ready(function() {
  window.onresize = function(event) {
    resize_columns();
  }
});

function getWindowSize() {
  var w = window,
  d = document,
  e = d.documentElement,
  g = d.getElementsByTagName('body')[0],
  x = w.innerWidth || e.clientWidth || g.clientWidth,
  y = w.innerHeight || e.clientHeight || g.clientHeight;
  var dimensions = {
    x: x,
    y: y
  }

Upvotes: 2

Views: 354

Answers (3)

Kevin Ennis
Kevin Ennis

Reputation: 14464

Try adding something like this in your code:

function throttle (func, wait) {
    var throttling = false;
    return function(){
        if ( !throttling ){
            func.apply(this, arguments);
            throttling = true;
            setTimeout(function(){
                throttling = false;
            }, wait);            
        }
    };
}

And then call:

window.onresize = throttle(function() {
    resize_columns();
}, 20);

This will limit the number number of times resize_columns will be called to a maximum of once every 20 milliseconds.

Explanation:

The throttle function accepts two parameters: the function you want to execute, and a timeout duration. It then returns a new function with a reference to the throttling variable, which acts as a flag. So, as far as onresize is concerned, throttle just looks like the inner function it returns. Every time that function is executed, it says "is throttling set to false?". And if it is, it goes ahead and executes your function. Then it sets throttling to true and creates a setTimeout that will wait x number of milliseconds before it sets throttling back to false. If it gets executed and throttling is set to true, it doesn't do anything.

So the basic effect is that, at most, your function can only be executed once in a given time window. So you're just rate-limiting.

I know that might not be a great explanation, but I think a full-blown overview of closures would be biting off a little more than I'm willing to chew this morning.

Upvotes: 3

Rorrik
Rorrik

Reputation: 370

When I've had problems like this I've made the elements that should be a percentage of the body size children of the body, and positioned them absolutely to be within the parent elements where I wanted them to be. Admittedly, it calls for a lot more work to get all the pieces in the right places, but probably not as much as actively resizing.

Upvotes: 0

Pointy
Pointy

Reputation: 413826

You can cap the maximum rate at which you resize with something like this:

$(window).resize(function(minTime) {
  var lastResize = 0;
  return function(event) {
    var now = new Date().getTime();
    if (now - lastResize > minTime) {
      lastResize = now;
      resize_columns();
    }
  };
}( 250 )); // 250 millisecond minimum interval between resize changes

Upvotes: 2

Related Questions