jquery addClass/removeClass to navigation links based on div position - javascript

I am trying to add a class to links in the navigation by detecting a div with a specific id, each div is on a different page and located at the top.
If I use this for each individual instance, changing out divs and classes respectively
$(document).on("scroll ready", function() {
if ($(this).scrollTop()>=$('#contact').position().top){
$("#nav .contact a").addClass("ur-here");
}
});
the code works, unless I use that code repeatedly like this
$(document).on("scroll ready", function() {
if ($(this).scrollTop()>=$('#contact').position().top){
$("#nav .contact a").addClass("ur-here");
}
});
$(document).on("scroll ready", function() {
if ($(this).scrollTop()>=$('#blog').position().top){
$("#nav .blog a").addClass("ur-here");
}
});
at which point only the first instance works (by first instance I mean it doesn't matter which part I put first, the rest seems to be ignored).
.
I have also tried including them all into one function
$(document).on("scroll ready", function() {
if ($(this).scrollTop()>=$('#intro').position().top){
$("#nav .home a").addClass("ur-here");
}
else if ($(this).scrollTop()>=$('#services').position().top){
$("#nav .service a").addClass("ur-here");
}
else if ($(this).scrollTop()>=$('#contact').position().top){
$("#nav .contact a").addClass("ur-here");
}
else if ($(this).scrollTop()>=$('#blog').position().top){
$("#nav .blog a").addClass("ur-here");
}
});
But yet again only the first instance works.
I've also tried switching out
$(document).on("scroll ready", function() {
with
$(document).ready(function() {
and
$(window).load(function() {
with similar results, except if I use
$(window).load(function() {
in the second instance the code works for it and the first, but continues to ignore the rest after it no matter what I use.
help please
edited
its a wordpress site if that helps
solved
I just targeted the individual "#"s with
if ($("#mydiv").length > 0){
If the targeted div exists and has a length greater than 0, I can make the nav links do stuff.

If your goal is to make sure that as you scroll either direction, you show the ur-here class on the bottommost element that the user has scrolled the top of the window into, then: Live Example
$(document).on("scroll ready", function() {
// Remember scrollTop
var scrollTop = $(this).scrollTop();
// Remove the class from all relevant elements
$("#nav a").removeClass("ur-here");
// Working from the BOTTOM up, add it to the first matching element
if (scrollTop >=$('#blog').position().top) {
$("#nav .blog a").toggleClass("ur-here");
}
else if (scrollTop >=$('#contact').position().top) {
$("#nav .contact a").addClass("ur-here");
}
else {
// ...and so on
}
});

Related

Onepage navigation script needs to troggle / close on click on link

I have an onepage site with a responsive navigation script. Works great.
When you click on the Navigation button the "subnav" links show up. (These are anchors).
I need to toggle/close the subnav when clicking on a link/anchor.
Made an example here:
https://jsfiddle.net/fourroses666/jcj0kph2/
The script:
$(document).ready(function(){
$('nav').prepend('<div class="responsive-nav" style="display:none">Navigation</div>');
$('.responsive-nav').on('click',function(){
$('nav ul').slideToggle()
});
$(window).resize(function(){
if ($(window).innerWidth() < 768) {
$('nav ul li').css('display','block');
$('nav ul').hide()
$('.responsive-nav').show()
} else {
$('nav ul li').css('display','inline-block');
$('nav ul').show()
$('.responsive-nav').hide()
}
});
$(window).resize();
});
You may tidy up your code a bit by doing the prepend and attaching the click handler all in one statement as below.
var $nav = $('#nav').
prepend('<div class="responsive-nav" style="display:none">Navigation</div>').
on('click', '.responsive-nav, ul a', function() {
$nav.find('ul').slideToggle()
});
Updated fiddle
Note: I used $nav.find('ul') to target the specific nav in question as opposed to other navs that may exist on the page.
Edit: To make it not disappear when on >= 768, replace $nav.find('ul').slideToggle() with the following.
if (evt.target.tagName === 'A' && $(window).innerWidth() >= 768) {
return;
}
$nav.find('ul').slideToggle()
Updated fiddle
I'm assuming you want the Nav to hide when you click on a link?
/* This executes when the nav or li (inside #nav) is pressed */
$('#nav').on('click', 'li, .responsive-nav', function(){
$('nav ul').slideToggle()
});
https://jsfiddle.net/jcj0kph2/1/

Show/Hide with plus minus

So I've got it to work that it shows/hides the UL's/LI's, but I'm not sure what I'm doing incorrectly where it's not swapping out the +/- signs?
Here's my JS:
$(".top ul li:not(:has(li.current))").find("ul").hide().end() // Hide all other ULs
.click(function (e) {
if (this == e.target) {
$(this).children('ul').slideToggle();
}
$(this).children("li.menu-item-has-children").text(this.toggle ? "-" : "+");
return false;
});
I have a class setup to append the li with a li:before that add the + sign before the li that has the nested ul's. But I'm not sure if I am going about it the right way to swap out the signs.
Here's the fiddle that I made:
http://jsfiddle.net/bc4mg13a/
There you go: http://jsfiddle.net/bc4mg13a/13/
$(".menu-item-has-children").on("click", function(e){
e.stopPropagation();
var clickedLi = $(this);
$("> ul", clickedLi).slideToggle();
clickedLi.toggleClass("current");
});
To start with, your first js line is a has so much redundant stuff.
$(".top ul li:not(:has(li.current))").find("ul").hide().end() // Hide all other ULs
.click
could be:
$(".top ul li:not(.current)").find("ul").hide().end() // Hide all other ULs
.click
On the other hand, i changed your code slightly, simplified your selectors. On each li click, i select direct ul children, and the i slidetoggle + toggle class the 'current' class.
i also switch the plus sign via the current class on css.
Your code feels incredibly verbose. Well, at least your js. Here's a fiddle of your code that I modified a little bit.
Instead of hiding all your menus with js immediately on pageload, I applied a CSS display: none; to the sub-menu class:
.sub-menu {
display: none;
}
The js is cleaned up a bit, and since the click handler is bound to .menu-item-has-children, You're really only clicking on that to reveal the contained UL.
Give it a look. Hope it helps :)
Simply add:
$(this).toggleClass('open');
To this:
if (this == e.target) {
$(this).children('ul').slideToggle();
$(this).toggleClass('open'); // <--
}
you can just add $(this).toggleClass('open'); before you return false but I would strongly look more into what your code is doing. I'm not so sure the line before is doing anything.
Fixed JS:
$(".top ul li:not(:has(li.current))").find("ul").hide().end() // Hide all other ULs
.click(function (e) {
if (this == e.target) {
$(this).children('ul').slideToggle();
$(this).toggleClass('open'); // added
}
return false;
});
Just added "$(this).toggleClass('open');" to use the class you specified in your CSS instead of trying to manipulate the text manually.
you can do it like this and add $(this).toggleClass('open');
http://jsfiddle.net/bc4mg13a/5/
For how you have it set up, I would try...
$(".top ul li:not(:has(li.current))").find("ul").hide().end() // Hide all other ULs
.click(function (e) {
if (this == e.target) {
$(this).toggleClass("open");
$(this).children('ul').slideToggle();
}
return false;
});
Additional:
For formatting, you might want to do something like:
.menu-item-has-children {
&:before {
content:"+ ";
color: $white;
width: 10px;
display:inline-block;
}
}
.open {
&:before {
content:"- ";
color: $white;
width: 10px;
display:inline-block;
}
}
You don't need to use text(this.toggle ? "-" : "+");
Inside the condition, just toggle the class .open that you have already defined in your SCSS/CSS.
Like so -
$(this).toggleClass('open');
JSFiddle

Responsive tabs to accordion issue

I'm in the process of modifying a responsive tabs to accordion, please see the jsfiddle
When the current 'active' tab is clicked it hides which I understand is what it is meant to do in the code, however I would like it if this does not happen and doesn't hide. Here is the current javascript:
$('#nav').children('li').first().children('a').addClass('active')
.next().addClass('is-open').show();
$('#nav').on('click', 'li > a', function() {
if (!$(this).hasClass('active')) {
$('#nav .is-open').removeClass('is-open').hide();
$(this).next().toggleClass('is-open').toggle();
$('#nav').find('.active').removeClass('active');
$(this).addClass('active');
} else {
$('#nav .is-open').removeClass('is-open').hide();
$(this).removeClass('active');
}
});
It's basically just applying classes dependent on what is clicked and what is currently active or not. I guess I need to change the logic of this?
If what I understood is correct that you want to stop hiding the active div when clicked again. Just remove the else part...
$('#nav').children('li').first().children('a').addClass('active')
.next().addClass('is-open').show();
$('#nav').on('click', 'li > a', function() {
if (!$(this).hasClass('active')) {
$('#nav .is-open').removeClass('is-open').hide();
$(this).next().toggleClass('is-open').toggle();
$('#nav').find('.active').removeClass('active');
$(this).addClass('active');
}
});
Check this Fiddle

Jquery toggle class on click, and remove class if another menu item clicked

My code is:
$(document).ready(function() {
$(".more").click(function(e) {
$(this).toggleClass("open");
if (!$(".more").hasClass(".icon-arrow-down")) {
// alert('Yep has class');
$(this).toggleClass("icon-arrow-down");
$(this).toggleClass('icon-arrow-up');
}
else {
// alert('all ok');
}
});
});
A little messy as i was testing some things out. Basically i have a menu, with a .more class added for dropdowns. People on mobile click the more, which adds a class of .open to the menu so people can see it. Now my problem is, this code doesn't seem to work 100% of the time.
Sometimes the classes get confused and i end up with a menu open, but a class of icon-arrow-down still.
And also, how would i add something in so that the open class gets removed if another more button is clicked?
Help appreciated as always.
In menus I always use something like this:
$(document).ready(function() {
$(".more").click(function(e) {
if($(this).hasClass("open")) {
// if it's open then just close it
$(this).removeClass("open");
} else {
// if it's closed, then close everything else and open it
$(".more").removeClass("open");
$(this).addClass("open");
}
/* TODO: now do something similar with icon-arrow */
});
});
Shouldn't you just be checking if the current element has the .icon-arrow-down class. So rather than
if (!$(".more").hasClass(".icon-arrow-down"))
this
if (!$(this).hasClass(".icon-arrow-down"))
Maybe consider using
$(".more").click(function(e) {
if( $(this).hasClass("open") ) {
$(this).removeClass("open").addClass("closed");
} else {
// if other menus are open remove open class and add closed
$(this).siblings().removeClass("open").addClass("closed");
$(this).removeClass("closed").addClass("open");
}
});
Then use the .open and .closed class to set your arrow styles
Fiddle here.
Simple but shows you what you can do.
You could remove the class .open from all and then add it to the clicked one:
$(document).ready(function() {
var $more = $(".more");
$more.click(function(e) {
var $this = $(this);
if ($this.hasClass("open") {
$more.removeClass("open");
} else {
$more.removeClass("open");
$this.addClass("open");
}
});
});

Changing js functionality of themeforest theme

I purchased a theme off of http://themeforest.net and now the them was taken off.
The original theme functionality was to have all of the links pages inside of their own divs in the index page however I changed the functionality so that each link is on its own controller since I am using Codeigniter.
What I want to happen is when a new link is clicked it still rolls up the content div and goes to the clicked link and then rolls down the content of that page. As of right now it rolls up ALL the way up the page and doesn't even load the new page. The commented section of code is what the original code was from the template.
/*****************************************************
MENU TRANSITION EFFECTS
******************************************************/
$("#menu1 ul li a").click(function(e){
e.preventDefault();
$('#container').animate({top:'-500px'},500,'easeInQuart');
/*
var id = $(this).attr("href");
if(id == aid) return false;
$('#menu1 ul li a').removeClass('a');
$(this).addClass('a');
if($("#container > div:visible").size() > 0) {
$("#container > div:visible").animate({top:'-500px'},500,'easeInQuart',function(){ $("#container > div:visible").css({display:'none',top:'-500px'}); $('#container > div#' + id).css({display:'block'}).delay(400).animate({top:'500px'},800,'easeOutQuart');
$(function() {
$('.scroll').jScrollPane();
});
});
} else {
$('#container > div#' + id).css({display:'block'}).animate({top:'500px'},200,'easeOutQuart');
}
aid = id;
return false;
*/
});
Edit: I tried it on my regular site and for some reason it wasn't working the same. Here's the template. I uploaded it to one of my other sites for display. Keep in mind the difference is that each link is a new controller and each div is a new view. Does that explain any further the differences between the original template and what I"m trying to accomplish.
http://www.justmyfiles.me/
Does anybody have any ideas?
The "transition" javascript code could look like :
$("#menu1 ul li a").click(function(e){
var a = this;
e.preventDefault();
$('#container').animate({top:'-500px'},500,'easeInQuart',function() {
location.href = a.href;
});
});
And the document ready code :
$(document).ready(function() {
$('#container').animate({top:'0px'},500,'easeInQuart');
});
/*CSS*/
#container { top: -500px; }

Categories