Add class to nav when scrolling to the anchor - javascript

This is dynamic. The nav changes based upon the page. The code here adds a class to the nav as you scroll to the section and then removes it as you scroll past. The problem is it only removes as you scroll down not up past the section. How do I do my condition to remove classes as you scroll up while achieving adding the class and removing it as you scroll down??
jQuery( document ).ready(function() {
var sectionelements = jQuery('.nav li');
(function(jQuery) {
var scrolling = function(){
jQuery(sectionelements).each(function(){
var object=jQuery('#'+this);
var wh = jQuery(window).height();
var st = jQuery(document).scrollTop();
var ot = jQuery(object).offset().top;
var eh = jQuery(object).height();
var href="a[href*=#"+object.attr('id')+"]";
if(st>ot){
jQuery(href).addClass('posreached');
}
if (st>ot+eh) {
jQuery(href).removeClass('posreached');
};
})
};
jQuery(window).scroll(scrolling);
jQuery(window).bind('resize orientationchange',scrolling);
//fire initial scroll
jQuery(window).scroll();
})(jQuery);
});

this:
if(st>ot){
jQuery(href).addClass('posreached');
}
if (st>ot+eh) {
jQuery(href).removeClass('posreached');
};
even in the second state the first will be true, so u need to add:
if(st>ot || st<ot+eh){
jQuery(href).addClass('posreached');
}
give it a try

I used these for my conditions and it worked
if(st>ot){
jQuery(href).addClass('posreached');
}
if (st<ot) {
jQuery(href).removeClass('posreached');
}
if (st>ot+eh) {
jQuery(href).removeClass('posreached');
}

Related

How do you script an addEventListener to toggle back a hamburger menu in javascript

Alright so I'm at the last phase of adding finishing touches to my website in order to publish it over the internet but I can't quite figure out how to add an eventListener that closes the navbar hamburger menu without having to manually scroll back up to the landing page to toggle it back. This is what I have so far.
//Select element function
const selectElement = function (element) {
return document.querySelector(element);
};
let menuToggler = selectElement('.menu-toggle');
let body = selectElement('body');
menuToggler.addEventListener('click', function () {
body.classList.toggle('open');
});
// Parallax scrolling effect
window.addEventListener('scroll', function () {
const parallax = document.querySelector('.parallax');
let scrollPosition = window.pageYOffset;
parallax.style.transform = 'translateY(' + scrollPosition * -.10 + 'px)';
});
Here's a ss of the HTML document with the nav tag for context; I'd appreciate a thorough explanation of what the js bit is doing as I'm fairly new to it. : ) Cheers!
Attached is a link to a video demonstrating how the hamburger menu responds
To close navbar when click a nav-link you can do this:
const menuToggler = document.querySelector('.menu-toggle');
const body = document.body;
const navItems = document.querySelectorAll(".nav-item");
Array.from(navItems).map(el => {
el.addEventListener('click', function () {
body.classList.remove('open');
});
});
menuToggler.addEventListener('click', function () {
body.classList.toggle('open');
});
// Parallax scrolling effect
window.addEventListener('scroll', function () {
const parallax = document.querySelector('.parallax');
let scrollPosition = window.pageYOffset;
parallax.style.transform = 'translateY(' + scrollPosition * -.10 + 'px)';
});
You want to add an event listener on the entire document, and check if the clicked element is your menu button, your nav element, or a child of your nav element. If it is not then remove the class.
document.addEventListener('click',(e)=>{
//the element clicked
let target = e.target;
//your nav element
let nav = document.querySelector('nav');
//if it's not the menu button, or nav, or a child of nav
if(target != menuToggler && target != nav && target.closest('nav') != nav){
body.classList.remove('open');
}
});
You could also use a key event like the user hitting ESC, in which you would just remove the class
document.addEventListener('keydown',(e)=>{
if(e.key=="Escape"){
body.classList.remove('open');
}
});
If you need to close it after a link in your nav has been clicked then add the remove code to your existing link listeners or add a new one to your links (or a delegated listener on your nav) and remove it there
document.querySelector('nav').addEventListener('click',(e)=>{
if(e.target.classList.contains('nav-link')){
body.classList.remove('open');
}
});

Make first menu item red on load with scrollspy an jQuery

Can someone help me with my code? This code below makes my menu items red on scroll within the div where a "scrollspy" is added. But there is something missing so my first menu item (Home) does not get red when page is loaded, only when I scroll a bit below. I need to have this 1st item red on load. How can I fix this?
An example code to make first menu item active on load?
window.onload = function() {
//code?
};
This makes menu item red when added "scrollspy" class on a row in admin
var elems = $('.scrollspy');
$(window).bind('scroll', function() {
var currentActive = null;
var currentActiveDistance = -1;
var currentTop = $(window).scrollTop();
elems.each(function(index) {
var elemTop = $(this).offset().top - 102
var id = $(this).attr('id');
var navElem = $('.menu a[href="#' + id + '"]');
navElem.removeClass('active');
if (currentTop >= elemTop) {
var distance = currentTop - elemTop;
if (currentActiveDistance > distance || currentActiveDistance == -1) {
currentActive = navElem;
}
}
});
if (currentActive) {
currentActive.addClass('active');
}
});
Why not use just CSS?
.nav li a.active {
background-color: red;
}
jQuery can be used as below to make first menu item link RED i.e by applying class active.
$(document).ready(function(){
$(".menu:first a").addClass('active');
});
Please post your HTML markup if it does not work with your HTML.

Opacity change icons on scrolls

new user here.
I'm having an issue with a javascript command I've written in my html.
So my page is set up in 3 sections. The sections are represented by 3 icons on a fixed nav bar. What I'm trying to do is have the other two icons opacity decrease depending on what section you scroll to.
I wrote an if-else statement to get it to work and it does for the first section, but when I write a new if-else statement for the next section the next opacity change isn't recognized.
My code:
$(document).ready(function() {
var nav = $(".work1");
var banner = $("#LogoBio");
var pos = nav.position();
var icon1 = $("#Graphics");
var icon2 = $("#Animations");
var icon3 = $("#HandArt");
var section1 = $("#ill4");
var section2 = $("#aniDes");
$(window).scroll(function(){
var windowpos = $(window).scrollTop();
if (windowpos>=banner.outerHeight()){
nav.addClass('fixedTop');
}
else {
nav.removeClass('fixedTop');
}
$(".work1").wrapInner('<div class="nav-inner"</div>');
if (windowpos>=section1.outerHeight()){
icon2.addClass('opacityChange');
icon3.addClass('opacityChange');
}
else {
icon2.removeClass('opacityChange');
icon3.removeClass('opacityChange');
}
});
});
If-else statement for next section?
If anyone has any ideas on a solution I would so appreciate it. Thank you all for your help!
first add class attribute to your icon tags:
<.... id="Graphics" class='icon' ...>
<.... id="Animations" class='icon' ...>
<.... id="HandArt" class='icon' ...>
then, in code first add class to all .icon tags and after it remove that from unwanted ones:
$(".icon").addClass("opacityChange");
if (windowpos>=section3.outerHeight()) {
icon3.removeClass("opacityChange");
} else if (windowpos>=section2.outerHeight()) {
icon2.removeClass("opacityChange");
} else if (windowpos>=section1.outerHeight()) {
icon1.removeClass("opacityChange");
}

.show(): how to call .show() on a specific element

I fixed my code but I'm having glitchy behavior. Specifically, when the mouse is no longer on the 'td.component' the buttons should be hidden but upon moving the mouse really fast over the various 'td.component's, some of these elements still show the buttons. Any thoughts on how I could fix this?
Thanks.
Code below:
$(function() {
var $newButton = $('<button class = "new"><img class = icon src = "images/new.png" >new</img></button>');
var $deleteButton = $('<button class = "delete"><img class = icon src = "images/delete.png" >delete</img></button>');
var $saveButton = $('<button id = "save">Save</button>');
for (i = 42; i > 0; i--) {
$table.append('<tr><td class = "number">' + i +
'</td><td class = "component"></td></tr>');
}
//appends to all 'td.component'
$('td.component').append($newButton).append($deleteButton);
//hides all buttons
$('button.new').hide();
$('button.delete').hide();
$('td.component').mouseover(function(e) {
$(this).find('button.new').show();
$(this).find('button.delete').show();
});
$('td.component').mouseout(function(e) {
$(this).find('button.new').hide();
$(this).find('button.delete').hide();
});
$('button.new').mouseout(function(e) {
e.stopPropagation();
});
$('button.delete').mouseout(function(e) {
e.stopPropagation();
});
});
You can use find:
$('td.component').mouseover(function(e) {
$(this).find('button.new').show();
$(this).find('button.delete').show();
});
Here is a jsfiddle.
You'll probably want to hide the buttons once the mouse leaves.
As #elzi pointed out, if you just want to show/hide them on hover, you are best off using CSS hover:
td.component button {
display: none;
}
td.component:hover button {
display: inline;
}
(classes ignored for simplicity)
Updated jsfiddle.
You can use this to execute the set of functions on that element.
$('td.component').mouseover(function(e) {
$(this).find('button.new').show();
$(this).find('button.delete').show();
});
This would find the buttons inside that particular element.

Add new item to bottom of scrollabe div

I'm trying to append a div to the bottom of a another div, by clicking a button in javascript, but once the height of the outer container is reached, it no longer scrolls the list to the bottom, after an insert.
Please see the fiddle here
If you click the red add button until you get to about 13 items in the list, it seems something goes wrong with the scrollTop function, and it it no longer functions correctly (hovers around the same spot in).
I'm pretty lost on this, and have tried a bunch of different combinations of css settings for both the container and side div. Please help me.
I've reformatted your code to be more jQuery-esque. The main change, however, was to change the list.scrollTop() function so that it just scrolls to the bottom of list:
$(document).ready(function() {
var list = $("#q-d-list");
$(document).on('click', '#add', function() {
$('.active', list).removeClass("active");
var count = list.children().length + 1;
var active = $('<div />', {
'data-qid': count,
'class': 'mli active'
}).text('q' + count).appendTo(list);
list.scrollTop(list[0].scrollHeight);
});
});​
Demo: http://jsfiddle.net/MrvcB/19/
Use
list.scrollTop(list.get(0).scrollHeight);
rather than
list.scrollTop($(".active").offset().top);
Try:
$(document).ready(function () {
var count = 2;
$("#add").live("click", function () {
var list= $("#q-d-list");
// remove the active class from the old item
var $clone = $(list.find("div:last-child").removeClass("active").clone());
count+=1;
var str_count = "q"+count.toString();
$clone.addClass("active").attr("data-qid",str_count).text(str_count);
list.append($clone);
list.scrollTop(list.get(0).scrollHeight);
});
});
http://jsfiddle.net/H4Kb3/

Categories

Resources