Sticky Sidebar that only sticks when sidebar bottom is at window bottom
i get this site ( got to bootstrap sticky example)
javascript
$(function() {
var win = $(window);
var doc = $(document);
var wh = win.height();
var dh = doc.height();
var sidebar = $('.rightside .stickybar');
var sot = sidebar.offset().top;
var sh = sidebar.height();
var elementToBottom = dh - sot - sh;
// reset the sidebar width
var wt = sidebar.width();
sidebar.width(wt);
win.scroll(function(){
var dst = doc.scrollTop();
var scrollBottom = dh - dst - wh;
if(scrollBottom <= elementToBottom) {
sidebar.addClass('fixToBottom');
} else {
sidebar.removeClass('fixToBottom');
}
});
});
css
.fixToTop {
position: fixed;
top: 50px;
}
.fixToBottom {
bottom: 60px;
position: fixed;
}
html
<header> </header>
<div class="contents">
<div class = "leftside"> left</div>
< div class="righside">
<div class="stickybar">
// when move scrolling up and down
</div>
</div>
</div>
<footer> footer </div>
I have a 2 column layout. The left column is way longer than the sidebar. I want the sidebar only to stick when its bottom reaches the bottom of the browser window. So the user can continue to scroll down the left column content while the right sidebar sticks. I've seen a lot of sticky questions here, however this particular situation still stumps me. I also have a sticking headline bar on the left column that i've successfully gotten to stick.
Check out this example, I whipped up.
http://www.bootply.com/hVx29SmQ4g
If you or anyone has any questions, just send me a message and I'll try to explain. I commented the code however, so it should be quite straightforward. I hope its what you needed though!
:::CODE:::
/*
=== JS ===
============
Author: Kevin Leegsma
Updated: Feb 10, 2015
Notes: Coded for Stack Overflow - re: Sticky Sidebar
*/
/* Base function that waits till rest of site loads and then executes */
$(document).ready(function () {
"use strict";
/* activate sidebar, this can also be done as in-line HTML using the following line, instead of the Javascript below */
/* <div class = "col-xs-4" id = "rightColumn" data-spy = "affix" data-offset-bottom = "200"> */
$('#sidebar').affix({
offset: {
top: 400 /* both TOP and BOTTOM can be used here, tweek to your own needs */
}
});
/*This function gets the WIDTH of the wrapper and maintains it for the SIDEBAR*/
/*It does this by setting the WRAPPER as the PARENT, it then calls a function to resize the child (SIDEBAR)
in this case equal to the parent size.*/
/*NOTE: Without this function, the AFFIX still works, just doesn't function as nicely as it doesn't follow
standard Bootstrap grid CSS rules. */
$('#sidebar').each(function () {
var elem = $(this);
var parentWrapper = $('#sidebarWrapper');
var childToParentResize = function () {
var sidebarWidth = $(parentWrapper).width();
elem.width(sidebarWidth);
};
childToParentResize();
$(window).resize(childToParentResize);
});
/* Alert to inform you the SIDEBAR has become fixed, can be removed/commented, just for testing, but helpful for those new to AFFIX */
$('#sidebar').on('affixed.bs.affix', function(){
alert("The left navigation menu has been affixed. Now it doesn't scroll with the page.");
});
});
/* CSS used here will be applied after bootstrap.css
=== CSS ===
=============
Author: Kevin Leegsma
Updated: Feb 10, 2015
Notes: Coded for Stack Overflow - re: Sticky Sidebar
--------------------------------------
Layout
-------------------------------------- */
/* Targets the SIDEBAR once the affix has become active */
/* Adjust these to cater to your layout settings */
#sidebar.affix{
top: 10px;
right: 8.5%;
}
/*
==============
=== HTML ===
==============
Author: Kevin Leegsma
Updated: February 10, 2015
Notes: Coded for Stack Overflow - re: how-use-sticky-sidebar-move-up-when-window-scroll-top
*/
<!-- Main Code -->
<div class="container" id="main">
<!-- Left column with dummy text -->
<div class="col-xs-8" id="leftColumn">
<h1> LEFT COLUMN</h1>
<h3>With Even More Filler Text!</h3>
<p>...a bunch of text...</p>
</div><!--end leftColumn-->
<!-- Right column/sidebar that affixes itself as the window is scrolled -->
<!-- Stuck within a col-xs-4 parent element, this is because the AFFIX
has wonky width controls, they ignore Bootstrap grids and aren't responsive
with this wrapper and the JS however, it resizes well. -->
<div class="col-xs-4" id="sidebarWrapper">
<div id="sidebar" data-spy="affix">
<h1> SIDEBAR</h1>
<h3>With Filler!</h3>
<small>
<p>...sidebar text/links...</p>
</small>
</div><!--end sidebar-->
</div><!--end sidebarWrapper-->
</div><!--end container-->
I'm not at my computer at home right now, if it still isn't answered by tonight I'll whip up an example.
However if I'm reading what you need correctly, all you need to do is give the one element, that's to be fixed, the AFFIX property either through HTML/CSS
<div id="sidebar" data-spy="affix" data-affix-bottom="50">
NOTE -> the data-affix-bottom is an offset number, so tweak it to suit your needs
Or through JavaScript
$("#sidebar").affix({
offset: {
bottom: someValue
}
}
});
Some useful links that explain it more in depth:
http://getbootstrap.com/javascript/#affix
And
http://goo.gl/8knwd4 (With a scrolling sidebar example)
Related
I've got a single page site with two div modules that expand when clicked.
The first is at the top, in the Hero section and with the current code works as desired. The second is much further down the page in another section. Currently this second module closes as soon as the scroll takes place.
What I need to do is get the documents scroll coordinates when the div is clicked. Then once the user scrolls 200px up or down the div closes back up. Regardless of where it (the div) is on the site.
All the questions I found here and elsewhere only refer to setting the scroll tolerance relative to the window position on page load. But for me that's no goon. This site is responsive, and as it changes the initial positions of the div's will / can be unknown. I need someway of dynamically storing the viewports scroll position when the div's are clicked and assigning the 200px tolerance then.
I hope that makes sense. I've been at this for like 12+hrs now. SOS :)
Here's the Fiddle
If you don't want to go over to Fiddle, Here's the requisite code
HTML:
<body>
<section id="hero">
<div>
<div class="module-cta hero-cta">
<a class="module-cta__button"><!-- Fallback location -->
<span class="module-cta__text">PRESS ME</span>
</a>
<div class="module-cta__open">
<div class="module-cta__open-inner">
<div class="hero-cta__contact-points">
<div class="phone">
<div class="hero-cta_contact_logo">
<span><!-- phone.svg" --></span>
</div><!-- .service-logo -->
<div class="contact_trigger">
<a>Scroll down to 200px to see</a>
</div><!-- .contact_trigger -->
</div><!-- .phone -->
<div class="email">
<div class="hero-cta_contact_logo">
<span><!-- email.svg --></span>
</div><!-- .service-logo -->
<div class="contact_trigger">
<a>this div fold back up</a>
</div><!-- .contact_trigger -->
</div><!-- .email -->
</div><!-- .hero-cta__contact-points -->
<button class="module-cta__close module-cta__cancel"><i class="icon"><span></span></i></button>
</div><!-- .hero-cta__open-inner -->
</div><!-- .hero-cta__open -->
</div><!-- .hero-cta -->
</div>
</section>
<section class="spacer"></section>
<section id="service_area">
<div class="area_input">
<div class="module-cta area-cta wow fadeInUp" id="form_module">
<a class="module-cta__button area-cta__button">
<span class="module-cta__text area-cta__text">NOW PRESS ME</span>
</a>
<div class="module-cta__open area-cta__open">
<div class="module-cta__open-inner area-cta__open-inner">
<div class="area-cta__search">
<form class="postcode_form" id="postcode_form" name="postcode_form" action="#">
<input type="number" id="your_postcode" class="your_postcode" name="postcode" placeholder="3???">
<button type="button" class="area-btn"><span></span></button>
<a class="call-now">##########</a>
</form>
</div><!-- .area-cta__search -->
<button class="module-cta__close module-cta__cancel"><i class="icon"><span></span></i></button>
</div><!-- .area-cta__open-inner -->
</div><!-- .area-cta__open -->
</div><!-- .area-cta -->
</div><!-- .area_input -->
</section>
<section class="spacer"></section>
</body>
Script:
I'm sure a lot of this can be cleaned up and shrunk, but for now I'm just trying to get it all going.
// opens & closes modules by clicking module name
$('.module-cta__button').on('click', function(){
if($(this).parent().hasClass('hero-cta')){
$(this).parent().toggleClass('module-cta--active');
} else {
if($(this).parent().hasClass('area-cta')){
$(this).parent().toggleClass('module-cta--active');
}
}
});
// closes modules with .module-cta__close btn
$('.module-cta__close').on('click', function(){
if($(this).closest('div .module-cta').hasClass('module-cta--active')){
$(this).closest('div .module-cta').removeClass('module-cta--active');
}
});
// closes modules on scroll.
// * works but doesn't apply scroll tolerance of 200px for #area
$(window).scroll(function(){
var currentPos = $(window).scrollTop();
var module = $('div .module-cta');
if(module.hasClass('module-cta--active') && module.position().top <= currentPos+200){
$('div .module-cta--active').removeClass('module-cta--active');
}
});
// closes modules when escape key is pressed
$(window).keydown(function(escape){
var key = escape.which;
if(key == 27){
$('div .module-cta--active').removeClass('module-cta--active');
}
});
see Fiddle for css
Thanks for any help or useful suggestions in advanced.
I've put together a much smaller and simpler demonstration, just to show you what variables you need to accomplish this. Essentially, when a div is clicked, capture the current document scroll position using $(document).scrollTop(). Also store a refference to the current div that has been clicked.
When scrolling, check the difference between the current scroll and the new scroll, and using your clicked div reference, shrink the div when the difference is 200 or greater. JS fiddle below;
https://jsfiddle.net/jLqu4pas/
Code from Fiddle;
var currentScroll;
var lastClickedDiv;
$('section').click(function(){
$(this).css({'height' : '400'})
currentScroll = $(document).scrollTop();
lastClickedDiv = $(this);
console.log(currentScroll);
})
$(window).scroll(function(){
if($(document).scrollTop() > currentScroll + 200){
lastClickedDiv.css({'height' : 0})
}
})
So I've put together a script that will potentially help you.
I've done some basic testing on it, but if you come across any problems make a comment.
// Generate offsets and return them as an object
function generateOffsets($element, tolerance)
{
var offsets = $element.offset(),
offsetTop = offsets.top;
return {
scrollPos: offsetTop,
toleranceTop: offsetTop - tolerance,
toleranceBottom: offsetTop + tolerance
};
}
// Run a callback when the user leaves the scroll tolerance of a set of elements
function closeOnScroll($elements, tolerance, callback)
{
$elements.each(function() {
var $element = $(this),
offsets = generateOffsets($element, tolerance),
resizeEvent;
// On resize, regenerate the offsets so they stay up to date
$(window).on('resize', function(e) {
resizeEvent = e;
offsets = generateOffsets($element, tolerance);
});
// On scroll check if we've left the tolerance area, if so run the event and unbind
$(window).on('scroll', function(e) {
var windowPos = $(this).scrollTop();
if (windowPos < offsets.toleranceTop || windowPos > offsets.toleranceBottom) {
callback($element);
$(this).unbind(e);
$(this).unbind(resizeEvent);
}
});
});
}
// Example: Apply the event to a set of elements
$('.btn').click(function() {
closeOnScroll($('div .module-cta'), 200, function($element) {
$element.removeClass('module-cta--active');
});
});
The thing to remember with thie script is that it needs to be applied EVERY time the user clicks your button. You may say, WHY WOULD YOU DO THAT - but it actually has some serious performance implications.
The events rely on both scroll and resize, both of which are very slow, especially if not debounced like in this script. However, what I do in the script is unbind the events once it has occured. Otherwise, the resize and scroll would keep happening for each and every one of your buttons until the end of time. By 'unbinding' the event, you ensure long running performance of your page.
Wouldn't want to ruin those pretty animations would we?
Well, i am stucked and can't find the answer myself. Hopefully someone can give me a hint.
I try to fullfill the following requirements:
There should be a Newsblock within a HTML Page with a fixed width and
height.
In this Newsblock only the title of the news are visible.
Those news are "collapsed" by default and should "expand" if the Mouse is over it.
Due the fact that the 'Newsblock' is limited by its height, there should be a Scrollbar visible. But only if the currently expanded news makes it necessary, so the user can Scroll down.
Newstitle and Newstext should never leave the Newsblock.
so far so good, i was able to fullfill all those demands except the one with the Scrollbar. If i try to reach the Scrollbar out of the currently expanded news it collapses again and the Scrollbar disappears. I understand that my .hover is configured that it always SlideUp if i leave the newsentry and the Scrollbar isn't a part of the newsentry div. But i have no idea what to change to still have an overall Scrollbar for the Newsblock, but won't disappear if i try to 'reach' it.
P.s.: A Scrollbar only per Newsentry looks weird. Thats why i want 'bind' the scrollbar to the parent container :S
HTML
<div id="newsblock">
<div> // some auto generated div's i have to life with, so the news entries are not 'direct' children of the newsblock.
<div class="newsentry">
<div class="newstitle">...</div>
<div class="newstext">...</div>
</div>
... another 9 'newsentry' divs.
</div>
</div>
JS
$(".newsentry").hover(
function() {
$(this).children(".newstext").stop(true,true).slideDown();
},
function() {
$(this).children(".newstext").stop(true,true).slideUp();
}
);
CSS
.newsblock {
height: 200px;
overflow-y: auto;
}
Instead of closing a .newsentry when the cursor goes out of it, a solution can be to close it only when it enters another .newsentry or when it leaves #newsblock.
The scrollbar being part of #newsblock, the entry isn't closed anymore when you go on it.
EDIT: Following our discussion about the scroll issue, I added a step callback to the closing animation to make sure that the top of the .newsentry getting opened remains visible when the other entries are getting closed.
Here is a working example:
var $newsblock = $("#newsblock");
function closeAllNews(slideUpArgs){
return $(".newstext").stop(true).slideUp(slideUpArgs);
}
function openNews(news, slideDownArgs){
$(news).find(".newstext").stop(true).slideDown(slideDownArgs);
}
function ensureNewsTopVisible(news){
// Check if the top of the newsentry is visible...
var top = $(news).position().top;
if(top < 0){
// ...and if not, scroll newsblock accordingly.
$newsblock.scrollTop($newsblock.scrollTop() + top);
}
}
$(".newsentry").each(function(){
var $this = $(this);
// When the mouse enter a news entry...
$this.on("mouseenter", function(){
// ...close all opened entries (normally there is at most one)...
closeAllNews({
// (while making sure that the top of this entry remains visible
// at each step)
step: ensureNewsTopVisible.bind(null, $this)
});
// ...open this newsentry.
openNews($this);
});
});
// When the mouse get out of the newsblock, close all news.
$newsblock.on("mouseleave", closeAllNews);
.newstitle {
font-size: 2em;
}
.newstext {
display: none;
}
#newsblock {
max-height: 150px;
overflow: scroll;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div id="newsblock">
<div>
<div class="newsentry">
<div class="newstitle">News 1</div>
<div class="newstext"></div>
</div>
<div class="newsentry">
<div class="newstitle">News 2</div>
<div class="newstext"></div>
</div>
<div class="newsentry">
<div class="newstitle">News 3</div>
<div class="newstext"></div>
</div>
<!-- Etc. -->
</div>
</div>
<!-- Ignore the script below. It is just filling in the news' text. -->
<script>
$(".newstext").each(function(i, newstext){
$.get("http://baconipsum.com/api/?type=meat-and-filler&format=html¶s=5&num=" + i)
.then(function(ipsumHtml){
$(newstext).html(ipsumHtml);
});
});
</script>
Try this:
$(".newsentry, .newsblock").hover( // <-- changed
function() {
$(this).children(".newstext").stop(true,true).slideDown();
},
function() {
$(this).children(".newstext").stop(true,true).slideUp();
}
);
This makes sure the block stays open when you hover either over the header or the block itself.
Is that what you mean?
There would be a joke , if i am wrong .. what i thing just change your css as
/* not .newsblock **/
#newsblock {
height: 200px;
overflow-y: scroll;/* not auto*/
}
It will be a lot better if you use click operation instead of hover to slide down news text block because the user can accidentally hover over any of the news entry in order to reach for the scroll bar. I think you need a accordion like functionality. You can use the below code if you are fine with click instead of hover.
$(".newsentry").click(
function() {
$(".newstext").stop(true,true).slideUp();
$(this).children(".newstext").stop(true,true).slideDown();
}
);
Or use the below one to go with hover.
$(".newsentry").hover(
function() {
$(".newstext").stop(true,true).slideUp();
$(this).children(".newstext").stop(true,true).slideDown();
},
function(){}
);
This will not close the news text block until you accidentally hover over another news entry.
I want to set equal heights to my columns in Bootstrap 3. I CAN'T set the rows to 'display: table;' or anything like that cause it screws up the layout of everything.
<article>
<div id="post-<?php the_ID(); ?>"> <!-- just gets the post's id -->
<div class="row">
<div class="col-md-8 indx-img" style="background-image:url('...');">
</div>
<div class="col-md-4 text-cell">
<h1>title</h1>
<h3>category</h3>
</div>
</div><!-- /#row -->
</div><!-- /#post -->
</article>
The content is on the right, a column with a background image is on the left. That column needs a height so that the background image is shown, I want that height applied to the column with the text.
I want it to be responsive height, what I used so far for that is
CSS
indx-img {
padding: 16% 0;
}
problem is that height doesn't apply the the column with the text. The ultimate goal is to have the two columns the same height, with the text vertically centred in the 'text-cell' column
If you can't use any css solutions because they will break your layout, you can use javascript.
Here we define a function named resize which will loop through the posts.
If the page is larger than the break point, set the height of the post container to the height of the image.
Then set the height of the text container to 100% once.
If the page is smaller than the break point, check to see if the height is set.
If it is we remove the height setting to allow natural expansion and contraction.
We call the resize function once on page load, then assign it to the window resize handler
(Demo)
<script type="text/javascript">
window.onload = function() {
(function () {
"use strict";
var resize = function () {
var posts = document.querySelectorAll('[id^="post"] .row'), post;
for (var i = 0; post = posts[i]; i++) {
if (window.innerWidth > 768) {
post.style.height = post.firstElementChild.offsetHeight + 'px';
if(post.lastElementChild.style.height !== '100%') {
post.lastElementChild.style.height = '100%';
}
} else {
if(post.style.height !== '')
post.style.height = '';
}
}
};
window.onresize = resize;
resize();
})();
}
</script>
I use the matchHeight plugin for this kind of issue all the time and it works perfectly with Bootstrap.
Just install the plugin, add a class of matchHeight to your col-md-8 and col-md-4 columns:
<div class="matchHeight col-md-8 indx-img" style="background-image:url('...');">
</div>
<div class="matchHeight col-md-4 text-cell">
<h1>title</h1>
<h3>category</h3>
</div>
And add the following to your javascript:
$('.matchHeight').matchHeight();
You can then use this fix throughout your site by simply repeating the above steps, even several times on the same page (it automatically scopes to within the current "row" element so if you have 3 rows with 6 elements then only those elements in any given row are matched in size).
So I was given a web template that uses a jquery library called sticky, and it "sticks" the navigation (starts at the bottom and moves up) at the top of the page, as you scroll.
I want to be able to plop a logo onto the navigation once it hits its resting place (post scroll). Similar to this website - http://99u.com/. Once you scroll past the image header, the logo fade's in to the nav bar and then stays on the page. Anyhow, here is the excerpt of the jquery code:
<script>
$(window).load(function() {
$('nav').sticky({ topSpacing:0, className: 'sticky', wrapperClassName: 'my-wrapper' });
});
</script>
And here is the excerpt of the html:
<div with image slideshow></div>
<nav>
<div class="container">
<div class="thirteen columns">
<ul id="nav" class="links">
<li id="sticker"><img src="[image i want to display after scroll]" /></li>
<li>About</li>
<li>Contests</li>
<li>etc.</li>
</ul>
</div>
</div>
</nav>
<div's and the rest of the page's content></div>
This whole template is responsive. Any help would be appreciated, or if someone can point me in the right direction. Thanks!
Take a look at scrollTop and offset.
This is untested but it would look something like this:
$(window).scroll(function(){
if($("#nav").offset().top <= $(window).scrollTop)
$("#nav").css({"position":"fixed","top":"0px", "left":"0px"});
else
$("#nav").css({"position":"relative"});
});
Basically, as the user scrolls, check the windows scroll position and if it passes the top of the nav, switch the nav over to fixed positioning. In my code above, the check on the way back may need a little tweaking but when they scroll to a position less than the height of the nav, put the nav back to relative positioning.
Also instead of switching to position fixed you could show/hide a totally separate nav, might actually make life easier.
-Ken
You can test the position property of the menu and when it changes, hide/show the image via adding/removing a class:
CSS:
#sticker.hidden { width:0; height:0; border:0; padding:0; margin:0; }
#sticker.hidden * { display:none; }
Javascript:
$(window).load(function () {
$('nav').sticky({
topSpacing: 0,
className: 'sticky',
wrapperClassName: 'my-wrapper'
});
var elem = $('#sticker');
var nav = $('nav');
var pos = nav.css('position');
$(window).scroll(function(){
if (nav.css('position')!=pos) { // if changed
if (pos=='fixed') {
elem.addClass('hidden');
} else {
elem.removeClass('hidden');
}
pos = nav.css('position');
}
});
});
jsfiddle
Thanks for the suggestions. They both helped! Here is what i ended up doing:
<script>
$(window).load(function() {
$('#sticker').css({'display':'none'});
$('nav').sticky({ topSpacing:0, className: 'sticky', wrapperClassName: 'my-wrapper' });
$(this).scroll(function() {
if($('nav').offset().top <= $(window).scrollTop()) {
$('#sticker').fadeIn('fast');
} else {
$('#sticker').css({'display':'none'});
}
});
});
</script>
I have a problem showing and hidden a text box.
You can see it working at: http://jsfiddle.net/CVPSg/
Problem:
I want to click <li>About</li>
and show the <aside id="aboutBox"> coming from the left part of the screen (display: none)
Then, I want to close <aside id="aboutBox"> with <h2>Close X</h2>
Also, The <aside id="aboutBox"> does not hidden and/or does not move to the left once again to display none.
It keeps moving to the right of the screen.
I hope it makes sense.
And I have added the code here as well:
HTML
<ul class="extras">
<li>About</li>
<!-- <li>Blog</li> For the future -->
<li class="hidesearch showsearch">
<form action="http://www.racamstudio.com/searchSubmit" method="post" name="seachform">
<input type="text" id="searchInputRight" value="Search..." in-focus="false" name="searchText">
<input width="16" height="16" type="image" id="searchbuttonRight" alt="Submit" name="submit" src="http://www.racamstudio.com/resources/images/search_icon_over.gif">
</form>
</li>
</ul><!-- end extras-->
<aside id="aboutBox">
<h1>Welcome</h1>
<p>One morning, when Gregor Samsa woke from troubled dreams, he found himself transformed in his bed into a horrible vermin. He lay on his armour-like back, and if he lifted his head a little he could see his brown belly, slightly domed and divided by arches into stiff sections.</p>
<p>One morning, when Gregor Samsa woke from troubled dreams, he found himself transformed in his bed into a horrible vermin. He lay on his armour-like back, and if he lifted his head a little he could see his brown belly, slightly domed and divided by arches into stiff sections.</p>
<p>One morning, when Gregor Samsa woke from troubled dreams, he found himself transformed in his bed into a horrible vermin. He lay on his armour-like back, and if he lifted his head a little he could see his brown belly, slightly domed and divided by arches into stiff sections.</p>
<h2>Close X</h2>
</aside><!-- end aboutbox -->
Javascript
$(function() {
// slideshow
var currentPosition = 0;
var slideWidth = 340;
var slides = $('#aboutBox');
var numberOfSlides = 2; // slides.length: show all images
// Remove scrollbar in JS - It is added in CSS for user how does not have js enable
$('#aboutBox').css('overflow', 'hidden');
// Wrap all .slides with #slideInner div
// variable slides = #aboutBox
slides.wrapAll('<div id="wrapAbout"></div>').css({
'display': 'none'
});
$('#wrapAbout').css('width', '340px');
// Create event listeners for .controls clicks
$('.extras li a').bind('click', function() {
// Determine new position
currentPosition = ($(this).attr('id') == 'left') ? currentPosition + 1 : currentPosition - 1;
// Hide / show controls
manageControls(currentPosition);
// Move slideInner using margin-left
$('#aboutBox').animate({
'marginLeft': slideWidth * (-currentPosition),
'display': 'block'
});
});
// manageControls: Hides and shows controls depending on currentPosition
function manageControls(position) {
// Hide left arrow if position is first slide
if (position == 0) {
$('#aboutBox').hide()
} else {
$('#aboutBox').show()
}
}
});
You don't want overflow:hidden on the slide-out, you want that on the wrapper. You don't want to animate the margin-left or display, you want to animate the wrapper's width. There's no need to absolutely position your slide-out either. Also, you can simplify things by handling the show and hide actions in separate handlers:
var slideWidth = 340;
var slides = $('#aboutBox').css('width', slideWidth);
slides.css({
width: slideWidth,
height: slides.attr('scrollHeight')
});
var wrapper = slides.wrap('<div>').parent().css({
width: 1,
height: slides.height(),
overflow: 'hidden',
display: 'none'
});
$('#show').click(function() {
if(wrapper.is(':visible'))
return;
wrapper.show().animate({
width: '+=' + slideWidth
}, 'slow');
});
$('#hide').click(function() {
wrapper.animate({
width: 1
}, 'slow', function() {
wrapper.hide();
});
});
I tweaked the HTML and CSS a bit too: I added id attributes to the show and hide links and dropped all the positioning for #aboutBox: http://jsfiddle.net/ambiguous/mp7aR/