I’m currently working with PHP, and this footer is one of the components of every page. First off, I know that a footer of this size needs to be made smaller before I publish it; it’s currently formatted like this before I create drop-down (or in this case, pop-up) menus.
I currently have jQuery set to auto-resize the footer’s height on window resize (with debounce), since the internal elements move in a grid pattern. However, I’ve run into a couple issues:
-
On the first page load, before any resizes, it doesn’t extend the footer sufficiently far enough so all internal elements are on the same colored background. I know I could just add a constant, but I want it to scale with the end user’s default text size.
-
After multiple resizes, the footer’s total height is several times more than intended.
I can’t spot the error; what am I doing wrong? I’ve pasted the relevant code into jsFiddle, as it’s rather long.
EDIT: Problem 2 fixed. Default behavior is now Problem 1.
EDIT 2: Here’s a preview. You should still checkout the fiddle, though.
var maxWidth, maxHeight, numBoxes;
function arrangeFooter() {
// Get the width of the footer to determine # of rows
var footerWidth = $("#footer").width();
// Get list of .box divs' widths and lengths
var widths = $(".box").map(function() {
return $(this).innerWidth();
}).get();
var heights = $(".box").map(function() {
return $(this).height();
}).get();
numBoxes = widths.length;
// Find maxWidth, maxHeight of .box divs
// From these, finds # of cols that can fit with the maxWidth,
// and number of rows
maxWidth = Math.max.apply(Math, widths);
maxHeight = Math.max.apply(Math, heights);
var cols = Math.floor(footerWidth / maxWidth);
var rows = Math.ceil(numBoxes / cols);
// Calculates footer's new height, defined as
// maxHeight * num rows + height of .firstrow div
var newHeight = maxHeight * rows + parseFloat($(".firstrow").css("font-size"));
// Prints out resulting CSS rules directly to page
var styling = "\n .box {\n height: " + maxHeight + "px;\n width: " +
maxWidth + "px;\n }\n"
styling += "\n #footer {\n height:" + newHeight + "px;\n }\n";
$("#style").text(styling);
}
function resizeFooter() {
var footerWidth = $("#footer").width();
var cols = Math.floor(footerWidth / maxWidth);
var rows = Math.ceil(numBoxes / cols);
// Calculates footer's new height, defined as
// maxHeight * num rows + height of .firstrow div
var newHeight = maxHeight * rows + parseFloat($(".firstrow").css("font-size"));
// Prints out resulting CSS rules directly to page
$('#footer').css('height',newHeight);
}
// Debounce method; used to ensure that only one event is fired
// after ms if multiple identical events are triggered
var delay = (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);
};
})();
function init() {
// calls arrangeFooter after 200ms to ensure page loads first
setTimeout(arrangeFooter, 200);
// Problem? Executes 500ms after window resize is "complete"
$(window).on("resize", function() {
delay(function() {
resizeFooter();
}, 500, "resize");
});
}
window.onload = init();
After messing with the code a bit I think the problem is related to adding the font size of the first row to the size of the content in the box div.
This will add about 16 pixels to the height, but won’t add the margin (10 pixels), padding (another 10 pixels) or border (1 pixel). Furthermore if the screen is so thin that for some reason that row extends to two lines then it’ll only add the font-size once and not twice.
Therefore I propose the alternative:
.outerHeight(true) will give you the height of the element including margins.