I am trying to create a light box kind of thing in jQuery. For vertically aligning my lightbox,I am using jQuery. Here is my plugin code:
(function($){
$.fn.lightbox = function(){
return this.each(function(){
/*plugin code starts here*/
var self = this;
console.log(self);
/*
* Now we will vertically align the lightbox
* To do that we will calculate the body's height,lightboxes height
* and then subtract later from earlier one.This will give us the total empty space
* So the margin from the top of lightbox will be half of the result we got from subtraction
*/
//calculating body's height
var doc_body_height = $('body').height();
var lightbox_height = $(self).height();
var margin_top = (doc_body_height - lightbox_height)/2;
$(self).css('margin-top',margin_top);
console.log($(self).height());
/*plugin code ends here*/
});
}
})(jQuery);
But the problem is, I am getting either 18 or 300 as height. 300 is the actual height of the div#lightbox,I don't know why the same function is returning different heights randomly.
See Image:
Clearly the div#lightbox is not 18px in height.
You are calculating the height using the $('body').height(). This is the computed value for the height of the body element. That means that for a page with just one visible element that is 50px high on it, the body will return 50px. Conversely, a long page that requires lots of scrolling will return the entire body height, not just the portion that is visible in the viewport.
You need to use $(window).height(); in your calculation instead.
But the problem is, I am getting either 18 or 300 as height. 300 is
the actual height of the div#lightbox,I don't know why the same
function is returning different heights randomly -Rajat Saxena
At original post
var self = this;
console.log(self);
var lightbox_height = $(self).height();
window.innerHeight appear to return viewport of window . See Window.innerHeight .
Try, at console , this page , while periodically adjusting console "height" , and within piece at original post
console.log($(window).height()
, $(self).height()
, $(window)[0].innerHeight
, $(window).height() === $(self).height()
, $(this).height());
If you're only supporting modern browsers then you could use CSS and take advantage of a flexbox http://css-tricks.com/snippets/css/a-guide-to-flexbox/
Related
I am currently implementing a tool for a project, and I am having some difficulties to remove some extra space at the bottom of the main container.
Basically, the container that contains the drawings-list and the map, resizes itself on window resize event. The bottom bar is fixed, so it does not affect anything.
$(window).on('resize', function () {
resize();
});
function resize() {
var height = $(window).height();
var width = $(window).width();
var mapHeight = height-260; // 260 for fixed elements
var mapWidth = width-360; // 360 for left hand side list
$('.map-drawings-container ul').height(mapHeight);
$('#map_parent_container > .map').height(mapHeight);
$('.drawings-list').height(mapHeight);
}
When the page is first loaded, it renders properly. Then when shrinking it, we can see a space that seems to be equal to the difference between the original page height and the current one.
Changing the size of the html and body element does NOT fix the issue.
Using the Google Chrome Dev tool, I am not able to select that grey background.
Changing margin-bottom to a negative value on the main container does not remove that space either.
Any clue on how to get this space removed?
Thanks
Sure you don't have an element inside that extends beyond the body with a min-height set on it. This would push the sticky footer down when the body shrinks below that min-height creating the extra space?
Look for all elements with a min-height and try shrinking them.
When the page is first loaded, it renders properly. Then when
shrinking it, we can see a space that seems to be equal to the
difference between the original page height and the current one.
May problem is: resizing the page so try that:
$(window).resize(function(){
var height = $(window).height();
var width = $(window).width();
var mapHeight = height-260; // 260 for fixed elements
var mapWidth = width-360; // 360 for left hand side list
$('.map-drawings-container ul').height(mapHeight);
$('#map_parent_container > .map').height(mapHeight);
$('.drawings-list').height(mapHeight);
});
I have a function that corrects and adapts the size (and vertical alignment) of three fluid columns with text and images.
The script, while not polished/efficient yet, works exactly as expected but sometimes(?) fails at the beginning.
The functions is the following:
var resetHeight = function(){
var maxHeight = 0;
$(".same-height-col").height("auto").each(function(){
maxHeight = $(this).height() > maxHeight ? $(this).height() : maxHeight;
}).height(maxHeight + 25);
var maxTextSize = 0;
var tempHeight;
$(".same-height-col").each(function(){
tempHeight = $(this).find(".links-text").height();
maxTextSize = tempHeight > maxTextSize ? tempHeight : maxTextSize;
});
var topMargin;
$(".same-height-col").each(function(){
topMargin = (maxTextSize - $(this).find(".links-text").height()) + 25;
$(this).find(".links-image").css("margin-top",topMargin);
});
}
The I call it twice:
$(document).ready(function() {
resetHeight();
$(window).resize(function() {
resetHeight();
});
});
The problem is that many times when I load the page, I see this:
That doesn't happen consistently, but it does happen pretty often, but as soon as I resize the window the script works exactly as expected:
So where could the mistake be?
The script is called for sure even at the beginning, if I put an alert in the function, and just load the page (with no resize), the alert pops up.
When you calculate the maxHeight value, you reset all the inline heights that were set in the previous resetHeight call by doing $(".same-height-col").height("auto"). However, you don't reset the margin-top properties that were added to the links-image elements.
This means that the second time that resetHeight is called (and all subsequent times), the maxHeight calculations will be different. To make sure the results are the same each time, you need to reset the margin-top property on the links-image elements before doing the calculation.
$(".same-height-col .links-image").css("margin-top","");
$(".same-height-col").height("auto").each(function(){
maxHeight = $(this).height() > maxHeight ? $(this).height() : maxHeight;
}).height(maxHeight + 25);
You may also want to make that height maxHeight+50 rather than maxHeight+25 if you think the result of the layout after the resize looked better than the intial layout on load.
As i understand your issue, you should set attribute width and height of images and use the document ready handler:
HTML for all images in .links-image DIVs: {width/height/alt attributes should always be specified for image when possible}
<div class="links-image" style="margin-top: 53px;">
<img src="img/list.png" width="210" height="92" alt="">
</div>
JS code:
$(document).ready(function() {
$(window).resize(resetHeight).trigger('resize');
});
I’m starting with the premise that you want the box content components — the title, the subtitle, and the image — vertically aligned across all the three boxes. If this is not true, just ignore this answer.
While I can’t spot the issue in the code at hand, I would try to approach it another way, without JS: clearfix the columns and fix the height of the components: let’s say I expect titles to be one line of text, subtitles three lines, and images are already fixed-height.
The fixed height will give you vertical alignment, and the clearfix will take care of the column height.
I'm trying to produce a photo slider that is dynamically sized according to the viewport size, but maintains a 4:3 ratio regardless of viewport dimensions.
The page I'm working on is here:
http://steph-morris.com/thenovel_III.html
Width is currently being calculated by grabbing the viewport width and subtracting the size of the menu bars, like so:
$(document).ready(function(){
var height = $(window).height(), width = $(window).width();
$('img').css('width', (width - (281+(height*0.32))) + 'px');
});
(Where one menu is a known width of 281px and the other menu is calculated as height*0.32).
I need to calculate height in relation to width in a 4:3 ratio.
I am brand new to jQuery maths and haven't been able to get a working nested equation that does something like
$('img').css('height', ((width - (281+(height*0.32))*thecorrectratio) + 'px');
Also, this is not an efficient approach- I should be storing the outcome of the 'width' calculation I think and calculating it more as
$('img').css('height', (widthvalue*thecorrectratio) + 'px');
But I also don't know how to do that with jQuery.
So I would really appreciate any assistance with (a) how to write a good nested equation to work out the value of 'height', or (b) how to save the outcome of the 'width' equation so that it can be used again, and obviously (c) the correct way to calculate a 4:3 ratio.
you can write an equation with a function :
$(document).ready(function(){
function height43(width){
return Math.floor(parseInt(width)/4*3);
}
var menuWidth = 281;
var slideWidth = $(window).width()-menuWidth;
var slideHeight = height43(slideWidth);
// all variables and functions declared directly inside some brackets
// are available everywhere inside or subinside these brackets so you can reuse them
function anotherFunctionSample(){
alert('slideHeight : '+slideHeight);
alert('new calculation with another width : '+height43(700));
}
anotherFunctionSample();
});
Then please have a look at javascript basis before trying going elsewhere...and maybe some primary Math lessons about cross product ;)
Then jQuery is 'just' a javascript wrapper that helps a lot through different browser compatibilities interpreting things quite differently...work hard
I am trying to animate the div to its full height when a button is pressed and come back to its original height if the button is clicked again. The full height of the div is auto as it contains text with different word counts. I tried doing the below codes but it does not work properly.
The CSS :
.category_brief{
text-align:justify;
height:100px;
overflow:hidden;
}
Example 1 : This code does not animate the div when opening to full height , but animates while coming back to old height.
$(".slide").toggle(function(){
$('.category_brief').animate({height:'100%'},200);
},function(){
$('.category_brief').animate({height:100},200);
});
Example 2 : The output of this code is the same as of Example 1
var toggle = true, oldHeight = 0;
$('.slide').click(function(event) {
event.preventDefault();
var $ele = $('.category_brief');
var toHeight = ((toggle = !toggle) ? oldHeight : newHeight);
oldHeight = $ele.height();
var newHeight = $ele.height('auto').height();
$ele.animate({ height: toHeight });
});
Example 3 : This code animates the div to its full height but does not toggle.
var slide = $('.slide');
var slidepanel = $('.category_brief');
// On click, animate it to its full natural height
slide.click(function(event) {
event.preventDefault();
var oldHeight, newHeight;
// Measure before and after
oldHeight = slidepanel.height();
newHeight = slidepanel.height('auto').height();
// Put back the short height (you could grab this first
slidepanel.height(oldHeight);
slidepanel.animate({height: newHeight + "px"});
});
If possible please provide a bit explanation also as i am a newbie..
Update : Solved by the idea from #chazm..
#chazm : thanks for the idea. I got it working by combining 1st and 3rd example ... Here is the code in case anyone needs it .
var slidepanel = $('.category_brief');
$(".slide").toggle(function(){
var oldHeight, newHeight;
// Measure before and after
oldHeight = slidepanel.height();
newHeight = slidepanel.height('auto').height();
// Put back the short height (you could grab this first
slidepanel.height(oldHeight);
slidepanel.animate({height: newHeight + "px"})
},function(){
$('.category_brief').animate({height:100},300);
});
Working with 'auto' height it always quite tricky. I think there are different issues in your examples.
1) Browser can't define correct 100% height. Possible solutions - define height to all its parents. Either set it to 100% (till html tag) or set closest parent as relative (because height is calculated from closest relative parent). If you want to animate div to 100% of the entire page - think of the absolute positioning
2)The same as above i assume
3)When this code supposed to toggle back it can't determine that it should become lower that it is now. Not absolutely sure why though. Probably because 'auto' height from 100% is set to something wrong. You may check in firebug what value it has on the computed tab after that function is toggled back. Probably it will give you a clue
Try to combine 2) and 3). The idea - if toggle is true (it shoud be lowered) then set newHeight = slidepanel.height('100').
The solution depends on your implementation needs. If you know that at first the div should be 100px etc in height and when you click, it maximizes to an unknown height, the following solution would work. If you had a structure similar to
<div class="outer">
<div class="wrapper">Content of unknown length here</div>
</div>
and css
div.wrapper { position:relative; height:100px; overflow:hidden; }
div.outer { position:absolute; height:auto; }
then you'd get a div that is 100px in height, with the content that doesn't fit in 100px cut off. Now when you press the desired button, you could get the height of the wrapper div, since it is a long as it's content is (even though you only see the top 100px) and set the outer div's height according to it. Like so
var newHeight = $('div.wrapper').height();
$('div.outer').animate({height:newHeight},200);
Which would then animate the outer div to display the whole contents. When you click the button again, you could just do
$('div.outer').animate({height:'100px'},200);
And you would again have only the 100px height.
I have the following function for calculating the height of .node. It then takes away the height of a possible image, .node-image, from the height of the .node, and sets a column, .node-content-column to have a height that is the difference (i.e. 500 - 50 = 450; column becomes 450 in height).
function initColumnSizer() {
imageHeight = $('.node-image').outerHeight(true);
resizeHeight = ($('.node').outerHeight() + 75) - imageHeight;
$('.node-content-column').removeAttr('style');
$('.node-content-column').css('min-height', resizeHeight);
$('.node-content-column').css('height', 'auto !important');
$('.node-content-column').css('height', resizeHeight);
}
This function gets called on page load, and resizes .node-content-column as expected.
It also gets called when a div within .node is toggled using jQuery.toggle(), but this calculation returns a larger number everytime, instead of reverting back to the original once this toggle is reverted.
Can anyone see where I am going wrong with this calculation? Or if I am going about it the wrong way?
Thanks in advance!
Karl
1) Maybe the problem is in outerHeight() function (it takes into account padding and border). Try using just height or clientHeight:
var img = document.getElementById('imageid');
//or however you get a handle to the IMG
var width = img.clientWidth;
var height = img.clientHeight;
2) why do you need to cleanup the whole elements' style?
and then you try to assign height = auto, and after that: height = resizeHeight - what's the purpose for that ? check the logic of your code.
outerHeight(true) will return height + padding + border + margin. Possibly, you might want to use height() ?
Most possible is that "larger number everytime" have always constant difference -- for example 75.
May be you just have some dependecies between .node-content-column and .node?
If your nodes like .node-content-column, .node and .node-image are all singles, then it's better to use IDs for them -- not CSS classes.