How to make links selected when scrolling? - javascript

I am having a trouble on adding a jquery code to a landing page so that when I scroll down among the sections the relevant sections should be shown in the navbar links by adding a class named clicked. I have added the code snippet that I am currently working on for your reference.. :-)
Any help would be gladly appreciated. :-)
$(document).ready(function(){
$(".link").click(function(event){
------ Scroll code ------------
$(".clicked").removeClass("clicked");
$(event.target).addClass("clicked");
});
});

You don't need to add an onClick event handler for that. The approach you should be using is not that difficult.
First you need to know your current scrolling position, which you can retrieve using:
$(document).scrollTop();
Then you need to know the position of bottom of the visible portion, which is actually the scrolling position + the height of the window:
var btm = $(this).scrollTop() + $(window).height();
Now we need to check if the section is above the bottom portion (that means it's visible), so in order to do that we need to get the position of the section. You can do that by using:
var titlePos = $($(myLink).attr("href")).offset().top;
What happens here is that we're going to look for the section that is referred to by the navbar link and then get it's offset (that's the position of where it's located on the document). You get both the left and top offset, but in this case we only need to get the top offset.
The only thing you need to do know is automate this for all links in your navigation, you can do that for example by doing:
$(".nav li a").each(function() {
var titlePos = $($(this).attr("href")).offset().top;
});
The next step is that we're going to look if the position of the title is above the bottom of the screen, that means that that section is/was visible. You can do that by using:
var btm = $(this).scrollTop() + $(window).height();
$(".nav li a").each(function() {
var titlePos = $($(this).attr("href")).offset().top;
if (titlePos < btm) {
$(this).addClass("visited");
}
});
Now there is only one problem. Sections that are above the screen (= sections you already passed/read) are also above the bottom of the screen, which means that with this code they will be active as well.
To fix that, we need to remove the .visited class from the previous link the moment we know that the next section is visible. You can do that by using:
$(this).parents("li").prev().children("a").removeClass("visited");
This goes to the link just before the link that's active and remove the .visited class from it, so actually only the last visible section is marked as visible.
Now you just add all of this to a scroll event handler and trigger it once to initialize the navigation. The code would become something like:
$(this).scroll(function() {
var btm = $(this).scrollTop() + $(window).height();
$(".nav li a").removeClass("visited").each(function() {
var titlePos = $($(this).attr("href")).offset().top;
if (titlePos < btm) {
$(this).addClass("visited");
$(this).parents("li").prev().children("a")
.removeClass("visited");
}
});
}).trigger("scroll");
Also notice the small change, when I scroll, I first remove the .visited class from all navigation links. I also made a JSFiddle demonstrating this.

Related

fixed header not getting right classes on scroll after closing fixed sidebar

I have a fixed sidebar and a fixed header with scrollable content in the main section of the page. The header is to be triggered on the scroll to hide the top portion of itself on scroll down and then show itself on scroll up. The sidebar can be triggered to hide and show itself with a button. When this happens the header gains back the full width of the page until the button is pressed to bring back the sidebar. The page loads with the sidebar opened.
So far I've been able to get the sidebar to transition off and back on the page properly. I also have the header working as intended on page load. However the issue I'm having is with the transition, more so recognizing the changed classes when the sidebar closes. I believe my issue is with the scroll javascript not recognizing the sidebar is closed because when scrolling it applies the classes to the header for when the sidebar is open. To test this I added a class called SEEME123 which never shows.
Below is the javascript for scrolling changes.
var exploreOpen = $('#explore').hasClass('open');
var exploreClosed = $('#explore').hasClass('closed');
$(function () {
var position = $(window).scrollTop();
if (exploreOpen) {
$(window).scroll(function () {
var scroll = $(window).scrollTop();
if (scroll > position) {
$('#wrapper-site-header').removeClass('explore-open--header-full');
$('#wrapper-site-header').addClass('explore-open--header-reduced');
} else {
$('#wrapper-site-header').addClass('explore-open--header-full');
$('#wrapper-site-header').removeClass('explore-open--header-reduced');
}
position = scroll;
});
} if (exploreClosed) {
$(window).scroll(function () {
var scroll = $(window).scrollTop();
if (scroll > position) {
$('#wrapper-site-header').removeClass('explore-closed--header-full');
$('#wrapper-site-header').addClass('explore-closed--header-reduced');
$('#wrapper-site-header').addClass('SEEME123');
} else {
$('#wrapper-site-header').addClass('explore-closed--header-full');
$('#wrapper-site-header').removeClass('explore-closed--header-reduced');
}
position = scroll;
});
} else {}
});
The javascript for the sidebar function toggles the open and closed classes on the sidebar, along with removing or adding the appropriate header class.
I don't understand why this isn't working as intended and would like to know how to resolve the issue. I've searched around attempting to understand where I screwed up, or to find an example where the scroll function does X because of Y. I've also attempted the above without variables (ie..
$(function () {
var position = $(window).scrollTop();
if (('#explore').hasClass('open')) {
), and as separate functions.
Anyway, here is a jsfiddle in case I missed something. https://jsfiddle.net/at0yxo0m/
Thank you all for your help and advice.
EDIT: Additional information.
I do have an earlier version of this layout where the scroll function only changes the header area that works with closing the sidebar. However the animations were clunky in general, and worse on mobile. Also to get everything to work right I had to wrap elements more than I thought was needed. So it was my goal to streamline as much as I could while getting the desired result.

Automatically Highlight Navigation Links on Horizontal Free Scrolling Website

I have a particular page with a set of images contained in a white-space:nowrap div, so the page scrolls horizontally. There's a fixed (main) navigation menu on the left.
I have a second navigation set, underneath the images, which when you click on the various links uses scrollTo to scroll the browser to the relevant image. This second navigation menu is contained in a fixed div and made up of a series of links to the various anchors associated with the images.
I would like a way of attaching and removing an active class to these links (i.e. addClass() ) depending on where the browser window is (and what is in view).
I have found lots of vertical versions of this, but my JS knowledge isn't fantastic and I haven't been able to successfully convert these to be used horizontally.
Essentially what I would like is a horizontal version of this JSFiddle.
I have come across this plugin, but haven't managed to get this to work for me either:
here
Thank you!
this your fiddle horizontal:
http://jsfiddle.net/x3V6Y/
I made a little change on HTML, and here is the JS:
$(function(){
var sections = {},
_width = $(window).width(),
i = 0;
// Grab positions of our sections
$('.section').each(function(){
sections[this.name] = $(this).offset().left;
});
$(document).scroll(function(){
var $this = $(this),
pos = $this.scrollLeft();
for(i in sections){
if(sections[i] >= pos && sections[i] <= pos + _width){
$('a').removeClass('active');
$('#nav_' + i).addClass('active');
}
}
});
});

Jquery Sticky Nav Issue

I'm been trying to get my head around issue and seem to cant find some help.
http://fiddle.jshell.net/DQgkE/7/show/
The experience is a bit jumpy and buggy now- but what i will like is
1) When you scroll down the page. I want the Sticky Nav to be (disable,dropped off, stop) at a specific location(chapter-3) on the page and the user should have the ability to keep scrolling down.
2) When the user is scrolling back up, the code will stick the nav back and carry it up until the nav reaches the original position at the top.
Below is a starting point.
3) Currently is kinda of doing that but there's some huge jump going on when scrolling back up
http://imakewebthings.com/jquery-waypoints/#doc-disable
using disable, destroy, enable option will be nice.
This is a original experience cleaned: http://fiddle.jshell.net/DQgkE/1/show/
Thanks for the help in Advance.
I'm not sure how this plugin you used work, but I have a solution I wrote a while back that I wrote in jquery. It has few variables at the top, the item you wanted sticky, the item where you want it to stop, and the class to add when it becomes sticky and padding at the top and bottom. I only modified the javascript portion in this fork.
EDIT
I went ahead and fixed the original code. Solution without waypoint plugin is in comments.
Here is the result:
http://fiddle.jshell.net/Taks7/show/
I would recommend to use jQuery (that was a surprise, right?! :P)
$(document).ready(function() { //when document is ready
var topDist = $("nav").position(); //save the position of your navbar !Don't create that variable inside the scroll function!
$(document).scroll(function () { //every time users scrolls the page
var scroll = $(this).scrollTop(); //get the distance of the current scroll from the top of the window
if (scroll > topDist.top - *distance_nav_from_top*) { //user goes to the trigger position
$('nav').css({position:"fixed", width: "100%", top:"*distance_nav_from_top*"}); //set the effect
} else { //window is on top position, reaches trigger position from bottom-to-top scrolling
$('nav').css({position:"static", width:"initial", top:"initial"}); //set them with the values you used before scrolling
}
});
});
I really hope I helped!

So DOM scrollIntoView aligns top/bottom, but what about left/right?

I would like to scroll horizontally the given element. The only way I find is using ScrollIntoView DOM method, which allows either align the element's bottom with the view bottom or the top - with the view top.
But what if the element is OK with respect to the Y axis, and I only want to scroll it horizontally? How can I align its left with the view left or its right with the view right?
EDIT
Here is more context. I have a YUI table with a horizontal scrollbar. I wish to scroll it programmatically to a certain TD node. I do not think window.scrollTo is of any help to me, since the scrollbar is on a div element, not on the whole page.
EDIT2
Turns out there is a duplicate SO question with the right answer - How can I scroll programmatically a div with its own scrollbars?
Voting to close mine.
I've recently had a problem with a table header that had inputs as filters for each column. Tabbing through the filters would move the focus, but if one of the inputs wasn't visible or if it was partly visible, it would only JUST bring the input into view, and I was asked to bring the full input and column into view. And then I was asked to do the same if tabbing backwards to the left.
This link helped to get me started: http://www.webdeveloper.com/forum/showthread.php?197612-scrollIntoView-horizontal
The short answer is that you want to use:
document.getElementById('myElement').scrollLeft = 50;
or:
$('#myElement')[0].scrollLeft = 50;
Here's my solution (which may be overkill for this question, but maybe it'll help someone):
// I used $.on() because the table was re-created every time the data was refreshed
// #tableWrapper is the div that limits the size of the viewable table
// don't ask me why I had to move the head head AND the body, they were in 2 different tables & divs, I didn't make the page
$('#someParentDiv').on('focus', '#tableWrapper input', function () {
var tableWidth = $('#tableWrapper')[0].offsetWidth;
var cellOffset = $(this).parent()[0].offsetLeft;
var cellWidth = $(this).parent()[0].offsetWidth;
var cellTotalOffset = cellOffset + cellWidth;
// if cell is cut off on the right
if (cellTotalOffset > tableWidth) {
var difference = cellTotalOffset - tableWidth;
$('#tableWrapper').find('.dataTables_scrollHead')[0].scrollLeft = difference;
$('#tableWrapper').find('.dataTables_scrollBody')[0].scrollLeft = difference;
}
// if cell is cut off on the left
else if ($('#tableWrapper').find('.dataTables_scrollHead')[0].scrollLeft > cellOffset) {
$('#tableWrapper').find('.dataTables_scrollHead')[0].scrollLeft = cellOffset;
$('#tableWrapper').find('.dataTables_scrollBody')[0].scrollLeft = cellOffset;
}
});
This is something I used a while back. There might be better and more efficient way of doing it but this gets the work done:
$(".item").click(function(event){
event.preventDefault();
// I broke it down into variable to make it easier to read
var tgt_full = this.href,
parts = tgt_full.split("#"),
tgt_clean = parts[1],
tgt_offset = $("#"+tgt_clean).offset(),
tgt_left = tgt_offset.left;
$('html, body').animate({scrollLeft:tgt_left}, 1000, "easeInOutExpo");
})
You just need to make sure that the item is an a tag with an href that corresponds to the target id element:
HTML:
go to section 1
...
<section id="one"> Section 1</section>
Hope this helps!

fixed div while scrolling which moves other elements in a menu

I have some menu items on the right hand side of my website that are: -
Basket Summary
Best Sellers
Quick Links
etc
I want the basket summary to follow down the page as the page is scrolled, I know how to this using position: fixed, but I need it to also move the other elements out of the way otherwise it will just overlap them.
I was looking at this: jsfiddle which would do the job and works but obviously thats only on button click, I would need to adapt this to scroll via jQuery.
I have read many tutorials for floated fixed divs but they are all for one div and don't have any other divs to interact with.
Any ideas if possible and/or how to do it?
Code from js fiddle as follows: -
$(function() {
$('.upButton').click(function(e){
var $parent = $('.highlight').closest('.box');
$parent.insertBefore($parent.prev());
});
$('.downButton').click(function(e){
var $parent = $('.highlight').closest('.box');
$parent.insertAfter($parent.next());
});
});
Is this what you're looking for?: http://jsfiddle.net/cmontgomery/YVh4q/
essentially, whenever the window scrolls check to see if your section is in the visible area and if not, adjust accordingly:
$(window).scroll(function () {
var mover = $("#sidebar .quick-links");
if($(window).scrollTop() === 0) {
//console.log("to top");
mover.prependTo("#sidebar");
} else if(!isFullyInViewableArea(mover)) {
var parent = mover.closest('.section');
if(isBelowViewableArea(mover)) {
//console.log("moving up");
parent.insertBefore(parent.prev());
} else {
//console.log("moving down");
parent.insertAfter(parent.next());
}
}
});
I must admit, this solution is not the best user experience, i.e. it jumps instead of scrolling smoothly. If it were me I would put the movable section as the last item in the right column and move that down the page with absolute positioning so it follows the top of the view-able area exactly.
Use this
Drag & Drop is best.
Greetings.

Categories

Resources