Script that makes all floating divs the same height - javascript

Hey there, I have 20 divs floated left with different height. I use this script to resize them. It worked perfect when my website was designed using pixels.
When i have changed my website to % design (percentage design), the script stopped working that reliable, sometimes it does not resize.
can you take a look, see if there are any adjustments needed for liquid layouts?
maybe it's the way i call the script?
Ty very much
Here it is:
var currentTallest = 0;
var currentRowStart = 0;
var 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.
$('div.column').each(function(index) {
if(currentRowStart != $(this).position().top) {
// 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 = $(this).position().top;
currentTallest = getOriginalHeight($(this));
rowDivs.push($(this));
} else {
// another div on the current row. Add it to the list and check if it's taller
rowDivs.push($(this));
currentTallest = (currentTallest < getOriginalHeight($(this))) ? (getOriginalHeight($(this))) : (currentTallest);
}
// do the last row
for(currentDiv = 0 ; currentDiv < rowDivs.length ; currentDiv++) setConformingHeight(rowDivs[currentDiv], currentTallest);
});
}
$(window).resize(function() {
columnConform();
});
$(document).ready(function() {
columnConform();
});

Well if you change it to fluid layout (% design) then you are going to have to add a window resize listener, basically when the resize event is done or while it's running you need to recall the script so it can recalculate with new dimensions, you did not need to doo that with pixels because it was a fixed size and once assigned will not change no matter how many times you resize the actual screen.

If you use styles like this:
<style>
.parent{
background:#F00;height:300px
}
.parent div{
float:left;height:100%;width:33.33%;
}
</style>
<div class="parent">
<div style="background:#FED"></div>
<div style="background:#EDF"></div>
<div style="background:#DFE"></div>
</div>
You just have to set the height of the parent div, and the width of the children div

Related

Containing element's width is not displayed correctly

Several images are placed into an element whose display is flex and flex-wrap set to nowrap. The images don't fit into the element's width and extend beyond the screen width.
I am trying to calculate the width of the element that includes the images. However the width of element is always equal to screen width whereas it should be much greater than screen width.
Several threads have advised to first check if all the images have been loaded. Following is the code used to check the loading of the images.
let len = allCarousalImagesList.length,
counter = 0;
[].forEach.call( allCarousalImagesList, function( img ) {
if(img.complete)
incrementCounter();
else
img.addEventListener( 'load', incrementCounter, false );
} );
function incrementCounter() {
counter++;
if ( counter === len ) {
let carousalWidth = carousalElement.offsetWidth;
let browserWidth = window.innerWidth;
console.log(browserWidth, carousalWidth);
}
}
Inspite of checking for the loading of images, the width of the element containing unwrapped images is not being displayed correctly and is equal to screen width. I am using offsetWidth to get the width. Please help with this issue.
The code has been uploaded on the codesandbox here
So I created a solution to your problem:
And make sure to add position:absolute; to your carousal class
window.addEventListener("load", function () {
let carousalElement = document.getElementsByClassName("carousal")[0];
var width_of_img_container = window.getComputedStyle(carousalElement).width;
console.log(width_of_img_container);
},false);
Hope I could help.

How to incorporate JS media Queries and Scroll listening?

I'm currently making an element visible when my nav is at the top of the page. I'd like the element to be hidden if the page gets to max-width: 900px;. I've tried using modernizer for JS media queries but I ca't seem to get it to work.
Code:
var a = $(".menu").offset().top;
function scrollListener(){
if($(document).scrollTop() > a)
{$('.hidden-logo').css({"opacity": "1","display": "block"});
$('.menu').css({"margin-left": "-130px"})
} else {
$('.hidden-logo').css({"opacity": "0","display": "none"});
$('.menu').css({"margin-left": "0px"})
}
};
$(document).scroll(scrollListener);
You were checking the scroll position the wrong way - I think you want the logo to disappear when the current scroll is greater than the top of the logo, not less.
I added a msgS div (for demo purposes only) that will show you the current scroll value against the top-of-menu static value. I also added a 100px fudge factor to the menu location to make it more clear in the demo when the current scroll reaches that position. I use these temporary msg divs myself when working out my code, and then remove them when I've got it all sorted and ready for production.
And this is all you need to check the media query in javascript:
var winmed = window.matchMedia("(max-width: 700px)");
if (winmed.matches){ //do something }
And that can go into a listener function exactly like your scroll listener.
var gloShowLogo = true;
var a = $(".menu").offset().top;
var fudge = 100; //100px fudge factor so can SEE div disappear
function scrollListener(){
updateScrollMsg();
var currScroll = $(document).scrollTop();
var topOfMenu = a+fudge;
if( gloShowLogo && currScroll < topOfMenu ){
$('.hidden-logo').css({"opacity": "1","display": "block"});
$('.menu').css({"margin-left": "-130px"})
} else {
$('.hidden-logo').css({"opacity": "0","display": "none"});
$('.menu').css({"margin-left": "0px"})
}
};
function resizeListener(){
updateMediaMsg();
var winmed = window.matchMedia("(max-width: 500px)");
if (winmed.matches){
$('.hidden-logo').css({"opacity": "1","display": "block"});
gloShowLogo = true;
} else {
$('.hidden-logo').css({"opacity": "0","display": "none"});
gloShowLogo = false;
}
}
$(window).scroll(scrollListener);
$(window).resize(resizeListener);
function updateScrollMsg(){
$('#msgS').html( $(document).scrollTop() +' // ' + $(".menu").offset().top );
}
function updateMediaMsg(){
var winmed = window.matchMedia("(max-width: 500px)");
var medmsg = (winmed.matches) ? '< 500' : '> 500';
console.log(medmsg);
$('#msgM').html(medmsg);
}
.menu{background:green;text-align:center;}
.content{height:200vh;background:palegreen;text-align:center;}
.hidden-logo{position:fixed;top:1vh;right:1vw;padding:15px; background:pink;z-index:2;}
#msgS{position:fixed;top:0;left:0;padding:10px;background:wheat;z-index:2;}
#msgM{position:fixed;top:40px;left:0;padding:10px;background:lightblue;z-index:2;}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/2.2.4/jquery.min.js"></script>
<div class="menu">Menu Div</div>
<div class="content">Lengthy content Div..<br><br><br><br>100<br></div>
<div class="hidden-logo">LOGO</div>
<div id="msgS"></div>
<div id="msgM"></div>
Update:
Sorry, I had the media query a bit backwards myself - I think you want the logo to display when the screen-size is < 900px and to be hidden if wider than 900px, yes?
I added a msgM div so you can watch the media query kick-in -- but getting the best width for the demo was a bit of a challenge. I finally settled at 500px as a width that can be demoed (StackOverflow resizes its StackSnippets container as the browser window resizes, which throws things into confusion at each of their resize breakpoints)

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');
}

Getting Coordinates of an element on page scroll

I am having this problem where i have a set of 6 UL's having a common class x.Each of them consist of a specific section of the page.Now i have 6 menus that are related to each of the section.What i have to do is highlight the menu when its related section is in users view.
For this i thought that may be jQuery position(); or offset(); could have helped but they give the top and left of the element.I also tried using jQuery viewport plugin but apparently view port is big it can show more than one UL at a time hence i cant apply element specific logic here.I am not familliar to this but does anything changes of an element on scrolling?If yes then how to access it?
Please share your views.
Regards
Himanshu Sharma.
Is very easy to do it using jQuery and a dummy fixed HTML block that helps you find the current position of the viewport.
$(window).on("scroll load",function(){
var once = true;
$(".title").each(function(ele, index){
if($(this).offset().top > $("#viewport_helper").offset().top && once){
var index = $(this).index(".title");
$(".current").removeClass('current')
$("#menu li").eq(index).addClass('current')
once = false;
}
});
})
Check out a working example: http://jsfiddle.net/6c8Az/1/
You could also do something similar with the jQuery plugin, together with the :first selector:
$(window).on("scroll load",function(){
$(".title:in-viewport:first").each(function(){
var index = $(this).index(".title");
$(".current").removeClass('current')
$("#menu li").eq(index).addClass('current')
});
})
You can get the viewport's width and height via $(document).width() and $(document).height()
You can get how many pixels user scrolls via $(document).scrollTop() and $(document).scrollLeft
Combining 1 and 2, you can calculate where the viewport rectangle is
You can get the rectangle of an element using $(element).offset(), $(element).width() and $(element).height()
So the only thing left to you is to determine whether the viewport's rectangle contains (or interacts) the elements's rectangle
So the whole code may look like:
/**
* Check wether outer contains inner
* You can change this logic to matches what you need
*/
function rectContains(outer, inner) {
return outer.top <= inner.top &&
outer.bottom >= inner.bottom &&
outer.left <= inner.left &&
outer.right >= inner.right;
}
/**
* Use this function to find the menu related to <ul> element
*/
function findRelatedMenu(element) {
return $('#menu-' + element.attr('id'));
}
function whenScroll() {
var doc = $(document);
var elem = $(element);
var viewportRect = {
top: doc.scrollTop(),
left: doc.scrollLeft(),
width: doc.width(),
height: doc.height()
};
viewportRect.bottom = viewportRect.top + viewportRect.height;
viewportRect.right = viewportRect.left + viewportRect.width;
var elements = $('ul.your-class');
for (var i = 0; i < elements.length; i++) {
var elem = $(elements[i]);
var elementRect = {
top: elem.offset().top,
left: elem.offset().left,
width: elem.width(),
height: elem.height()
};
elementRect.bottom = elementRect.top + elementRect.height;
elementRect.right = elementRect.left + elementRect.width;
if (rectContains(viewportRect, elementRect)) {
findRelatedMenu(elem).addClass('highlight');
}
}
}
$(window).on('scroll', whenScroll);
Let's see if i understood well. You have a page long enough to scroll, and there is an element that when it appears in the viewport, you wanna do something with it. So the only event that's is triggered for sure on the time the element gets in the viewport is the 'scroll'. So if the element is on the page and the scroll is on the viewport, what you need to do is bind an action to the scroll event to check if the element is in the view each time the event is trigger. Pretty much like this:
$(window).scroll(function() {
check_element_position();
});
Now, in order for you to know if the element is in the viewport, you need 3 things. The offset top of that element, the size of the viewport and the scroll top of the window. Should pretty much look like this:
function check_element_position() {
var win = $(window);
var window_height = win.height();
var element = $(your_element);
var elem_offset_top = element.offset().top;
var elem_height = element.height();
var win_scroll = win.scrollTop();
var pseudo_offset = (elem_offset_top - win_scroll);
if (pseudo_offset < window_height && pseudo_offset >= 0) {
// element in view
}
else {
// elem not in view
}
}
Here, (elem_offset_top - win_scroll) represent the element position if there was no scroll. Like this, you just have to check if the element offset top is higher then the window viewport to see if it's in view or not.
Finally, you could be more precise on you calculations by adding the element height (variable already in there) because the code i just did will fire the event even if the element is visible by only 1 pixels.
Note: I just did that in five minutes so you might have to fix some of this, but this gives you a pretty darn good idea of what's going on ;)
Feel free to comment and ask questions

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