I'm trying to use fitHeights (http://codepen.io/davatron5000/pen/fIqnF) to equalize rows of columns but I can't get it to calculate the height separately for each row. Does anyone have any ideas on how this can be modified to calculate each rows tallest container?
This is the example I'm working with. http://codepen.io/FernE97/pen/rzfid. Right now it is calculating the heights but it takes it from the tallest of the 4 instead of the tallest in each row.
(function ($) {
'use strict';
$.fn.fitHeights = function () {
var items = $(this);
function setHeights() {
var currentTallest = 0;
items.css({ 'min-height' : currentTallest }); // unset min-height to get actual new height
items.each(function () {
if ($(this).outerHeight() > currentTallest) { currentTallest = $(this).outerHeight(); }
});
items.css({ 'min-height' : currentTallest });
}
setHeights();
$(window).on('resize', setHeights);
return this;
};
}(jQuery));
// on load
jQuery(window).load(function ($) {
$('.fitheights .module').fitHeights();
}(jQuery));
hoping this helps but check out the updated codepen I did - essentially I created a sameHeights function and put a height on the image hopefully this will be of help to you
http://codepen.io/anon/pen/fslvc
the js
$.fn.sameHeights = function() {
$(this).each(function(){
var tallest = 0;
$(this).children().each(function(i){
if (tallest < $(this).height()) { tallest = $(this).height(); }
});
$(this).children().css({'height': tallest});
});
return this;
};
$(window).load(function(){
/* $(groupOfItems).fitHeights(); */
$('ul').sameHeights();
});
css
img { max-width: 100%; height:300px; }
Related
Any ideas what I am doing wrong here? I have tried adding within the each as well but ended up being like 415px in height which was incorrect as only 2 lines of text so should be around 40px.
As you will see it creates the H3 heading in the each, but what I need to do after the the each is complete is find the highest heading so I can then set the height of all the others.
$(document).ready(function() {
// rebuild product options display
$('.rebuild_options .ty-product-options .ty-product-options__item').each(function(i, obj) {
var option_title = $(this).find('.ty-product-options__item-label').text().replace(":", "");
var option_html = $(this).find('.ty-product-options__item-label span a').attr('title');
var $option_content = $(option_html);
var option_html_text = $option_content[0].innerHTML;
var option_html_img = $option_content[1].innerHTML;
$(this).find('.ty-product-options__box').hide();
$(this).find('.ty-product-options__item-label').addClass('input-text cm-hint');
$(this).find('.ty-product-options__item-label').attr('title',option_html_text);
$(this).find('.ty-product-options__item-label').html(option_html_img);
$(this).find('.ty-product-options__item-label').prepend('<i class="option-status-icon ty-icon-star-empty"></i>');
$(this).find('.ty-product-options__item-label').prepend("<h3 class='option-heading'>"+option_title+"</h3>");
});
var maxHeight = 0;
$('.ty-product-options__item-label h3').each(function(i, obj) {
if ($(this).height() > maxHeight) {
maxHeight = $(this).height();
}
$(this).height(maxHeight);
});
});
$('.ty-product-options__item-label h3').each(function(i, obj) {
if ($(this).height() > maxHeight) {
maxHeight = $(this).height();
}
}).height(maxHeight);
You should assign the height to all h3's after calculating max by chaining it after the each function.
Is there a way to simplify Javascript multiple if?
I have this code to make three different divs appear when scrolling to other divs but i'm new with javascript, I tried declaring all the variables first but i'm not sure how to write the if part
$(document).ready(function () {
var topOfOthDiv1 = $("#cuidamos").offset().top - 490;
$(window).scroll(function () {
if ($(window).scrollTop() > topOfOthDiv1) { //scrolled past the other div?
$("#cuidado").fadeIn(); //reached the desired point -- show div
} else {
$('#cuidado').fadeOut();
}
});
});
$(document).ready(function () {
var topOfOthDiv2 = $("#productos").offset().top - 490;
$(window).scroll(function () {
if ($(window).scrollTop() > topOfOthDiv2) { //scrolled past the other div?
$("#sabor").fadeIn(); //reached the desired point -- show div
} else {
$('#sabor').fadeOut();
}
});
});
$(document).ready(function () {
var topOfOthDiv3 = $("#encuentranos").offset().top - 490;
$(window).scroll(function () {
if ($(window).scrollTop() > topOfOthDiv3) { //scrolled past the other div?
$("#locat").fadeIn(); //reached the desired point -- show div
} else {
$('#locat').fadeOut();
}
});
});
Get rid of those redundant .ready() and .scroll() handlers, and put everything in one.
Then make a map of the ID of each element to be faded to its original .offset().top position.
Then in the .scroll() handler, iterate the map, and use the ID and top value of each to compare to the current scrollTop() position to decide if it should be faded or not.
The if statement itself can be eliminated as well by choosing the name of the method to be invoked dynamically using square brackets and the conditional operator.
$(function () {
var tops = {
cuidaado: $("#cuidamos").offset().top - 490,
sabor: $("#productos").offset().top - 490,
locat: $("#encuentranos").offset().top - 490
};
$(window).scroll(function () {
var top = $(window).scrollTop();
$.each(tops, function(id, this_top) {
$("#" + id)[top > this_top ? "fadeIn" : "fadeOut"]();
});
});
});
A solution should give a class to your divs and store the target with them.
How to store the target with your div ?
<div id="cuidamos" class="my-div-class" data-target-id="cuidado"></div>
<div id="productos" class="my-div-class" data-target-id="sabor"></div>
<div id="encuentranos" class="my-div-class" data-target-id="locat"></div>
As mentioned by #squint, you only need a event that do it for all your divs.
Then your code should be the following:
$(window).scroll(function () {
var windowTop = $(window).scrollTop();
var $div;
var divTop;
var $divTarget;
$('.my-div-class').each(function(div) {
$div = $(div);
divTop = $div.offset().top - 490;
$divTarget = $('#' + $div.data('target-id'));
if (windowTop > divTop) {
$divTarget.fadeIn();
} else {
$divTarget.fadeOut();
}
});
});
You can store the divs map first, then do what you want. Like this:
$(document).ready(function () {
var divsMap = {
'cuidamos': 'cuidado',
'products': 'sabor',
'encuentranos': 'locat'
};
$(window).scroll(function () {
$.each(divsMap, function(key, item){
var topOfDiv = $('#'+key).offset().top - 490;
if ($(window).scrollTop() > topOfDiv) { //scrolled past the other div?
$('#'+item).fadeIn(); //reached the desired point -- show div
} else {
$('#'+item).fadeOut();
}
});
});
});
var obj = {
"#cuidado" : $("#cuidamos").offset().top - 490,
"#sabor" : $("#productos").offset().top - 490,
"#locat" : $("#encuentranos").offset().top - 490
};
$(window).scroll(function () {
$.each(arr , function(key, val) {
if ($(window).scrollTop() > val) {
$(key).fadeIn();
}else{
$(key).fadeOut();
}
});
});
I try to set all my divs to the height of the highest div on load and on resize. Here's the code:
// set equal column heights
function eqColumn(){
if ($(window).width() > 767){
var item = $(".item");
var biggest = 0;
$(item).each(function(){
if ($(this).height() > biggest){
biggest = $(this).height();
console.log(".item height = " + biggest);
}
});
item.css("height", biggest);
}
}
// bind events
$(window).on("load resize", eqColumn);
It works fine on load, but not when I resize the window. When I log the value in the console, the value doesn't change on resize. I'm really stumped. Here's the example site: http://dev.thomasveit.com/zuzuegler/
What am I doing wrong?
this is because all items are equally big after load/resize. Because you resize them all when the eqColumn function runs for the first time:
item.css("height", biggest);
Try resetting the .item size before the .each iteration:
function eqColumn(){
if ($(window).width() > 767){
var item = $(".item");
//reset the height to auto
item.css("height", "auto");
var biggest = 0;
$(item).each(function(){
if ($(this).height() > biggest){
biggest = $(this).height();
console.log(".item height = " + biggest);
}
});
item.css("height", biggest);
}
}
I have a single level navigation list. What I want to do is, on window resize, add a dropdown at the end to display elements that do not fit the window width.
Below an image representation:
var base = this,
container = $(base.selector),
items = container.find('>li:not(.smallmenu):visible'),
count = container.find('>li:not(.smallmenu):visible').length,
listWidth = [],
added;
items.each(function() {
listWidth.push($(this).width());
});
function getWidth() {
var width = 0;
container.find('>li:not(.smallmenu):visible').each(function() {
width += $(this).outerWidth();
});
return width + 100;
}
function hideLast() {
var i = container.find('>li:not(.smallmenu):visible').last().index()
if( $(window).width() < (getWidth()) ) {
items.eq(i).hide();
if(!added) {
$('<li class="smallmenu"><i class="fa fa-plus"></i></li>').appendTo(container);
added = true;
}
}
}
function showLast() {
var i = container.find('>li:not(.smallmenu):visible').last().index();
if( (getWidth() + listWidth[i+1]) < $(window).width() ) {
container.find('>li:not(.smallmenu)').eq(i+1).show();
if((i+2) === count) {
container.find('.smallmenu').remove();
added = false;
}
}
}
$(window).resize(function() {
showLast();
hideLast();
});
However this is not working as expected and half-done. I feel like I am heading in the wrong direction.
EDIT: Here is an updated jsFiddle: http://jsfiddle.net/anteksiler/zyv8f/1/ Resize your browser to get the effect.
I have a gallery of three Grids with images. The grid sizes changes depending on the screen size, and I have achieved that using Media-Query - ie, on desktop the grid's width will be 33% to make three columns view next to each other, and on tablet it will be 50% to make two columns view, and on phone it will be a 100% for each grid making one column view.
The reason I did this is to create a tiled gallery with images of different heights - and if I did it the normal way it will generate White-empty-spaces when floating.
So to fix this problem, and with the help of few members on this website, we have created a JavaScrip function that will MOVE all of the images that are inside Grid3 equally to Grid1 & Grid2 when screen size is tablet, so we get rid of the third grid making a view of fine two columns. Everything is working great!
Now, the problem is - on Chrome & IE - The function is being fired before its time for some reason that I need your help to help me find it! Please try it your self here: [http://90.195.175.51:93/portfolio.html][2]
Slowly on Chrome or IE - (try it on Firefox as well) - try to re-size the window from large to small, you will notice that BEFORE the top header changes to be a responsive Header (which indicate that you are on a small screen) the images have been sent to Grid1 and Grid 2! but a few px before the time. As on the function it says to fire it on <770.
Hope my question is clear enough for you to help me solve this issue which is stopping me from launching my website. Thanks.
Here is the JavaScrip:
//Gallery Grid System//
var testimonial = $(".testimonial, .galleryItem", "#grid3");
(function () {
$(document).ready(GalleryGrid);
$(window).resize(GalleryGrid);
})(jQuery);
function GalleryGrid() {
var grid3 = $('#grid3');
var width = $(window).width();
if (width < 1030 && width > 770) {
var grid1 = $('#grid1');
var grid2 = $('#grid2');
for (var i = 0; i < testimonial.length; i++) {
if (i < testimonial.length / 2) {
grid1.append(testimonial[i]);
} else {
grid2.append(testimonial[i]);
}
}
} else {
grid3.append(testimonial);
}
}
Note: The following is the whole page with all the functions:
$(document).ready(function () {
//Prevent clicking on .active links
$('.active').click(function (a) {
a.preventDefault();
});
//Allow :active on touch screens
document.addEventListener("touchstart", function () {}, true);
//Hide toolbar by default
window.addEventListener('load', function () {
setTimeout(scrollTo, 0, 0, 0);
}, false);
//Scroll-up button
$(window).scroll(function () {
if ($(this).scrollTop() > 100) {
$('.scrollup').fadeIn();
} else {
$('.scrollup').fadeOut();
}
});
$('.scrollup').click(function () {
$("html, body").animate({
scrollTop: 0
}, 600);
return false;
});
//StickyBox
$(function () {
$.fn.scrollBottom = function () {
return $(document).height() - this.scrollTop() - this.height();
};
var $StickyBox = $('.detailsBox');
var $window = $(window);
$window.bind("scroll resize", function () {
var gap = $window.height() - $StickyBox.height() - 10;
var footer = 288 - $window.scrollBottom();
var scrollTop = $window.scrollTop();
$StickyBox.css({
top: 'auto',
bottom: 'auto'
});
if ($window.width() <= 770) {
return;
$StickyBox.css({
top: '0',
bottom: 'auto'
});
}
if (scrollTop < 50) {
$StickyBox.css({
bottom: "auto"
});
} else if (footer > gap - 100) {
$StickyBox.css({
top: "auto",
bottom: footer + "px"
});
} else {
$StickyBox.css({
top: 80,
bottom: "auto"
});
}
});
});
//Change items location depending on the width of the screen//
$(function () { //Load Ready
function myFunction() {
var insert = $(window).width() <= 770 ? 'insertBefore' : 'insertAfter';
$('#home-sectionB img')[insert]($('#home-sectionB div'));
$('#home-sectionD img')[insert]($('#home-sectionD div'));
}
myFunction(); //For When Load
$(window).resize(myFunction); //For When Resize
});
//Contact Form//
$(".input").addClass('notSelected');
$(".input").focus(function () {
$(this).addClass('selected');
});
$(".input").focusout(function () {
$(this).removeClass('selected');
});
$(document).ready(function () {
GalleryGrid();
$(window).resize(GalleryGrid);
});
//Gallery Grid System//
var testimonial = $(".testimonial, .galleryItem", "#grid3");
(function () {
$(document).ready(GalleryGrid);
$(window).resize(GalleryGrid);
})(jQuery);
function GalleryGrid() {
var grid3 = $('#grid3');
var width = $(window).width();
if (width < 1030 && width > 770) {
var grid1 = $('#grid1');
var grid2 = $('#grid2');
for (var i = 0; i < testimonial.length; i++) {
if (i < testimonial.length / 2) {
grid1.append(testimonial[i]);
} else {
grid2.append(testimonial[i]);
}
}
} else {
grid3.append(testimonial);
}
}
//Testimonials Animation//
$(".testimonial").hover(function () {
$(".testimonial").addClass('testimonialNotActive');
$(this).removeClass('testimonialNotActive').addClass('testimonialActive');
},
function () {
$(".testimonial").removeClass('testimonialNotActive');
$(this).removeClass('testimonialActive');
});
//Portfolio Gallery Filter//
(function () {
var $portfolioGallerySection = $('#portfolio-sectionB'),
$filterbuttons = $('#portfolio-sectionA a');
$filterbuttons.on('click', function () {
var filter = $(this).data('filter');
$filterbuttons.removeClass('portfolio-sectionAClicked');
$(this).addClass('portfolio-sectionAClicked');
$portfolioGallerySection.attr('class', filter);
$('.galleryItem').removeClass('selectedFilter');
$('.galleryItem.' + filter).addClass('selectedFilter');
});
}());
});
Your problem is that CSS media queries and jQuery's $(window).width() do not always align.
function getCSSWidth() {
var e = window, a = 'inner';
if (!('innerWidth' in window )) {
a = 'client';
e = document.documentElement || document.body;
}
return e[ a+'Width' ];
}
Use this instead of $(window).width()
modified from http://andylangton.co.uk/articles/javascript/get-viewport-size-javascript/
I think this could solve your problem (but I'm not quite sure)
//Put that before the document ready event
(function($,sr){
// debouncing function from John Hann
// http://unscriptable.com/index.php/2009/03/20/debouncing-javascript-methods/
var debounce = function (func, threshold, execAsap) {
var timeout;
return function debounced () {
var obj = this, args = arguments;
function delayed () {
if (!execAsap)
func.apply(obj, args);
timeout = null;
};
if (timeout)
clearTimeout(timeout);
else if (execAsap)
func.apply(obj, args);
timeout = setTimeout(delayed, threshold || 100);
};
}
// smartresize
jQuery.fn[sr] = function(fn){ return fn ? this.bind('resize', debounce(fn)) : this.trigger(sr); };
})(jQuery,'smartresize');
// Here you call GalleryGrid (replace $(window).resize(GalleryGrid) with that):
$(window).smartresize(GalleryGrid);
http://www.paulirish.com/2009/throttled-smartresize-jquery-event-handler/
The reason is your vertical scrollbar. Your content is fixed at width=1030, but when the window size is 1030, the size of the viewport is actually: window size (1030) - vertical scroll bar
Try setting
<body style="overflow:hidden">
You will see that it works correctly when the scrollbar is removed. Or try setting:
<link href="assets/css/tablets-landscape.css" rel="stylesheet" type="text/css" media="screen and (max-width : 1045px)"/>
Set max-width:1045px to make up for scrollbar, you will see that it works correctly.
Your javascript should be like this:
var width = $(window).width() + verticalscrollbarWidth;