Set heights not changing inline with jQuery - javascript

I have a piece of code where I am trying to dynamically change the heights of children elements and I am running into something bizarre. Here is my code so far:
var heights = [],
tallest;
$(window).resize(function() {
$(elem).children().each(function (i) {
heights[i] = $(this).height();
tallest = Math.max.apply(null, heights);
$(this).height(tallest);
});
});
All this does is find the heights of each child element, pushes it into an array and then finds the biggest value in that array and attempts to set the height based on that value. One would expect that each child element that is found will change according to what the tallest variable value is on resize, but it doesn't -- it stays the same. However, this code works:
var heights = [],
number = 1000;
$(window).resize(function() {
$(elem).children().each(function (i) {
heights[i] = $(this).height();
tallest = Math.max.apply(null, heights);
$(this).height(number--);
});
});
The height attribute is changed inline with the number variable when resizing the window. What gives?
Why does the second piece of code work and the first one doesn't? They look like almost the same code to me.

It won't assign the max value right away because you're not really calculating the Max height. You have to let it run for all the child elements to get the tallest value. And then run again to assign to each child.
var heights = [],
tallest;
$(window).resize(function() {
$(elem).children().each(function (i) {
heights[i] = $(this).height();
});
tallest = Math.max.apply(null, heights);
$(elem).children().each(function (i) {
$(this).height(tallest);
});
});

Figured it out. You have to reset the height every time in the original loop so it pushes a new value into the array.
$(window).on("resize", function () {
$(elem).children().each(function (i) {
$(this).css("height", "");
heights[i] = $(this).height();
});
});
Solved it for me.
The issue comes when you set the height in the other each, it sets the biggest value. You need to get rid of the inline height each time to retrieve the new value.

Related

Detected height of a percentage-width-div is still the same after resizing the window? jQuery

It is hard to explain… so I opened a Fiddle:
http://jsfiddle.net/qga046f3/
Goal: My goal is to get three divs of the same height. So I detect all the heights and choose the biggest one and apply this height to the other div-containers.
If the user resizes the browser-window the heights of the divs should be re-adjust. But jQuery gives me always the same height from first time. Why?
This is my jQuery code:
var adjustheights = function(){
heights = [];
$('.element').each(function(i){
heights.push($(this).outerHeight());
});
var maxHeight = Math.max.apply(Math, heights);
$('.element').css('height', maxHeight);
$('.maxheight').html(maxHeight);
}
adjustheights();
$(window).resize(function(){
adjustheights();
});
You need to reset (remove) the height of each element before adding the new one. jQuery adds an inline style when you set a height via CSS, so you need to remove it and add it again with the new value: (http://jsfiddle.net/qga046f3/4/)
var adjustheights = function(){
heights = [];
$('.element').each(function(i){
// Reset height first
$(this).removeAttr('style');
heights.push($(this).outerHeight());
});
var maxHeight = Math.max.apply(Math, heights);
$('.element').css('height', maxHeight);
$('.maxheight').html(maxHeight);
console.log(heights);
}
adjustheights();
$(window).resize(function(){
adjustheights();
});

Responsive margin resizing

I want to have my elements resize their margins equally so that they fill the page. I tried turning the page width into a value using jquery but that didn't work.
var margen = $(window).width()
$(document).ready(function () {
$('#FixedMenu *').animate({
'margin-left': 'margen/6'
});
});
http://jsfiddle.net/clarinetking/2PGZS/40/
I make little update to your jsFiddle, you can see it here:
jsFiddle
What i change is this:
1.
You found width of screen:
var screenWidth = $(window).width();
2.
You found total width of child elements of your fixed menu
var widthOfChilds = 0;
$('#FixedMenu > *').each(function() {
widthOfChilds += $(this).outerWidth( true );
});
3.
You take off total width of child elements from screen size and you will get "free"width around child elements.
There are six of them, but you need space after last one from right, so you divide "free"width by number of childs + 1
var newmargin = (screenWidth - widthOfChilds)/7;
$('#FixedMenu *').animate({
'margin-left': newmargin
});
I hope it helped! :)

Equal height divs (or li) in rows with fluid width and height

I found this sweet jQuery snippet by CSS-Tricks' Chris Coyier that resets div elements heights that share the same top position on the page (are on the same row) to the tallest element.
The Problem
This solution almost works with fluid width layouts and resets height when top positions changes but it resets it to the original height of the current tallest element in the row when the page first loaded. This is an issue because the height of the tallest element might have changed since this page first loaded because of the use of relative units like ems or because of word wrapping with paragraphs.
Proposed Solution
The solution would be to have the row's elements' height being set to the tallest element's current height, not the original height. I have been unsuccessful in accomplishing this.
Here is the snippet where "li.half" is the elements being compared and resized.
jQuery(document).ready(function($) {
// these are (ruh-roh) globals. You could wrap in an
// immediately-Invoked Function Expression (IIFE) if you wanted to...
var currentTallest = 0,
currentRowStart = 0,
rowDivs = new Array();
function setConformingHeight(el, newHeight) {
// set the height to something new, but remember the original height in case things change
el.data("originalHeight", (el.data("originalHeight") == undefined) ? (el.height()) : (el.data("originalHeight")));
el.height(newHeight);
}
function getOriginalHeight(el) {
// if the height has changed, send the originalHeight
return (el.data("originalHeight") == undefined) ? (el.height()) : (el.data("originalHeight"));
}
function columnConform() {
// find the tallest DIV in the row, and set the heights of all of the DIVs to match it.
$('li.half').each(function() {
// "caching"
var $el = $(this);
var topPosition = $el.position().top;
if (currentRowStart != topPosition) {
// we just came to a new row. Set all the heights on the completed row
for(currentDiv = 0 ; currentDiv < rowDivs.length ; currentDiv++) setConformingHeight(rowDivs[currentDiv], currentTallest);
// set the variables for the new row
rowDivs.length = 0; // empty the array
currentRowStart = topPosition;
currentTallest = getOriginalHeight($el);
rowDivs.push($el);
} else {
// another div on the current row. Add it to the list and check if it's taller
rowDivs.push($el);
currentTallest = (currentTallest < getOriginalHeight($el)) ? (getOriginalHeight($el)) : (currentTallest);
}
// do the last row
for (currentDiv = 0 ; currentDiv < rowDivs.length ; currentDiv++) setConformingHeight(rowDivs[currentDiv], currentTallest);
});
}
$(window).resize(function(){
columnConform();
});
// Dom Ready
// You might also want to wait until window.onload if images are the things that
// are unequalizing the blocks
$(function() {
columnConform();
});
});
Please let me know if you can figure out how to make the setConformingHeight adjust on window resize.
Those solutions didn't work on window.resize() as elements height should be unlocked with $el.height('auto') before calculating new real height.
Here is my solution :
var currentRowTop = -100, currentHighest= 0;
$('.page-wrapper .cc').each(function() {
$el=$(this);
if($el.position().top!=currentRowTop){
equalizeHeight();
currentRowTop = $el.position().top;
$el.height('auto').addClass('same-height');
currentHighest=$el.height();
}else{
$el.height('auto').addClass('same-height');
currentHighest = ($el.height()>currentHighest) ? $el.height() : currentHighest ;
}
});
equalizeHeight();
function equalizeHeight(){
if($('.same-height').size()==0) return;
$('.same-height').height(currentHighest).removeClass('same-height');
}

multiple tables with the same row height using closure

I have two tables, side by side. What I am trying to do is have each row of each table that is in the same container have the same row height per row. I have gotten that far with this.
The way it works is you have an array thay grabs the row heights of each table and uses the largest height for each row. Thats fine except as its a single array that means if there are other containers on the page they will look at the same array. I tried writting a closure function but failed. any ideas?
$(document).ready(function() {
var heights = [];
computeTableHeights(true);
assignTableHeights();
var windowWidth = $(window).width();
$(window).resize(function() {
computeTableHeights(($(window).width() < windowWidth) && ($(window).width() != windowWidth));
windowWidth = $(window).width();
assignTableHeights();
})
function computeTableHeights(recordBiggestHeights) {
$("table").each(function() {
var rowIndex = 0;
var rows = $(this).find("tr");
$(rows).each(function() {
var rowHeight = $(this).css("height");
if (heights[rowIndex] === undefined) {
heights[rowIndex] = rowHeight;
} else {
var existingHeight = parseInt(heights[rowIndex]);
var currentHeight = parseInt(rowHeight);
if (shouldChangeHeight(recordBiggestHeights, existingHeight, currentHeight)) {
heights[rowIndex] = rowHeight;
}
}
rowIndex++;
});
});
}
function shouldChangeHeight(recordBiggestHeights, existingHeight, currentHeight) {
if (existingHeight == currentHeight) {
return false;
} else if (recordBiggestHeights) {
return existingHeight < currentHeight;
} else {
return existingHeight > currentHeight;
}
}
function assignTableHeights() {
$(".container table").each(function() {
var rowIndex = 0;
var rows = $(this).find("tr");
$(rows).each(function() {
var rowHeight = $(this).css("height");
if (heights[rowIndex]) {
var existingHeight = parseInt(rowHeight);
var targetHeight = parseInt(heights[rowIndex]);
if (existingHeight != targetHeight) {
$(this).css("height", heights[rowIndex]);
}
}
rowIndex++;
});
});
}
});
I think I understand what you're trying to do. If not, please elaborate a little on the requirements you're looking for, so I can revise this answer.
You want to treat the row heights of each container and its child tables separately. Correct me if I'm wrong
The code below loops through each container separately, before equalizing the heights of the table rows.
You are indeed right that storing all row heights for all tables in one array will not get you the results you need. You would need to create an array instance per container.
In your code you read out the css for the height of the row. Once you set the height in the css, this property will stay the same. I believe in your use-case you need the height of the row as the browser has calculated it (jquery offers methods for this purpose).
Therefore, on resizing, the css property should be cleared, before setting it again to the greatest calculated height.
function resizeHandler() {
// Treat each container separately
$(".container").each(function(i, container) {
// Stores the highest rowheight for all tables in this container, per row
var aRowHeights = [];
// Loop through the tables
$(container).find("table").each(function(indx, table) {
// Loop through the rows of current table (clear their css height value)
$(table).find("tr").css("height", "").each(function(i, tr) {
// If there is already a row height defined
if (aRowHeights[i])
// Replace value with height of current row if current row is higher.
aRowHeights[i] = Math.max(aRowHeights[i], $(tr).height());
else
// Else set it to the height of the current row
aRowHeights[i] = $(tr).height();
});
});
// Loop through the tables in this container separately again
$(container).find("table").each(function(i, table) {
// Set the height of each row to the stored greatest height.
$(table).find("tr").each(function(i, tr) {
$(tr).css("height", aRowHeights[i]);
});
});
});
}
$(document).ready(resizeHandler);
$(window).resize(resizeHandler);
I have this fiddle: http://jsfiddle.net/k5g87/
You can resize the result window in there.

function equalHeight , set a minimum Height to apply?

I have tried everything, but without javascript I cannot achieve the bad layout my designer gave to me!!
As you can see I have the div #backgr-box that has to be absolute positioned with z-index to be properly behind the #contenuto (which holds the page content!!)
Now to solve the extensibilty trouble of #backgr-box I have the below code that works if the content of #contenuto is longer than the sidebar #barra-laterale , but it is not ok in opposite case, see page: http://demo.liquidfactory.it/secondopolo/per-informarti
So how can I tell javascript to apply that calculation only over a minimum height of div sidebar #barra-laterale ??
Need help.. please!
function equalHeight(group) {
tallest = 0;
group.each(function() {
thisHeight = $(this).height();
if(thisHeight > tallest) {
tallest = thisHeight = $("#contenuto").height() - 380;
}
});
group.height(tallest);
}
$(document).ready(function() {
equalHeight($(".column"));
});
The problem is likely with this line:
tallest = thisHeight = $("#contenuto").height() - 380;
Currently it is setting both the variables tallest and thisHeight to the height of the content region minus 380 pixels. Change it to:
tallest = thisHeight;
And it will resize all the columns to the height of the tallest one.
Edit: It looks like your right-hand column actually consists of multiple columns with a class of .barra-laterale in this case you may want to take another tack altogether:
// calculate the total height of the content are and sidebar
var contentHeight = $("#contenuto").height();
var sidebarHeight = 0;
$(".barra-laterale").each(function() { sidebarHeight += $(this).height(); })
if (sidebarHeight > contentHeight) {
$("#contenuto").height(sidebarHeight);
} else {
// extend the last sidebar column to cover the difference between the
// height of the content and the sum of the sidebar heights
var lastSideBarHeight = $(".barra-laterale").last().height();
var heightDifference = contentHeight - sidebarHeight;
$(".barra-laterale").last().height(lastSideBarHeight + heightDifference)
}

Categories

Resources