I have a static sidebar on scroll but when it reaches the footer it overlaps. Is there a way for me to stop this scrolling onto the footer? I understand this may be a simple concept but I have little experience working with the Scroll event in JQuery so any help would be fantastic.
Please find my code and a CodePen below.
<div id="main">
<div class="spacing">CONTENT HERE TO SHOW HOW THE SCROLL WILL WORK. PLEASE SCROLL DOWN</div>
<div class="container">
<div id="sidebar">
<div id="nav-anchor"></div>
<nav>
<ul>
<li>Blue</li>
<li>Green</li>
<li>Red</li>
<li>Yellow</li>
<li>Purple</li>
</ul>
</nav>
</div>
<!-- /sidebar -->
<div id="content">
<section id="blue">
...
</section>
<section id="green">
...
</section>
<section id="red">
...
</section>
<section id="yellow">
...
</section>
<section id="purple">
...
</section>
</div>
<!-- /#content -->
</div>
<!-- /.container -->
<footer>
<p>Footer here</p>
</footer>
</div>
<!-- /#main -->
$(document).ready(function(){
$(window).scroll(function(){
var window_top = $(window).scrollTop() + 12;
var div_top = $('#nav-anchor').offset().top;
if (window_top > div_top) {
$('nav').addClass('stick');
} else {
$('nav').removeClass('stick');
}
});
});
http://codepen.io/harryberry94/pen/MyOezg
If you want to hide the static element when it is overlapping the footer, add one more condition in your if condition after $('nav').addClass('stick'); :
var footer_top = $("footer").offset().top;
var static_div_bottom = $('nav').offset().top + $('nav').height();
$('#abc').text(footer_top +" " + static_div_bottom +" " + window_top);
if(static_div_bottom > footer_top){
$('nav').removeClass('stick');
}
You can use css for that if all you want is for your div not to overlap the footer, no need to use javascript and the scroll event. Just add z-index:-1; for nav.stick. Also if it needs a greater z-index to go over other elements in the page you can give the footer position:absolute; and a greater z-index (to keep content from going under the footer add padding-bottom to the body element).
Related
I'm trying expand one area based on the height of the other with jQuery. However, the first area has dynamic content, so I can't set a fixed value as I did in JS code (line 6, with 175px of height).
I have an example here: https://codepen.io/anon/pen/VyEZjv.
HTML
<div>
<div class="columns row-8">
<section id="summary" class="area">
<main>
<div id="details">
<div>bla bla</div>
<div>bla bla</div>
<div>bla bla</div>
</div>
<div id="more-details" class="hide">
<div>more bla bla</div>
<div>more bla bla</div>
<div>more bla bla</div>
</div>
</main>
<footer>
<button id="more-details-link">View more details</button>
</footer>
</section>
</div>
<div class="columns row-4">
<section id="activity" class="area">
<main>
<ul>
<li>activity</li>
<li>activity</li>
<li>activity</li>
<li>activity</li>
<li>activity</li>
<li>activity</li>
<li>activity</li>
<li>activity</li>
<li>activity</li>
<li>activity</li>
</ul>
</main>
<footer>
<a id="full-activity" href="#">See full activity</a>
</footer>
</section>
</div>
</div>
JS:
var minHeight = $('#summary > main').height();
$('#activity > main').height(minHeight);
$('#more-details-link').on('click', function(){
if ($('#more-details').is(':hidden')) {
$('#more-details').slideDown();
// I don't want to set a fixed value, because the first area content may vary
$('#activity > main').animate({height: '115px'});
} else {
$('#more-details').slideUp();
$('#activity > main').animate({height: minHeight});
}
});
So, the first area has two divs: one is always shown and the other one is hidden by default. When I click the expand button, this area will slide down to show the hidden div. I want the second area to expand as well, using the same slide effect, and keep the same height of the first area.
The only way I achieved it was sliding the second area after the first one, not along.
Thanks in advance.
(edit) To be more specific, I want the second area to be the same height as the first one. So, I if the first area is 100px height while collapsed, the second one will have 100px height too. If I expand the first area to 500px, the second one must have the same 500px.
I don't want to set a fixed height to the second area, like I did in the js code. I need to get the first area height and set the same value to the second one. I can't get the height of the first one right after the slideDown() because it's an async function and I'll get the wrong height.
PS: I'm limited to jQuery and CSS to this.
In order to be able to expand both sections simultaneously, you need to know the height the largest one occupies when expanded.
To make this happen, I use below probably the ugliest trick out there:
/* Show and hide '#more-details' instantly to find out the height it reaches. */
var maxHeight;
$('#more-details').show();
maxHeight = $('#summary > main').height();
$('#more-details').hide();
When you get this done, you now only have to substitute '115px' in your event listener with maxHeight:
$('#more-details').slideDown();
$('#activity> main').animate({height: maxHeight});
Check out the following snippet for more.
Snippet:
/* ----- JavaScript ----- */
var
/* Cache summary, activity and more-details. */
summary = $('#summary > main'),
activity = $('#activity > main'),
moreDetails = $('#more-details'),
/* Cache the height of the summary. */
minHeight = summary.height(),
maxHeight;
/* Set the activity to match the summary's height. */
activity.height(minHeight);
/* Show and hide '#more-details' instantly to find out the height it reaches. */
moreDetails.show();
maxHeight = summary.height();
moreDetails.hide();
/* Set the 'click' event of the link. */
$('#more-details-link').on('click', function(){
if (moreDetails.is(':hidden')) {
moreDetails.slideDown();
activity.animate({height: maxHeight});
} else {
moreDetails.slideUp();
activity.animate({height: minHeight});
}
});
/* ----- CSS ----- */
main {padding: 7px}
footer {border-top: 1px solid #000}
.columns {float: left;margin: 10px}
.row-8 {width: 200px}
.row-4 {width: 200px}
.area {background-color: #AAA}
.hide {display: none}
#activity>main {overflow: hidden}
<!----- HTML ----->
<script src="//cdnjs.cloudflare.com/ajax/libs/jquery/3.2.1/jquery.js"></script>
<div>
<div class="columns row-8">
<section id="summary" class="area">
<main>
<div id="details">
<div>bla bla</div>
<div>bla bla</div>
<div>bla bla</div>
</div>
<div id="more-details" class="hide">
<div>more bla bla</div>
<div>more bla bla</div>
<div>more bla bla</div>
</div>
</main>
<footer>
<button id="more-details-link">View more details</button>
</footer>
</section>
</div>
<div class="columns row-4">
<section id="activity" class="area">
<main>
<ul>
<li>activity</li>
<li>activity</li>
<li>activity</li>
<li>activity</li>
<li>activity</li>
<li>activity</li>
<li>activity</li>
<li>activity</li>
<li>activity</li>
<li>activity</li>
</ul>
</main>
<footer>
<a id="full-activity" href="#">See full activity</a>
</footer>
</section>
</div>
</div>
I'm not sure I understand your question well
If you want to expand the two sections at the same time, what about a multiple selector
$('#full-activity, #activity > main')
in
$('#more-details-link').on('click', function(){
...
$('#full-activity, #activity > main').animate({height: '115px'});
...
$('#full-activity, #activity > main').animate({height: minHeight});
I've been trying to get the automatic update on my navbar but i cant get it to work.
Here is my code: http://pastebin.com/YTHaBD0i
<div id="header">
<ul class="nav-list">
<li class="download selected">Download</li>
<li class="features">Features</li>
<li class="method">Method</li>
<li class="purchase">Purchase</li>
</ul>
</div>
<div id="footer">yey productions © 2016</div>
<div id="fullpage">
<div class="section " id="section0">
<div class="intro">
<h1>Download</h1>
<p>Lorem Ipsum</p>
</div>
</div>
<div class="section" id="section1">
<div class="slide" id="slide1">
<div class="intro">
<h1>Features</h1>
<p>Cheese.</p>
</div>
</div>
<div class="slide" id="slide2">
<h1>Cheese2</h1>
</div>
</div>
<div class="section" id="section2">
<div class="intro">
<h1>Yey</h1>
</div>
</div>
<div class="section" id="section3">
<div class="intro">
<h1>Yey2</h1>
</div>
</div>
</div>
Help would be much appreciated!
Greetz,
Assuming you are using jQuery, you will need a function that fires every time you scroll.
From there, you need to detect which elements are in view.
Once you know which elements are in view, clear any currently active elements with the .selected class, then choose which one you want to be .selected and add the .selected class.
Edit for more detail:
Below is a pure JavaScript solution, which I found here. This should be close to a drop-in solution!:
(function() {
'use strict';
var section = document.querySelectorAll(".section");
var sections = {};
var i = 0;
Array.prototype.forEach.call(section, function(e) {
sections[e.id] = e.offsetTop;
});
window.onscroll = function() {
var scrollPosition = document.documentElement.scrollTop || document.body.scrollTop;
for (i in sections) {
if (sections[i] <= scrollPosition) {
document.querySelector('.selected').setAttribute('class', ' ');
document.querySelector('a[href*=' + i + ']').setAttribute('class', 'selected');
}
}
};
})();
I need to have only one nav link in active state when a user goes through multiple sections of my website. How do I make the proper edits to this JS to make that happen?
For instance, if the default nav link id = #dinos_
I want all my sections that use section ids like #dinos_trex, #dinos_raptor, #dinos_triceratops to keep making the nav id that = #dinos_ to stay in the active state in the nav.
After further research, would someone be able to code something with 'classes'?
Lets say a set of divs share a certain class name, in this case "dinos_" how can I set an active state for just one nav item if the user is on 'any' of the related "dinos_" sections????
here is the current jquery Im using:
var sections = $('section'), nav = $('nav'), nav_height = nav.outerHeight();
$(window).on('scroll', function () {
var cur_pos = $(this).scrollTop();
sections.each(function() {
var top = $(this).offset().top - nav_height,
bottom = top + $(this).outerHeight();
if (cur_pos >= top && cur_pos <= bottom) {
nav.find('a').removeClass('active');
sections.removeClass('active');
$(this).addClass('active');
nav.find('a[href="#'+$(this).attr('id')+'"]').addClass('active');
}
});
});
Im guessing this snippet of code in particular is where I need someone to help me redefine?
nav.find('a[href="#'+$(this).attr('id')+'"]').addClass('active');
Here is my HTML
<header id="header">
<!-- Nav -->
<nav id="nav">
<ul>
<li>DINOS</li> /*multiple unique section ids that contain the word dinos_ in their id name should set this to 'active */
<li>ROBOTS</li> /*multiple unique section ids that contain the word robots_ in their id name should set this to 'active */
<li>UNDEAD</li> /*multiple unique section ids that contain the word undead_ in their id name should set this to 'active */
</ul>
</nav>
</header>
<section id="dinos_" class="main style2 right dark fullscreen">
<div class="content box style2">
<header>
<h2>DINOSAURS INTRO</h2>
</header>
<p>
Intro to the dinos</p>
</div>
up
down
</section>
<section id="dinos_trex" class="main style2 left dark fullscreen">
<div class="content box style2">
<header>
<h2>T-REX</h2>
</header>
<p>
Section for the T-rex</p>
</div>
up
down
</section>
<section id="dinos_raptor" class="main style2 left dark fullscreen">
<div class="content box style2">
<header>
<h2>THE RAPTOR</h2>
</header>
<p>
Section for the raptor/p>
</div>
up
down
</section>
<section id="robots_" class="main style2 left dark fullscreen">
<div class="content box style2">
<header>
<h2>ROBOTS INTRO</h2>
</header>
<p>
Section for the Robots Intro</p>
</div>
up
down
</section>
<section id="robots_gunner" class="main style2 left dark fullscreen">
<div class="content box style2">
<header>
<h2>THE ROBOT GUNNER</h2>
</header>
<p>
Section for the gunner</p>
</div>
up
down
</section>
Using the waypoints plugin:
http://imakewebthings.com/waypoints/
UPDATED
JS:
$('section').waypoint({
handler: function (direction) {
$(".active").removeClass("active");
$("nav a[href=\"#" +this.element.id + "\"").addClass("active");
}
});
HTML with some minor changes:
<header id="header">
<!-- Nav -->
<nav id="nav">
<ul>
<li>DINOS
</li>
<li>ROBOTS
</li>
<li>UNDEAD
</li>
</ul>
</nav>
</header>
<section id="dinosaurs" class="main style2 right dark fullscreen">
<div class="content box style2">
<header>
<h2>DINOSAURS INTRO</h2>
</header>
<p>Intro to the dinos</p>
</div> up
down
</section>
<section id="dinosaurs_trex" class="main style2 left dark fullscreen">
<div class="content box style2">
<header>
<h2>TREX</h2>
</header>
<p>Section for the Trex</p>
</div> up
down
</section>
<section id="dinosaurs_raptor" class="main style2 left dark fullscreen">
<div class="content box style2">
<header>
<h2>THE RAPTOR</h2>
</header>
<p>Section for the Trex</p>
</div> up
down
</section>
Here's a fiddle:
http://jsfiddle.net/4qwawrgx/
change your this code
nav.find('a[href="#'+$(this).attr('id')+'"]').addClass('active');
to this
function activateNav() {
var hashValue = window.location.hash.substr(1);
$('body').find('a[href="#'+ hashValue +'"]').addClass('active');
}
$( document ).ready(function() {
activateNav();
$('a').on('click', function() {
activateNav();
});
});
Having this div's:
<div id="siteContainer">
<div id="Shadow">
<div id="Border">
<div id="Display">
<div id="NBar"></div>
<!-- End NBar -->
<div id="Screen"></div>
<!-- End Tablet Screen -->
<div id="MenuBar"></div>
<!-- End Menu Bar -->
</div>
<!-- End Display -->
</div>
<!-- End Border -->
</div>
<!-- End Shadow -->
</div>
#MenuBar is set with position fixed on the bottom of the screen (bottom: 0px) and what I want is to set position absolute when it reaches the bottom of div #Display so it doesn't go further downward.
I managed to make it work as I wanted with this code:
$(window).scroll(function (event) {
if ($(this).scrollTop() >= $("#MenuBar").height().valueOf() * 2) {
$("#MenuBar").addClass("fixedMenu");
} else {
$("#MenuBar").removeClass("fixedMenu");
}
});
I want to know if there might be a better way to do it.
I am using the following script to show a different background depending on the state of the div.
When it is not expanded it shows the "plus (+)" sign, while when is expanded it does not have background image (does not shows anything).
The problem there is that only work once, and I dont know why.
Here's the code:
EDIT (added HTML)!
HTML:
<body>
<section>
<div class="wrapper wf">
<ul id="Parks" class="just">
<!--------------- PRODUCT -->
<li class="mix" href="#therapy_vital" >
<div class="meta name">
<div class="img_wrapper">
<img src="images/spa/masaje/.jpg" onload="imgLoaded(this)"/>
</div>
<div class="titles">
<h2>TITLE</h2>
</div>
</div>
<!-- Expand -->
<div href="#therapy_vital" class="nav-toggle"></div>
<div id="therapy_vital" style="display:none">
<article class="ac-small">
SUBCONTENT<br><br><br><br><br><br><br><br><br><br><br><br>
</article>
</div>
</li>
<!--------------- PRODUCT -->
<li class="mix" href="#therapy_natur" >
<div class="meta name">
<div class="img_wrapper">
<img src="images/spa/masaje/.jpg" onload="imgLoaded(this)"/>
</div>
<div class="titles">
<h2>TITLE</h2>
</div>
</div>
<!-- Expand -->
<div href="#therapy_natur" class="nav-toggle"></div>
<div id="therapy_natur" style="display:none">
<article class="ac-small">
SUBCONTENT<br><br><br><br><br><br><br><br><br><br><br><br>
</article>
</div>
</li>
</ul>
</div>
</section>
</body>
JS:
$(document).ready(function() {
$('.meta').click(function() {
$(this).css('background', 'none');
});
$('.mix').click(function() {
var collapse_content_selector = $(this).attr('href');
var toggle = $(this);
$('.meta').click(function() {
$(this).css('background', 'url(images/arrow_down.png) no-repeat scroll 95% 97% transparent');
});
$(collapse_content_selector).toggle(function() {});
});
});
(The .mix value makes the Div expands, and the .meta class switch to different background).
Any clue?
EDIT2 (Live example)
http://anubisfiles.com/test/test.html
(Due I am not really familiar with jsFiddle, I prefer to show you it hosted on a website).
Thanks!
Use on function to bind events,
$('element').on('click', function() {
});
$('.mix').click(function() {
var collapse_content_selector = $(this).attr('href');
var toggle = $(this);
$(this).find('.meta').css('background', 'url(images/arrow_down.png) no-repeat scroll 95% 97% transparent');
$(collapse_content_selector).toggle(function() {});
});
Try this