How to set height of div and animate width at same time - javascript

I am trying to replicate the left nav at this website: http://www.kahuna-webstudio.fr/.
As you can see when you scroll down about 200 pixels the left nav appears. I almost have it with one problem: I am currently animating the height and width of my div at the same time. What I want to do is set the height of the left nav div to the document height, and then when you scroll down exactly 296 pixels the width will grow to 150 pixels. Hope that makes sense.
So my question is: how can I set the height of this div to the document height, and then a second step would be to animate the width.
This is the line I am currently using:
$("#slidebottom").stop().animate({height:docheight +"px", width:newwidthgrow + "px"},'fast');
What I want to work, but is not working is:
slidebottomHeight = docheight;
$("#slidebottom").stop().animate({width:newwidthgrow + "px"},'slow');
Here is my current code:
$(window).scroll(function(){
var wintop = $(window).scrollTop();
var docheight = $(document).height();
var winheight = $(window).height();
var newwidthgrow = 150;
var smallheight = 0;
var smallwidth = 0;
var slidebottomHeight = $("slidebottom").height();
if((wintop > 296)) {
$("#slidebottom").stop().animate({height:docheight +"px", width:newwidthgrow + "px"},'fast');
}
if((wintop < 296))
{
$("#slidebottom").stop().animate({height:smallheight +"px", width:smallwidth + "px"}, 'fast');
}
});

If I understood correctly, you want to execute two action in sequence. If that is the case, you can use the callback for .animate. This callback is executed when the animation complete. Hence you can:
set the height
wait for the height to be set
fire the callback
Which in code becomes something like:
$("#slidebottom").stop().animate({width:newwidthgrow + "px"},'slow', function(){
$("#slidebottom").animate({
width:newwidthgrow + "px"
});
});
You can read more about the callback and .animate here.

$("#slidebottom").stop().animate({
height:docheight +"px"
},'fast',function(){
// This is a callback function. It will be called when the animation
// has finished executing.
$("#slidebottom").stop().animate({
width:newwidthgrow + "px"
});
});

Related

Animate when certain pixels into viewport (Pen by Bramus)

I'm using the following pen by Bramus to animate(FadeInUp) divs when entering the viewport. However currently the div only starts fading in when the div is completely in the viewport. What I need is the flexibility to start the animation when a div is a certain pixels inside the viewport. For example it will start the animation FadeInUp when the div is 100 pixels in the viewport. How can I do this with the current code/pen I'm using (see code below)?
Is this also possible with percentages? F.e. when a div is 20% in viewport the animation starts?
Thanks.
jQuery(function($) {
// Function which adds the 'animated' class to any '.animatable' in view
var doAnimations = function() {
// Calc current offset and get all animatables
var offset = $(window).scrollTop() + $(window).height(),
$animatables = $('.animatable');
// Check all animatables and animate them if necessary
$animatables.each(function(i) {
var $animatable = $(this);
if (($animatable.offset().top + $animatable.height() - 20) < offset) {
$animatable.removeClass('animatable').addClass('animated');
}
});
};
// Hook doAnimations on scroll, and trigger a scroll
$(window).on('scroll', doAnimations);
$(window).trigger('scroll');
});
Offsetting is already foreseen in the code. Tweak the value of 20 in this line:
if (($animatable.offset().top + $animatable.height() - 20) < offset) {
You might also need to change the - sign to a + to suit your needs.

How can you constantly check when the height of the scrollbar has changed using jquery

I want to detect whenever the user changes the height of the scrollbar. Right now the script I have detects it once (when the user moves the scrollbar down) but when you move the scrollbar again nothing happens. My logic is that when the user moves the scrollbar to a position greater than 296 a div appears using animate(), and this works. But when the user moves the scrollbar to a position less than 296 the div should disappear using animate(). My code is below. Can anyone help? Thanks a lot.
$(window).scroll(function(){
var wintop = $(window).scrollTop();
var docheight = $(document).height();
var winheight = $(window).height();
var newWidthGrow = 500;
var smallHeight = 0;
var smallWidth = 0;
if(wintop > 296)
{
$("#slidebottom").animate({height:docheight +"px", width:newWidthGrow + "px"},'fast');
}
if(wintop < 296)
{
$("#slidebottom").animate({height:smallheight +"px", width:smallWidth + "px"}, 'fast');
}
});
Two issues here:
You initiate a variable named smallHeight but you use smallheight, which causes an error.
You should add the .stop()-method before running another animation like that:
$("#slidebottom").stop().animate();
And you should consider to run each animation only once and not any time the scroll event is fired. A boolean can be helpful here:
if(wintop < 296 && expanded) {
expanded = false;
$("#slidebottom").stop().animate();
}
Demo
Try before buy

how to re-calculate variables in javascript

function scrollContent(){
var div = $('#scrolling-content'),
ul = $('ul.image'),
// unordered list's left margin
ulPadding = 0;
//Get menu width
var divWidth = div.width();
//Remove scrollbars
div.css({overflow: 'hidden'});
//Find last image container
var lastLi = ul.find('li:last-child');
//When user move mouse over menu
div.mousemove(function(e){
//As images are loaded ul width increases,
//so we recalculate it each time
var ulWidth = lastLi[0].offsetLeft + lastLi.outerWidth() + ulPadding;
var left = (e.pageX - div.offset().left) * (ulWidth-divWidth) / divWidth;
div.scrollLeft(left);
});
}
This is how I scroll my image list. The problem is that #scrolling-content element's size is dynamic. It changes on window resize. Here;
$(window).resize(function() {
$("#scrolling-content").css("width",$(window).width() + "px");
$("#scrolling-content").css("height",($(window).height()-400) + "px");
});
So it has to recalculate the left value when user changes windows size. How sould I change script to do that? Recalling scrollContent() function with window.resize function is a noob solution I guess. And it creates conflict for IE.
You could set the width on resize and make your function call the variable like so. This method turns your function into a js object and the window update resets the width var inside that object. Course now you call the function like this: scrollContent.scroll();
var scrollContent = {
width: 0,
scroll:function(){
var div = $('#scrolling-content'),
ul = $('ul.image'),
// unordered list's left margin
ulPadding = 0;
//Get menu width
scrollContent.width = div.width();
//Remove scrollbars
div.css({overflow: 'hidden'});
//Find last image container
var lastLi = ul.find('li:last-child');
//When user move mouse over menu
div.mousemove(function(e){
//As images are loaded ul width increases,
//so we recalculate it each time
var left = (e.pageX - div.offset().left) * (ulWidth-scrollContent.width) / scrollContent.width;
div.scrollLeft(left);
});
}
};
$(window).resize(function() {
$("#scrolling-content").css("width",$(window).width() + "px");
$("#scrolling-content").css("height",($(window).height()-400) + "px");
scrollContent.width = $(window).width();
});
You can also just declare a standard js var and use that to keep things simple. I just prefer working with js objects to eliminate possible var interference.

Continuously check page (client) height and change footer height according to that value

At my website, I try to accomplish (with javascript) that the footer height changes if the page height is larger then a specific value (907 pixels, the body height). It also needs to change if the page height changes (so if the viewer changes his client height).
I use jQuery to get the page height, but I need it's continuously checked, and not only when the page loads.
This is the snippet I use:
$(document).ready(function(){
var windowheight = $(window).height();
if(windowheight >= "907") {
var extrafooterheight = windowheight - 907;
$('#footer').height(40 + extrafooterheight);
$('body').height(907 + extrafooterheight);
}
});
Thanks for your help.
I suggest attaching to the resize event of the window using jQuery:
$(document).ready(function(){
$(window).resize(function() {
var windowheight = $(window).height();
if(windowheight >= "907") {
var extrafooterheight = windowheight - 907;
$('#footer').height(40 + extrafooterheight);
$('body').height(907 + extrafooterheight);
}
});
});
Take a look at the jQuery resize() docs.

How do I get an element to scroll into view, using jQuery?

I have an HTML document with images in a grid format using <ul><li><img.... The browser window has both vertical & horizontal scrolling.
Question:
When I click on an image <img>, how then do I get the whole document to scroll to a position where the image I just clicked on is top:20px; left:20px ?
I've had a browse on here for similar posts...although I'm quite new to JavaScript, and want to understand how this is achieved for myself.
There's a DOM method called scrollIntoView, which is supported by all major browsers, that will align an element with the top/left of the viewport (or as close as possible).
$("#myImage")[0].scrollIntoView();
On supported browsers, you can provide options:
$("#myImage")[0].scrollIntoView({
behavior: "smooth", // or "auto" or "instant"
block: "start" // or "end"
});
Alternatively, if all the elements have unique IDs, you can just change the hash property of the location object for back/forward button support:
$(document).delegate("img", function (e) {
if (e.target.id)
window.location.hash = e.target.id;
});
After that, just adjust the scrollTop/scrollLeft properties by -20:
document.body.scrollLeft -= 20;
document.body.scrollTop -= 20;
Since you want to know how it works, I'll explain it step-by-step.
First you want to bind a function as the image's click handler:
$('#someImage').click(function () {
// Code to do scrolling happens here
});
That will apply the click handler to an image with id="someImage". If you want to do this to all images, replace '#someImage' with 'img'.
Now for the actual scrolling code:
Get the image offsets (relative to the document):
var offset = $(this).offset(); // Contains .top and .left
Subtract 20 from top and left:
offset.left -= 20;
offset.top -= 20;
Now animate the scroll-top and scroll-left CSS properties of <body> and <html>:
$('html, body').animate({
scrollTop: offset.top,
scrollLeft: offset.left
});
Simplest solution I have seen
var offset = $("#target-element").offset();
$('html, body').animate({
scrollTop: offset.top,
scrollLeft: offset.left
}, 1000);
Tutorial Here
There are methods to scroll element directly into the view, but if you want to scroll to a point relative from an element, you have to do it manually:
Inside the click handler, get the position of the element relative to the document, subtract 20 and use window.scrollTo:
var pos = $(this).offset();
var top = pos.top - 20;
var left = pos.left - 20;
window.scrollTo((left < 0 ? 0 : left), (top < 0 ? 0 : top));
Have a look at the jQuery.scrollTo plugin. Here's a demo.
This plugin has a lot of options that go beyond what native scrollIntoView offers you. For instance, you can set the scrolling to be smooth, and then set a callback for when the scrolling finishes.
You can also have a look at all the JQuery plugins tagged with "scroll".
Here's a quick jQuery plugin to map the built in browser functionality nicely:
$.fn.ensureVisible = function () { $(this).each(function () { $(this)[0].scrollIntoView(); }); };
...
$('.my-elements').ensureVisible();
After trial and error I came up with this function, works with iframe too.
function bringElIntoView(el) {
var elOffset = el.offset();
var $window = $(window);
var windowScrollBottom = $window.scrollTop() + $window.height();
var scrollToPos = -1;
if (elOffset.top < $window.scrollTop()) // element is hidden in the top
scrollToPos = elOffset.top;
else if (elOffset.top + el.height() > windowScrollBottom) // element is hidden in the bottom
scrollToPos = $window.scrollTop() + (elOffset.top + el.height() - windowScrollBottom);
if (scrollToPos !== -1)
$('html, body').animate({ scrollTop: scrollToPos });
}
My UI has a vertical scrolling list of thumbs within a thumbbar
The goal was to make the current thumb right in the center of the thumbbar.
I started from the approved answer, but found that there were a few tweaks to truly center the current thumb. hope this helps someone else.
markup:
<ul id='thumbbar'>
<li id='thumbbar-123'></li>
<li id='thumbbar-124'></li>
<li id='thumbbar-125'></li>
</ul>
jquery:
// scroll the current thumb bar thumb into view
heightbar = $('#thumbbar').height();
heightthumb = $('#thumbbar-' + pageid).height();
offsetbar = $('#thumbbar').scrollTop();
$('#thumbbar').animate({
scrollTop: offsetthumb.top - heightbar / 2 - offsetbar - 20
});
Just a tip. Works on firefox only
Element.scrollIntoView();
Simple 2 steps for scrolling down to end or bottom.
Step1: get the full height of scrollable(conversation) div.
Step2: apply scrollTop on that scrollable(conversation) div using the value
obtained in step1.
var fullHeight = $('#conversation')[0].scrollHeight;
$('#conversation').scrollTop(fullHeight);
Above steps must be applied for every append on the conversation div.
After trying to find a solution that handled every circumstance (options for animating the scroll, padding around the object once it scrolls into view, works even in obscure circumstances such as in an iframe), I finally ended up writing my own solution to this. Since it seems to work when many other solutions failed, I thought I'd share it:
function scrollIntoViewIfNeeded($target, options) {
var options = options ? options : {},
$win = $($target[0].ownerDocument.defaultView), //get the window object of the $target, don't use "window" because the element could possibly be in a different iframe than the one calling the function
$container = options.$container ? options.$container : $win,
padding = options.padding ? options.padding : 20,
elemTop = $target.offset().top,
elemHeight = $target.outerHeight(),
containerTop = $container.scrollTop(),
//Everything past this point is used only to get the container's visible height, which is needed to do this accurately
containerHeight = $container.outerHeight(),
winTop = $win.scrollTop(),
winBot = winTop + $win.height(),
containerVisibleTop = containerTop < winTop ? winTop : containerTop,
containerVisibleBottom = containerTop + containerHeight > winBot ? winBot : containerTop + containerHeight,
containerVisibleHeight = containerVisibleBottom - containerVisibleTop;
if (elemTop < containerTop) {
//scroll up
if (options.instant) {
$container.scrollTop(elemTop - padding);
} else {
$container.animate({scrollTop: elemTop - padding}, options.animationOptions);
}
} else if (elemTop + elemHeight > containerTop + containerVisibleHeight) {
//scroll down
if (options.instant) {
$container.scrollTop(elemTop + elemHeight - containerVisibleHeight + padding);
} else {
$container.animate({scrollTop: elemTop + elemHeight - containerVisibleHeight + padding}, options.animationOptions);
}
}
}
$target is a jQuery object containing the object you wish to scroll into view if needed.
options (optional) can contain the following options passed in an object:
options.$container - a jQuery object pointing to the containing element of $target (in other words, the element in the dom with the scrollbars). Defaults to the window that contains the $target element and is smart enough to select an iframe window. Remember to include the $ in the property name.
options.padding - the padding in pixels to add above or below the object when it is scrolled into view. This way it is not right against the edge of the window. Defaults to 20.
options.instant - if set to true, jQuery animate will not be used and the scroll will instantly pop to the correct location. Defaults to false.
options.animationOptions - any jQuery options you wish to pass to the jQuery animate function (see http://api.jquery.com/animate/). With this, you can change the duration of the animation or have a callback function executed when the scrolling is complete. This only works if options.instant is set to false. If you need to have an instant animation but with a callback, set options.animationOptions.duration = 0 instead of using options.instant = true.

Categories

Resources