Links of nav bar don't go to the area id - javascript

After applying styles of Codrops in nav bar, I cannot make links go to the area id in a single page.
If I press "Clients" (for example), the link does not go to the id Clients area.
I need help in identifying the source of the problem.
Here is my HTML:
<nav class="menu menu--ferdinand">
<ul class="menu__list">
<li class="menu__item">
<a class="menu__link" href="#Services">Services</a>
</li>
<li class="menu__item">
<a class="menu__link" href="#Clients">Clients</a>
</li>
<li class="menu__item">
<a class="menu__link" href="#Us">About Us</a>
</li>
<li class="menu__item menu__item--current">
<a class="menu__link" href="#Contact">Contact</a>
</li>
</ul>
</nav>
script on the bottom of my index.html (I have classie.js, clipboard.min.js on js folder)
<script src="js/classie.js"></script>
<script src="js/clipboard.min.js"></script>
<script>
(function() {
[].slice.call(document.querySelectorAll('.menu')).forEach(function(menu) {
var menuItems = menu.querySelectorAll('.menu__link'),
setCurrent = function(ev) {
ev.preventDefault();
var item = ev.target.parentNode; // li
// return if already current
if (classie.has(item, 'menu__item--current')) {
return false;
}
// remove current
classie.remove(menu.querySelector('.menu__item--current'), 'menu__item--current');
// set current
classie.add(item, 'menu__item--current');
};
[].slice.call(menuItems).forEach(function(el) {
el.addEventListener('click', setCurrent);
});
});
[].slice.call(document.querySelectorAll('.link-copy')).forEach(function(link) {
link.setAttribute('data-clipboard-text', location.protocol + '//' + location.host + location.pathname + '#' + link.parentNode.id);
new Clipboard(link);
link.addEventListener('click', function() {
classie.add(link, 'link-copy--animate');
setTimeout(function() {
classie.remove(link, 'link-copy--animate');
}, 300);
});
});
})(window);
</script>
Areas (example):
<section id="Clients" class="Clients">
</section>
<section id="Services" class="Services">
</section>

ev.preventDefault() Prevents a link from doing it's default thing (i.e. follow the link to a new page or bookmark).

Related

Add Active Class to Menu

I have a side menu and I want to display the active class when it loads the page.
The obvious answer would be to do this with jquery in every page but it repeats tons of code and it's boring.
So I used this in a app.js globally:
//Active side-menu
$('.nav-item').click(function () {
$(this).addClass('active');
});
But this doesn't work because it puts active and when it loads the page this class is removed after loading the html
What can I do?
<ul class="nav">
<li class="nav-item">
<a class="nav-link" href="general-setup" onclick="gitLabFetch()" id="createEnviromentTab">
<img src="../resources/img/icons/create-icon.png" alt="" class="menuIcon">
<span class="menu-title">Create Environment</span>
</a>
</li>
//A lot of li elements
<ul>
I think that on page load, you should get the url, try to find it on the menu with javascript and then add the active class to the nav-item, something like this:
$(document).ready(function() {
var url = window.location.pathname + window.location.search;
$('ul.nav a.nav-link[href="' + url + '"]').parent().addClass('active');
});
A little example, you might need to tweak the url part:
$(document).ready(function() {
var url = 'general-setup';//window.location.pathname + window.location.search;
$('ul.nav a.nav-link[href="' + url + '"]').parent().addClass('active');
});
.active {
background: red;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<ul class="nav">
<li class="nav-item">
<a class="nav-link" href="general-setup" onclick="gitLabFetch()" id="createEnviromentTab">
<img src="../resources/img/icons/create-icon.png" alt="" class="menuIcon">
<span class="menu-title">Create Environment</span>
</a>
</li>
<li class="nav-item">
<a class="nav-link" href="general-setup2" onclick="gitLabFetch()" id="createEnviromentTab">
<img src="../resources/img/icons/create-icon.png" alt="" class="menuIcon">
<span class="menu-title">Create Environment</span>
</a>
</li>
//A lot of li elements
<ul>
Ok, so after further thought i have come up with a solution.
An approach i would take is to add a data attribute to anchor onto, this gives you the freedom to define routes that your list items link to and style them accordingly based on route...
(() => {
$('li')
.filter((i, li) => $(li).data('route') === window.location.pathname)
.addClass('active')
})()
<li data-route="/">HOME</li>
<li data-route="/friends">Friends</li>
<li data-route="/profile">Profile</li>
<li data-route="/blog">Blog</li>
As you can see, i run over all the list-items and filter out all the items that do not have data-route attributes that match the window.location.pathname, after i am left with the filtered list, i apply an active class to the matched items.

Ajax success callback unexpected behaviour

I have a href link for my unordered list.
When the page loads for the first time, only the welcome page is visible as expected.
When I click on the list for the first time after the page loads, I get the desired results on the desired div after clicking on the href link on the ul li.
However, if I subsequently click on the other tab, the results are displayed on the one I had clicked before. For example, if i click on href #tab2a, the results will be displayed on #tab2b and vice versa. AJAX will direct results to the div I clicked on previously.
I'm at a loss here! How can I force the results to be displayed in the div that's referenced by the href id tag? I'm using an if else if condition; is this the right approach?
JS
$(document).ready(function() {
$("#tab2").hide();
$("#tab3").hide();
$("#tab6").hide();
$("#tab2a").hide();
$("#tab2b").hide();
$('ul li a').click(function() {
href = undefined;
if (($(this).attr('href')) == "#tab2a") {
var href = $(this).attr('href');
$.ajax({
url: "http://mypage1_action=execute"
}).done(function(data) {
$(href).html(data);
});
$(href).show();
$('form#tab div:not(' + href + ')').hide();
} else if (($(this).attr('href')) == "#tab2b") {
var href = $(this).attr('href');
$.ajax({
url: "http://mypage1_action=execute"
}).done(function(data) {
$(href).html(data);
});
$(href).show();
$('form#tab div:not(' + href + ')').hide();
} else {
$(href).show();
$('form#tab div:not(' + href + ')').hide();
};
});
HTML
<form id="cssmenu">
<ul>
<li class='active'><a href='#tab1'><span>Home</span></a>
</li>
<li class='has-sub'><a href='#tab2'><span>Tab2</span></a>
<ul>
<li><a href='#tab2a'><span>Tab 2a</span></a>
</li>
<li><a href='#tab2b'><span>Tab 2b</span></a>
</li>
<li class='last'><a href='#tab2c'><span>Tab 2c</span></a>
</li>
</ul>
</li>
<li class='has-sub'><a href='#tab3'><span>Tab 3</span></a>
<ul>
<li><a href='#'><span>Tab 3a</span></a>
</li>
<li><a href='#'><span>Tab 3b</span></a>
</li>
<li class='last'><a href='#'><span>Tab 3c</span></a>
</li>
</ul>
</li>
<li class='has-sub'><a href='#tab4'><span>Tab 4</span></a>
<ul>
<li><a href='#'><span>Company</span></a>
</li>
<li class='last'><a href='#tab5'><span>Contact</span></a>
</li>
</ul>
</li>
<li class='last'><a href='#tab6'><span>Contact</span></a>
</li>
</ul>
</form>
<form id="tab" class=".allclass">
<div id="tab1" class='active'>
<h1>Welcome Page</h1>
</div>
<div id="tab2">
</div>
<div id="tab2a">
</div>
<div id="tab2b">
</div>
<div id="tab3">
</div>
<div id="tab6">
</div>
</form>
Here is the fiddle: https://jsfiddle.net/kBoni/1ag0ymh/#&togetherjs=m9pPoV3yoy
This is probably caused because by the time the .done() executes, the value of the href variable may have changed because you've clicked another tab, a simple way to avoid that is to wrap the ajax() code into a new function, and pass the href value as a parameter
function changeTab(href) {
$.ajax({
url: "http://mypage1_action=execute"
}).done(function(data) {
$(href).html(data);
});
$(href).show();
$('form#tab div:not(' + href + ')').hide();
}
$(document).ready(function() {
$("#tab2,#tab3,#tab6,#tab2a,#tab2b").hide();
$('ul li a').click(function() {
href = undefined;
if (($(this).attr('href')) == "#tab2a") {
var href = $(this).attr('href');
changeTab(href);
} else if (($(this).attr('href')) == "#tab2b") {
var href = $(this).attr('href');
changeTab(href);
} else {
$(href).show();
$('form#tab div:not(' + href + ')').hide();
};
});
});
Now, if you also want to have a different url for every tab, (which you probably do), you can add it as a data-attribute to your a and pass it to the function:
function changeTab(href,url) {
$.ajax({
url: url
}).done(function(data) {
$(href).html(data);
});
$(href).show();
$('form#tab div:not(' + href + ')').hide();
}
.
.
.
if (($(this).attr('href')) == "#tab2a") {
var href = $(this).attr('href');
var url = $(this).attr('data-url');
changeTab(href,url);
}

Add/Remove class based on active URL

My HTML code looks like this:
<div id="sidebar-menu" class="main_menu_side hidden-print main_menu">
<div class="menu_section">
<ul class="nav side-menu">
<li>
<a>
<i class="fa fa-home"></i>home
<span class="fa fa-chevron-down"></span>
</a>
<ul class="nav child_menu" style="display: none">
<li>
Dashboard
</li>
<li>
dashbord2
</li>
</ul>
</li>
<li>
<a>
<i class="fa fa-edit"></i>form
<span class="fa fa-chevron-down"></span>
</a>
<ul class="nav child_menu" style="display: none">
<li>
general form
</li>
<li>
form validation
</li>
</ul>
</li>
</ul>
</div>
</div>
to add/remove class based on current url, i am using this:
$(function () {
var url = window.location.href;
$('#sidebar-menu a[href="' + url + '"]').parent('li').addClass('current-page');
$('#sidebar-menu a').filter(function () {
return this.href == url;
}).parent('li').addClass('current-page').parent('ul').slideDown().parent().addClass('active');
});
It works, but when i click this link
dashbord2
the class="current-page" doesn't change to current path url
How i fix this?
Your issue arises from the page not being reloaded when you click on the link with hash in it, while your code only executes on page load, or dom ready to be exact. The solution is to whether use window's hashchange event (not supported in < IE8) or, like #sirrocco mentioned, use click event with setTimeout to detect the change of hash:
function setCurrentMenuPage() {
var url = window.location.href;
var anchors = $('#sidebar-menu a');
anchors.parent('li').removeClass('current-page');
anchors.filter(function () {
return this.href == url;
}).parent('li').addClass('current-page').parent('ul').slideDown().parent().addClass('active');
}
$(function () {
setCurrentMenuPage();
$('#sidebar-menu a').on('click', function (e) {
if ($(this).attr('href').indexOf("#") >= 0) {
setTimeout(function () {
setCurrentMenuPage();
}, 100);
}
});
});
Hope that helps.

Highlight Parent Menu when on child page also

I have a simple multilevel menu and a script which works to highlight the menu item irrespective of being parent menu or child menu.
In below example when I am on child page then it will only change the colour of child page, while I also want to change the colour or it parent item.
I tried few thing but it is not working as intended.
Here's a codepen of what I have so far.
In case that doesn't work, here's a code snippet:
jQuery(document).ready(function() {
var url = window.location.href;
$('#cssmenu a[href="' + url + '"]').addClass('active-menu');
// Will also work for relative and absolute hrefs
$('#cssmenu a').filter(function() {
return this.href == url;
$(this).parents("li a").addClass('active-menu');
}).addClass('active-menu');
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div id="cssmenu">
<div id="menu-button"></div>
<ul>
<li>About Us
</li>
<li class="has-sub">
<span class="submenu-button"></span>Gallery
<ul>
<li>Photo Gallery
</li>
<li>Video Gallery
</li>
<li>Instagram Gallery
</li>
</ul>
</li>
<li>News
</li>
<li>Contact
</li>
</ul>
</div>
UPDATE
Here's my new code, but this works but keeps keeps other links highlighted as well:
$('#cssmenu a').filter(function() {
$(this).parents("li.has-sub").find('a:first').addClass('active-menu');
return this.href == url;
}).addClass('active-menu');
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div id="cssmenu">
<div id="menu-button"></div>
<ul>
<li>About Us
</li>
<li class="has-sub">
<span class="submenu-button"></span>Gallery
<ul>
<li>Photo Gallery
</li>
<li>Video Gallery
</li>
<li>Instagram Gallery
</li>
</ul>
</li>
<li>News
</li>
<li>Contact
</li>
</ul>
</div>
I guess, this is what you were after.
var $menu = $("#cssmenu");
//Get the anchor based on the page URL
var $current = $menu.find('a').filter(function() {
return location.href.indexOf(this.href) > -1;
//Or (whatever works)
//return location.href === this.href;
});
//Add it's parent's anchor
$current = $current.add($current.closest("li.has-sub").find(' > a'));
//Set the desired class
$current.addClass('active-menu');
Here is a demo along the same lines.

Jquery disrupting the links in my main navigation

I have added a space on my site that dynamically loads pages using jquery. To do this it attaches a hash onto the url of the page it is on i.e. -
example.co.uk/html/print.html#../php/letterheads.php
which loads the information for each section. Subsequently when i the go to use my main navigation it changes the url to -
example.co.uk/html/print.html#furniture.html
instead of -
example.co.uk/html/furniture.html.
Here is my html :
<div id="section" style="margin-bottom:40px;">
<article>
<br/>
</article>
<div id="page-wrap" style="margin-top:0px;">
<header>
<nav id="printProducts">
<ul>
<li>Business Cards</li>
<li>Letterheads</li>
<li>Leaflets</li>
<li>Promo-Gifts</li>
<li>Banners</li>
<li>Posters</li>
<li>A Boards</li>
<li>NCR</li>
<li>Compliments Slip</li>
<li>Order of Service</li>
<li>Canvas</li>
<li>Sublimation</li>
</ul>
</nav>
</header>
<section id="main-content">
<div id="guts">
<h3 style="font-family:'kreon-bold-webfont';line-height:25px;font-weight:200;text-align:center">Click a tab for more information on the many different types of print we do in-house here at Cawthornes!</h3>
</div>
</section>
</div>
</div>
here is myjquery that deals with this :
$(function() {
var newHash = "",
$mainContent = $("#main-content"),
$pageWrap = $("#page-wrap"),
baseHeight = 0,
$el;
$pageWrap.height($pageWrap.height());
baseHeight = $pageWrap.height() - $mainContent.height();
$("nav").delegate("a", "click", function() {
window.location.hash = $(this).attr("href");
return false;
});
$(window).bind('hashchange', function(){
newHash = window.location.hash.substring(1);
if (newHash) {
$mainContent
.find("#guts")
.fadeOut(200, function() {
$mainContent.hide().load(newHash + " #guts", function() {
$mainContent.fadeIn(200, function() {
$pageWrap.animate({
height: baseHeight + $mainContent.height() + "px"
});
});
$("nav a").removeClass("current");
$("nav a[href="+newHash+"]").addClass("current");
});
});
};
});
$(window).trigger('hashchange');
});
Here is my main nav HTML
<nav id ="main">
<ul>
<li><a href="http://example.co.uk" alt="home"/>Home</a></li>
<li><a href="print.html" alt="Print"/>Print</a></li>
<li><a href="stationery.html" alt="Stationery"/>Office Supplies</a></li>
<li><a href="furniture.html" alt="Furniture"/>Furniture</a></li>
<li><a href="design.html" alt="Design"/>Design</a></li>
<li><a href="webDesign.html" alt="Web Design"/>Web Design</a></li>
<li><a href="ourStore.html" alt="Our Store"/>Retail Store</a></li>
<li><a href="http://82.163.59.97/" alt="Online Store"/>Online Store</a></li>
<li><a href="workwear.html" alt="Workwear"/>Workwear</a></li>
<li><a href="http://example.promoideas.info/" alt="Promotional Goods"/>Promo Goods</a></li>
</ul>
</nav>
Is there any way of rectifying this so that my main navigation will work as i want it to?

Categories

Resources