menu items getting highlight as I scroll to each section with deficiency - javascript

I just used this code to get my menu highlighted as I scroll down to each each section of my WordPress site:
(function($) {
$(document).ready(function(){
$("header nav ul").toggleClass("open");
$("section.container").addClass("section");
});
$(window).scroll(function() {
var position = $(this).scrollTop();
$('.section').each(function() {
var target = $(this).offset().top;
var id = $(this).attr('id');
if (position >= target) {
$('#primary-menu > li > a').removeClass('active');
$('#primary-menu > li > a[href=#' + id + ']').addClass('active');
}
});
});
}(jQuery));
css:
.active{
color: #fff !important;
}
Here is the link: http://scentology.burnnotice.co.za
Problem is that the last item(Contact) is not getting highlighted when I scroll all the way down up to contact section.
Also,if I click on a menu item,it goes to the respective section but that menu doesn't get highlighted unless I scroll the page a little bit down'.
How can I solve that?
Thanks in advance

NOTE: It seems that you took that code from my answer to this SO question, I have edited it to cover your case. Other people looking for more code can check it out for a snippet.
So, you have two problems:
The last item is not getting highlighted.
When clicking on a menu item, the page scrolls to the respective section but that menu doesn't get highlighted unless scrolling down the page a little bit.
Problem 1
This one is easy, you just forgot to add the id attribute to the last section :)
It should be:
<section id="contact" class="container contact-us section">
Problem 2
Your click event starts a scroll animation to the corresponding section but, since the navigation bar is on the top of the page, you made the animation to leave a little margin on the top. That margin prevents the section from reaching the top of the page, so the menu item doesn't get highlighted.
#Shnibble pointed you in the right direction, you can add a small positive margin to the value returned by $(window).scrollTop() (or a negative one to the offset().top of the element).
So, following the code you have included, it will be something like:
if (position + my_margin >= target) {
The margin could be the height of your navigation bar:
my_margin = $('#site-navigation').height();
You can, obviously, add a little more or less to tailor it to your needs.

There is a simple solution and it just requires a bit of additional math :)
You are measuring from the top of the (window) viewport and checking to see if it is greater than or equal to the top of a specified target div. Because your content sections are exactly 100% of the viewport, it is impossible for the top of the viewport ever be greater than or equal to the top of the last content div.
What you need to do is offset the point you are measuring from so that you are not measuring from the top of the viewport, but rather some ways down from the top, say halfway or 3/4 of the way down. This will solve both of your issues.
Edit: here is something to get you started, then play around with dividing the window height by 1/2 or something like that:
var position = $(this).scrollTop() + $(window).height;

Related

Modify Sidenavigation Which Highlights Which Part of Page is Viewed

I currently have a sidenavigation bar which continually checks the users scroll position and if it is greater than a specified .slide height, it adds a class .current to a certain div on a sidebar making it turn orange and thus indicates which part of a page the user is on. Right now, the code only works for one specific height of .slide but I would like to modify it so that each slide (i.e. slide red, slide green, slide blue which are the divs with the colored background) can be of different heights since my content for each section will vary in length.
The fiddle can be found here
JavaScript:
$(document).scroll(function() {
if($(window).scrollTop() > $('.slide').height()*$('.current').index()){
$('.current').removeClass('current');
var newSlide = Math.floor($(window).scrollTop() / $('.slide').height());
$('.sidenavigation li:eq('+newSlide+')').addClass('current');
}
if($(window).scrollTop() < $('.slide').height()*$('.current').index()){
$('.current').removeClass('current');
var newSlide = Math.floor($(window).scrollTop() / $('.slide').height());
$('.sidenavigation li:eq('-newSlide-')').addClass('current');
}
});
I was trying to help you with your code and then i realize how hard it is, so I know it is probably not what you really want, but I recommend you a great jQuery plugin, which will solve your problem very fast: http://imakewebthings.com/jquery-waypoints/

Jquery change div based on another div's position

Let me start of by saying, I'm just now learning JS and Jquery, so my knowledge is very limited.
I've been looking around for 2 days now, and tried all sorts of combinations. But I just can't get this to work.
Below is an example of the layout
I'm looking for a way to trigger an event when div 1 is X px from the top of the screen. Or when div 1 collides with div 2.
What I'm trying to accomplish is to change the css of div 2 (the fixed menu) when div 1 is (in this case) 100px from the top of screen (browser window). Alternatively, when div1 passes div2 (I'm using responsive design, so the fixed height from top might become a problem on smaller screens right? Seeing as the header for example won't be there on a hand held.). So maybe collision detection is better here? Would really appreciate some thoughts and input on this matter.
Another issue is, div2 has to revert back to is previous css once div1 passes it (going back (beyond the 100px)).
This is what I have but it has no effect
$(document).ready(function() {
var content = $('#div1');
var top = $('#div2');
$(window).on('scroll', function() {
if(content.offset().top <= 100) {
top.css({'opacity': 0.8});
}else{
top.css({'opacity': 1});
}
});
});
I am not sure of the reason but $("#content").offset().top was giving a constant value on console. So I added window.scrollTOp() to check its distance from top, here is how it works,
$(document).ready(function() {
var top = $("#menu");
$(window).on('scroll', function(){
if(($('#content').offset().top - $(window).scrollTop()) <= 100){
top.css({'opacity': 0.4});
}else{
top.css({'opacity': 1});
}
});
});
And DEMO JSFIDDLE....

Make a div appear when scrolling past a certain point of a page

My goal is to make a fixed div appear at the top of a page once someone scrolls a certain amount of pixels down the page. Basically once the header section is out of view, this div will appear.
I've looked at code similar to what I want; however, haven't seen anything that would allow me to easily modify the pixel count from the top of the page (if possible).
Here is a piece of code I saw dealing with making divs appear by scrolling.
// Get the headers position from the top of the page, plus its own height
var startY = $('header').position().top + $('header').outerHeight();
$(window).scroll(function(){
checkY();
});
function checkY(){
if( $(window).scrollTop() > startY ){
$('.fixedDiv').slideDown();
}else{
$('.fixedDiv').slideUp();
}
}
// Do this on load just in case the user starts half way down the page
checkY();
I just want to know how to make it appear. If someone knows of a piece of code already in tact with a slide up and slide down animation, that would be greatly appreciated as well but not required.
window.addEventListener("scroll",function() {
if(window.scrollY > 500) {
$('.fixedDiv').slideDown();
}
else {
$('.fixedDiv').slideUp();
}
},false);
Brandon Tilley answered my question in a comment...
You would change the first line, with the startY, to be the specific Y
position you need, rather than calculating based on the header's
position and height. Here's an updated fiddle:
jsfiddle.net/BinaryMuse/Ehney/1
window.addEventListener("scroll",function() {
$('.fixedDiv')[(window.scrollY > 500)?"slideDown":"slideUp"]();
},false);
DEMO: http://jsfiddle.net/DerekL/8eG2A/

Solving scrolling element inside below div (under screen) - I want to have it fixed after scrolling

I do not know how to solve this situation:
I`ve got the html/css looks like this:
Image showing how my css/html looks like and what is displayed on the screen after landing on page:
The when I scroll down I see green element:
scrolling down ->
After continuing to scrolling down I saw full green element and the if I scroll down I want to have this element like in css language: position fixed bottom 0. See image below:
I ve saw full element -> same link but image called problem3.png
and then I scroll below and I want to have it fixed at the bottom of the page, like on this image:
Fixed element on screen - What I want and I do not know how to do that -> same link but image called problem4.png (stupid spam prevention mechanism)
Is it possible to solve this situation ?
To sum up: I`ve got two divs, one above and second below, Wheen I scroll down I suddenly see another element (green div) and when i continue to scroll down I WANT TO HAVE THIS GREEN DIV FIXED AT THE BOTTOM OF THE PAGE.
Ofcourse, when I scroll up (back on the top) I want to "park" that green div at the top of the second div.
Is there any way to solve this situation with jQuery (Javascript) / html / css ?
Thank you in advance
I think you'll have to show some of your html structure. There are lots of ways to achieve this kind of effect. Fundamentally, in javascript terms you'll be looking to:
Add an event listener to the window scroll that checks whether the green element is fully in view
If it is in view, add a class (or change it's css) that fixes it's position where you want
Change your window scroll method so that it's checking the relative offset of the red div to the top of the screen. If it goes below the position where the green div should be fixed, remove the class you added earlier.
That sounds complicated, but it's not too bad. The javascript would be something like:
$(function() {
$(window).scroll(function() {
if($(".divToFix").hasClass("fixedAtBase")){
if(Utils.underView($(".redDiv"), $(".divToFix").height())) $(".divToFix").removeClass("fixedAtBase");
} else {
if(Utils.inView($(".divToFix"))) $(".divToFix").addClass("fixedAtBase");
}
});
});
Utils = {
underView: function(element, offset) {
return (($(window).height() + $(window).scrollTop() - offset) <= element.offset().top);
},
aboveView: function(element) {
return ($(window).scrollTop() >= element.offset().top + element.height());
},
inView: function(element) {
return (Utils.aboveView(element) !== true && Utils.underView(element, element.height()) !== true);
}
};
Bear in mind I've not tested that or anything.
edit - here's a demo

How would I scroll horizontally to the next article in a page (or #, etc.)?

I'm trying to work with a jQuery script I found at http://marcgrabanski.com/articles/scrollto-next-article-button-jquery that allows me to set up "next" and "previous" buttons that scroll the user through a page from one article to the next (or previous). The idea is that the button would stay in a fixed position and clicking the button multiple times would keep the user scrolling on to the next article (or other element).
I have a page that scrolls horizontally, so I want to adapt the code so that instead of finding the top of each h2 in the container, it finds the left side of each h2 and scrolls the user horizontally and not vertically. Here is the code I'm using:
jQuery(function($){
$('<div id="next_arrow">Next</div>')
.prependTo("body") //append the Next arrow div to the bottom of the document
.click(function(){
scrollTop = $(window).scrollTop();
$('#container h2').each(function(i, h2){ // loop through article headings
h2top = $(h2).offset().top; // get article heading top
if (scrollTop<h2top) { // compare if document is below heading
$.scrollTo(h2, 800); // scroll to in .8 of a second
return false; // exit function
}
});
});
});
Any help is greatly appreciated in advance. Thank you.
jP
#paulGraffix, #ShankarSangoli, and #esses thank you for your responses.
As a follow-up to my last question, how would I go about limiting the scroll to scroll horizontally only?
If you click on the arrows at the top of http://174.121.134.126/~methfree/ the window will scroll vertically (as well as horizontally) if the browser window is small enough to scroll vertically. Is there any way to add a scroll-x (or something like that) to the script to limit the scroll to horizontal only?
Thanks,
jP
Basically you should just be able to switch out all the vertical references to horizontal ones and it should work. Try something like this:
jQuery(function($){
$('<div id="next_arrow">Next</div>')
.prependTo("body") //append the Next arrow div to the bottom of the document
.click(function(){
scrollLeft = $(window).scrollLeft();
$('#container h2').each(function(i, h2){ // loop through article headings
h2Left = $(h2).offset().left; // get article heading left
if (scrollLeft<h2Left) { // compare if document is left of heading
$.scrollTo(h2, 800); // scroll to in .8 of a second
return false; // exit function
}
});
});
});
you may be able to modify your code using offsetLeft (or offsetRight) instead of using (window).scrollTop.
this link may be helpful: http://unknownerror.net/2011-04/top-clienttop-scrolltop-offsettop-the-difference-between-memo-4017
Try this
jQuery(function($){
$('<div id="next_arrow">Next</div>') //item to be added
.prependTo("body") //append the Next arrow div to the bottom of the document
.click(function(){
scrollLeft = $(window).scrollLeft();
$('#container h2').each(function(i, h2){ // loop through article headings
h2left = $(h2).offset().left; // get article heading left
if (scrollLeft < h2Left) { // compare if document is below heading
$.scrollTo(h2, 800); // scroll to in .8 of a second
return false; // exit function
}
});
});
});

Categories