optimizing div + screen resize JS block

384 Views Asked by At

I'm struggling to figure out what the best way would be to optimize this code. I'm currently only using width @media tags, and JS seems to be the only reliable way I can control a series of very specific variables to adjust this div element.

It's currently a mess I realize, but I wanted to get feedback to see if there are any glaring issues. Still learning, so go easy on me.

Thanks.

jQuery(document).ready(function($){
    var elementHeight = $('.hs-caption').height();
    var screenHeight = jQuery(window).height();
    var upcomingHeader = $('.fold-header').height() * 2.0;
    if (screenHeight > 960) {
    var heightOffset = 220;         
    } else {
    var heightOffset = 200; 
    } 
    var totalHeight = elementHeight + heightOffset;

function fullscreen(){
    jQuery('#hero').css({
        width: jQuery(window).width(),
        height: jQuery(window).height()
    });
}  
function setToCenterOfParent(element, parent, ignoreWidth, ignoreHeight){
    parentWidth = $(parent).width();
    parentHeight = $(parent).height();  
    elementWidth = $(element).width();
    elementHeight = $(element).height();
    if(!ignoreWidth)
        $(element).css('left', parentWidth/2 - elementWidth/2);
    if(!ignoreHeight)
        $(element).css('top', heightOffset);
}   

function scalar(){
  if (window.innerHeight < (totalHeight * 1.25) + upcomingHeader) {
        console.log("screenHeight is less than elementHeight");       
        $('.hs-info p').css({
            display: 'none'
        }),
        $('.hs-info .btn-slide').css({
            padding: '10px 0px 0px 0px'
        }),
        $('.hs-sponsor').css({
            display: 'none'
        })
    } else {
        console.log("screenHeight is NOT less than elementHeight");       
        $('.hs-info .btn-slide').css({
            padding: '0px'
        }),
        $('.hs-sponsor').css({
            display: 'block'
        }),
        $(".hs-info p").css({
            display: 'block'
        })
    }
}

setToCenterOfParent( $('.hs-caption'), document.body, true, false);
fullscreen();
scalar();

jQuery(window).resize(function() {
    scalar();
    setToCenterOfParent( $('.hs-caption'), document.body, true, false);
    fullscreen();         
});

console.log("height:", elementHeight);
console.log("total height:", elementHeight + heightOffset); 
console.log("screenHeight:", screenHeight); 
console.log("heightOffset:", heightOffset); 
console.log("upcomingHeader:", upcomingHeader);     
});
1

There are 1 best solutions below

1
On BEST ANSWER

As the target is not very clear, I can only do some small code editing to make it more easy to read, and maybe a little performance improvement.

jQuery(document).ready(function($) {
  // Define share variables.
  var element = $('.hs-caption');
  var elementWidth, elementHeight;
  var screenWidth, screenHeigth;
  var upcomingHeader = $('.fold-header').height() * 2.0;
  var heightOffset;
  var totalHeight;
  var HEIGHT_RATIO = 1.25;
  var paddingElements = $('.hs-info .btn-slide');
  var displayElements = $('.hs-info p, .hs-sponsor');
  var RESIZE_DELEY = 200;
  var delayedHandler = null;

  function onResize() {
    updateSetting();
    setToCenterOfParent(element, $(document.body), true, false);
    fullscreen();
    scalar();
  };

  function scalar() {
    var innerHeight = window.innerHeight;
    var totalElementHeight = totalHeight * HEIGHT_RATIO + upcomingHeader;
    var isScreenSmaller = (innerHeight < totalElementHeight);
    var padding = isScreenSmaller ? '10px 0px 0px 0px' : '0px';
    var display = isScreenSmaller ? 'none' : 'block';
    paddingElements.css('padding', padding);
    displayElements.css('display', display);
  }

  function updateSetting(){
    screenWidth = $(window).width();
    screenWidth = $(window).height();
    elementWidth = element.width();
    elementHeight = element.height();
    heightOffset = (screenHeight > 960) ? 220 : 200;
    totalHeight = elementHeight + heightOffset;
  }

  function fullscreen() {
    $('#hero').css({
      width: screenWidth,
      height: screenHeigth
    });
  }

  function setToCenterOfParent(element, parent, ignoreWidth, ignoreHeight) {
    var parentWidth = parent.width();
    var parentHeight = parent.width();
    if (!ignoreWidth) {
      element.css('left', parentWidth/2 - elementWidth/2);
    }
    if (!ignoreHeight) {
      element.css('top', heightOffset);
    }
  }

  // Init
  onResize();

  $(window).resize(function() {
    // Don't do this too often
    if (delayedHandler !== null) {
      clearTimeout(delayedHandler);
    }
    // Delayed the function to be executed, so it only updates when user stop
    // resizing for a fixed amount of time.
    delayedHandler = setTimeout(onResize, RESIZE_DELEY);
  });

  console.log("height:", elementHeight);
  console.log("total height:", elementHeight + heightOffset);
  console.log("screenHeight:", screenHeight);
  console.log("heightOffset:", heightOffset);
  console.log("upcomingHeader:", upcomingHeader);
});

The idea is:

  1. Pull out all of the elements that will be queried again and again, like $('.hs-info .btn-slide') and $('.hs-info p, .hs-sponsor'), also $('.hs-caption') seems to be widely used, pull it out.
  2. Do samething to variables, here I'm not sure if you would use setToCenterOfParent to other elements, but I'll try to input the jquery wrapped element, so I can directly use jquery on them in the function.
  3. elementWidth/elementHeight here is not clear whether it'll change or not, so I remain the code not edited.
  4. Add a settimeout to resize, so jquery won't do lots of computation during the user resizing his window, and 0.2 sec's delay should be fast enough so user won't feel a delay(or you can adjust RESIZE_DELEY to a even smaller number).
  5. unless you're using some library that will conflict with jquery, keep code style same is preferable, so I change all jQuery(foo).bar to $(foo).bar for consistency.

I believe this should be the most we can do, if there's no example like jsfiddle, to demonstrate what this code is for.