Jquery navigation menu - javascript

The above code does not work properly. I need to implement a simple menu with sub-menu items using Jquery. When I open the web-page, I see the content of all menus and submenus all together (like a stack). I need to improve JavaScript shown below in order to properly assign the content to menu items. So, when I click "menu2",there should be the content of DIV id = "menu2". Now I see all content on one page.
<!-- Start css3menu.com BODY section -->
<ul id="css3menu1">
<li class="topfirst"><a class="pressed" href="#menu1" style="height:40px;line-height:40px;"><span>menu1</span></a>
<ul class = "menu">
<li>submenu11</li>
<li>submenu12</li>
<li>submenu13</li>
<li>submenu14</li>
</ul></li>
<li class="menu">menu2</li>
<li class="menu">menu3</li>
<li class="toplast">menu4</li>
</ul>
<!-- End css3menu.com BODY section -->
<script>
$('ul.menu').each(function() {
var $active, $content, $links = $(this).find('a');
$active = $links.first().addClass('active');
$content = $($active.attr('href'));
$links.not(':first').each(function() {
$($(this).attr('href')).hide();
});
$(this).on('click', 'a', function(e) {
$active.removeClass('active');
$content.hide();
$active = $(this);
$content = $($(this).attr('href'));
$active.addClass('active');
$content.show();
e.preventDefault();
});
});
</script>

This line has an issue
$content = $($active.attr('href'));
There is no item with that ID... ($content is length 0)
e.g.
you press a link with href="#menu1"
$active.attr('href') equals to #menu1
which translates to $content = $("#menu1");
there is no element on the page with ID "menu1"
In jQuery a selector with a hash (#) means - find an element with the id after the hash sign
So #menu1 means the same (almost) as document.getElementById("menu1")
However there is no element with that ID (or any id that is equal to the href values)
It might not be the last issue, but this is the next stop in the attempt to make it work...
See in jsFiddle

Related

Make current div change relevant menu tab to active

In my mobile project I can press a menu tab (Tab2) and the tab becomes active (with background color for the active class) and the corresponding div (Div2) below will appear on the screen.
If I press another tab, that tab gets active with corr. div etc...all in all, works perfect!
But now I have the opposite problem, I want to press (in my case, swipe) a div onto my screen and have the corresponding tab above to be active (with color). e.g. swipe in Div1 on screen, Tab1 should be active and have a certain background color. Swipe in Div2, then Tab2 should be active instead etc. but can't get it to work.
Below are my li tags:
<ul class="nav nav-pills mobileNavbar">
<li onclick="swipeFunction(0)" class="col-xs-4 tab1" data-index="0">STREAM</li>
<li onclick="swipeFunction(1)" class="col-xs-4 tab2" data-index="1">CHAT</li>
<li onclick="swipeFunction(2)" class="col-xs-4 tab3" data-index="2">IDE</li>
</ul>
And my jQuery:
$('#carousel-example-generic').on('slid.bs.carousel', function() {
var savedIndex = $(this).find('.active').index();
if (savedIndex === 0){
// I want Tab1 to be active here
} else if (savedIndex == 1){
// I want Tab2 to be active here
} else if (savedIndex == 2){
// I want Tab3 to be active here
}
});
For more details into what I'm trying to build, incl. libs, images (and my previous problem, solved by "Pieter"):
Link to a section on horizontal web page
As I commented above, you are doing same thing in all the conditions. All you need to do is, to activate the navigation item by index you are getting from carousel. Try this:
$('#carousel-example-generic').on('slid.bs.carousel', function () {
var savedIndex = $(this).find('.active').index();
$('.nav-pills>li:eq(' + savedIndex + ')>a').css('background', 'yellow');
});
EDIT:
I would recommend to play with a CSS class instead of inline css. Try this:
$('#carousel-example-generic').on('slid.bs.carousel', function () {
var savedIndex = $(this).find('.active').index();
$('.nav-pills>li:eq(' + savedIndex + ')>a')
.addClass("active") // add active class to the current one
.parent().siblings() // select sibling navigation items
.removeClass("active"); // remove active class from the other navigations
});
You conveniently already have classnames "tab1", "tab2", "tab3" on the tabs, which can be matched easily based on savedIndex:
$('#carousel-example-generic').on('slid.bs.carousel', function() {
$('.nav li').removeClass('active'); // clear the old one
var savedIndex = $(this).find('.active').index();
$('.tab'+ (savedIndex+1)).addClass('active'); // add the new one
});
(I believe index() returns an integer, but if not you may need to parseInt it before adding 1.)

Add active class to parent nav when on child pages

I need to highlight the parent nav item when a user is within a child page based on the URL.
User is currently on the page foo1-child and the parent is foo1 so I need to add the active class to Foo 1: http://foo.com/foo1/foo1-child.html
NAV:
<ul class="main-nav">
<li>Foo 1</li>
<li>Foo 5</li>
</ul>
I have no issue adding an active class to links within the nav as I just compare every the href in the .nav li a vs the URL but how can I check the URL for a matching anchor link name in the URL or something similar?
Current JS
$('.main-nav li > a').each(function () {
var $this = $(this);
if ($this.attr('href').indexOf(location.pathname) !== -1) {
$this.addClass('active');
}
});
If you cut off the ".html" from the end of both of them and you search for the a's href (which should be shorter) in the location, it should work.
$('.main-nav li > a').each(function () {
var $this = $(this);
var loc = location.
if (location.pathname.replace(/\/[^\/]*\.html$/, '').startsWith($this.attr('href').replace(/\.html$/, ''))) {
$this.parent().addClass('active');
}
});
You can see it in "action" here: https://jsfiddle.net/c8u2f91v/ Note it uses a fake location_pathname instead of location.pathname, because jsfiddle doesn't have the necessary prefixes in the path, but it shows that it should work.

Unable to detect what div is clicked

I want every li tag to show the a's clicked href content below that li tag in a div. For example, I have a structure like this:
<ul id="ids">
<li class="res"><a class="item">item1</a></li>
<li class="res"><a class="item">item2</a></li>
<li class="res"><a class="item">item3</a></li>
</ul>
Dynamically if a's href is clicked, accordingly a function that shows the div <div class="testing"><h3>showing item1 here</h3></div> outside the <a> tag needs to be shown. That function could take time so until then Loading... needs to be shown. But I am unable to detect where the user has clicked as class names are the same. Once loading is done, loading should be hidden.
So far I have this:
$(document).on('click', '.item', function(e) {
e.preventDefault();
$(this).append('Loading');
//function code here
$(this).append('<div class="testing"><h3>showing item1 here</h3></div>');
});
Also, the function appends 1 div tag with class 'mydiv', that needs to be hidden. But again, since class names that get appended to every <li> is the same, I don't know where the click has taken place to detect it.
to summarise:
show a list of elements which has anchor tag
click on every element should show the content of the click in a div under that anchor tag
content of anchor tag can take 2 seconds so until then user should see "loading". Once it loads, loading should be hidden
You are looking for $.after() or $.insertAfter():
$(document).on('click', '.item', function(e) {
e.preventDefault();
var aTag = $(this);
if (aTag.siblings('.testing, .loader').length === 0) { //it's not loaded or loading
var loader = $('<div class="loader">Loading</div>');
loader.insertAfter(aTag);
//function code here
loader.remove();
aTag.after('<div class="testing"><h3>showing ' + aTag.html() + ' here</h3></div>');
}
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<ul id="ids">
<li class="res"><a class="item">item1</a>
</li>
<li class="res"><a class="item">item2</a>
</li>
<li class="res"><a class="item">item3</a>
</li>
</ul>
If you want to avoid multiple loadings check if it exists before:
if(aTag.siblings('.testing, .loader').length === 0){ //it's not loaded or loading
}
You can get the href attribute using `$(this). This should work.
$(document).on('click', '.item', function(e) {
e.preventDefault();
var href = $(this).attr("href");
$(this).append('Loading');
$(this).append('<div class="testing"><h3>showing ' + href + ' here</h3></div>');
});
Also, the code above will append the div inside the a tag. You probably want to put it somewhere else using something like
$("#messageDiv").html('<div class="testing"><h3>showing ' + href + ' here</h3></div>');
To hide the loading message, you can wrap that in a span
$(this).append('<span class="loadingspan">Loading</span>');
Then in the code that runs when the load is complete, you can use
$('.loadingspan').hide();

active class on menu and parent item

i have this HTML code for my menu:
<nav id="main-navigation" class="navigation-simple">
<ul>
<li>Home</li>
<li><a class="active-nav" href="">About Us</a>
<ul>
<li><a class="active-nav" href="about">About</a></li>
<li>Testimonials</li>
<li>Meet The Team</li>
</ul>
</li>
</nav>
i have added in the active-nav class but how can i automatically set the active class on parent and child items when the current URL is the href value of the link?
you need java script for this, jQuery is great for beginners!
It could be done like this:
var url = window.location.href;
$( "nav li a" ).each(function(index) {
if (url.indexOf($(this).attr('href')) >= 0){
$(this).addClass('active-nav');
}
});
line by line -
get the current page url
for each link in the navigation...
check if its href is in the current url
if it is, add the class 'active-nav'
close if statement
close for loop
You can use the .filter() method to find the appropriate link and add the required class:
$('#main-navigation li > a').removeClass('active-nav')
.filter(function() {
return location.href.indexOf(this.href) > -1;
})
.addClass('active-nav') //add class to matched element(s)
//add class to parent(s) of matched, if any
.each(function() {
$($(this).parents('a'), '#main-navigation').addClass('active-nav');
});
Also remember to close your first ul.
Something like:
$(function() {
$('#main-navigation a').each(function() {
if(this.href.indexOf(window.location.pathname) === 0) {
$(this).addClass('active-nav');
} else {
// case when something was set to active by the server
$(this).removeClass('active-nav');
}
});
});
will do the job.
Make sure you make the if condition safe to your sites deeplinking implementation (e.g. GET params, anchors or multiple domains with same pathname are possible within your navigation).

dynamically apply active class to nav li

I have included a header to my files as in include. In the header is the nav bar.
How do I, using jQuery, apply class="active" to the relevant li.
The only way I could think of doing it is to set a variable on the actual pages, apply an id that is equal to that variable of the relevant page and if function so if they match apply a class to the li.
However, I thought there must be a simpler way of achieving this.
<ul class="nav nav-pills right" id="div">
<li id="home" class="active">
Home
</li>
<li id="search">
Search
</li>
<li id="contact">
Contact
</li>
</ul>
An easy way to do this would be to have a script per page:
$('#home').addClass('active'); // for home page
You could try and match the href to the current url:
var path = window.location.pathname.substring(1);
$('.nav>li>a[href="' + path + '"]').parent().addClass('active');
More compact way:
$(function(){
var sPath = window.location.pathname;
var sPage = sPath.substring(sPath.lastIndexOf('/') + 1);
$('a[href="'+ sPage +'"]').parent().addClass('active');
});
As soon as the page loads it will run this code:
$(document).ready(function(){
$('li').removeClass('active');
$('li a').each(function() {
$found = $.contains($(this).prop("href"),location.pathname);
if ($found) {
$(this).closest('li').addClass('active');
break;
}
});
});
OR
You can also do this using regex :
$(document).ready(function(){
$('li').removeClass('active');
var regex = /[a-z]+.php/g;
var input = location.pathname;
if(regex.test(input)) {
var matches = input.match(regex);
$('a[href="'+matches[0]+'"]').closest('li').addClass('active');
}
});
You might need to have the similar id name to that of php file.
Check the demo here : Demo
You can do this:
//remove the active class from all items, if there is any
$('.nav>li').removeClass('active');
//finally, add the active class to the current item
$('a[href='+ location.pathname.substring(1) +']').parent().addClass('active');
You could use javascript to find the current list item based on the url, by adding the class to the right list item after the DOM has been loaded (e.g. string manipulation of window.location together with JQuery selectors and addClass())
I found a routine to set active (current) class on my shared menu, but I need to modify it to set the parent link only, and not the 'closest' link. It works great on menu items with no sub menus, but when a sub menu item is clicked, there is not indication on the main menu after page load. (the code I need to modify is below)
(function( $ ) {
$.fn.activeNavigation = function(selector) {
var pathname = window.location.pathname
var extension_position;
var href;
var hrefs = []
$(selector).find("a").each(function(){
// Remove href file extension
extension_position = $(this).attr("href").lastIndexOf('.');
href = (extension_position >= 0) ? $(this).attr("href").substr(0, extension_position) :
$(this).attr("href");
if (pathname.indexOf(href) > -1) {
hrefs.push($(this));
}
})
if (hrefs.length) {
hrefs.sort(function(a,b){
return b.attr("href").length - a.attr("href").length
})
hrefs[0].closest('li').addClass("current")
}
}; })(jQuery);
If someone still checks on google how to do it here is my solution
var path = window.location.href; // full url
$('a[href="'+ path +'"]').parent().addClass('active'); // find by selector url
HTML
<ul class="navbar-nav mr-auto">
<li class="nav-item">
<a class="nav-link" href="http://example.com/">Home</a>
</li>
<li class="nav-item">
<a class="nav-link" href="http://example.com/history"> History</a>
</li>
</ul>

Categories