Bootstrap4 scroll spy - active to parent li - javascript

I've got bootstrap4 menu like this:
<ul class="navbar-nav ml-auto">
<li class="nav-item"><a class="nav-link" href="#introduction">INTRODUKTION <span class="sr-only">(current)</span></a></li>
</ul>
Default scroll spy adds active to nav-link (a) I need to change this, becouse my active should be after nav-item (li). Can I do that ?
You can see this here:
Example
When I click, everything goes ok - but on scroll - active is a href.

By default .active class will be added to only anchor tags.
Try something like this for your requirement
$('[data-spy="scroll"]').on('activate.bs.scrollspy', function () {
$(".navbar-nav .active").removeClass("active").parent().addClass("active");
})
Add attribute data-spy="scroll"
on <div class="container"> the parent of section with id="introduction"
like
<div class="container" data-spy="scroll">

I found solution. I need just to add new event (cssClassChanged) - and working !
(function(){
// Your base, I'm in it!
var originalAddClassMethod = jQuery.fn.addClass;
jQuery.fn.addClass = function(){
// Execute the original method.
var result = originalAddClassMethod.apply( this, arguments );
// trigger a custom event
jQuery(this).trigger('cssClassChanged');
// return the original result
return result;
}
})();
and then
$(".nav-link").bind('cssClassChanged' , function(e) {
$(".nav-item").each( function() {
if( $(this).hasClass("active") == true ) {
$(this).removeClass("active");
}
});
$(this).removeClass("active").parent().addClass("active");
});

Related

Apply click event to element with class

I have a function where I have a list of links, where when the list link is clicked, it doesn't open a link until it's clicked again. Can someone please tell me how to get this working?
Here is the HTML:
<ul>
<li class = "submenu"> <a class="nav-link" href = "" > About </a> </li>
<li class = "submenu"> <a class="nav-link" href = "" > Gallery </a> </li>
<li class = "submenu"> <a class="nav-link" href = "" > Contact </a> </li>
</ul>
Here is the function:
(function() {
$('.nav-link').delegate("a", "click", function(e){
e.preventDefault();
});
})();
Here's a method using pure JS:
document.getElementsByClassName('nav-link').forEach(e => {
let wasClicked = false;
e.onclick = () => {
if (wasClicked) return true;
wasClicked = false;
// add a class to it
e.className += ' was-clicked-once';
return false; // reject the click
}
});
The delegate method is deprecated since jquery version: 3.0
Use the jquery on() method. it attaches an event handlers for the selected elements and child elements.
(function() {
$('.nav-link').on("click", function(e){
e.preventDefault();
});
})();

Hash check for URL constantly firing function

I have the following functions. When the a-link is clicked, it changes the url and adds a hash to it. I then run a check to see if there is a hash. I get the name after the text and load the relevant content.
My problem is that the changePage function fires constantly. Even if I add a flag check. See below -
var changeCheck = true;
$(document).ready(function(){
$('a.nav-link').on('click', function(e){
e.preventDefault( );
var pageRef = $(this).attr('href');
window.history.pushState('changeUrl', 'Title', '/DigiOutsourceTask/#' + pageRef);
changeCheck = true;
changePage(pageRef)
});
if(window.location.hash && changeCheck === true){
console.log('hash');
changePage(window.location.hash.slice(1));
}
});
function changePage(href){
$( "#home-body" ).load(href, function(){
console.log('changed');
});
changeCheck = false;
console.log(href,'click');
}
<div id="home-body"></div>
<ul class="main-menu-list">
<li>
<a class="nav-link" href="index.html">Home</a>
</li>
<li>
<a class="nav-link about" href="about.html">About</a>
</li>
</ul>
Try deleting the if statement along with everything inside of it since it is redundant to the functioning of the script.
On line 11 of the snippet the function call is missing a semi-colon to end the line.

Navigation menu dropdown top level doesn't work

I have a dropdown menu with top level and two sub levels. The thing is that the sub levels work just fine, I can click on them and it takes me to the page I selected. The problem is with the top level, when I hover over it it displays the submenus but when I click on it it doesn't take me to the page.
var menu_Sub = $(".menu-has-sub");
var menu_Sub_Li;
$(".mobile-device .menu-has-sub").find(".fa:first").removeClass("fa-angle-right").addClass("fa-angle-down");
menu_Sub.click(function() {
if ($(".header").hasClass("mobile-device")) {
menu_Sub_Li = $(this).parent("li:first");
if (menu_Sub_Li.hasClass("menu-opened")) {
menu_Sub_Li.find(".sub-dropdown:first").slideUp(function() {
menu_Sub_Li.removeClass("menu-opened");
menu_Sub_Li.find(".menu-has-sub").find(".fa:first").removeClass("fa-angle-up").addClass("fa-angle-down");
});
} else {
$(this).find(".fa:first").removeClass("fa-angle-down").addClass("fa-angle-up");
menu_Sub_Li.addClass("menu-opened");
menu_Sub_Li.find(".sub-dropdown:first").slideDown();
}
return false;
} else {
return false;
}
});
menu_Sub_Li = menu_Sub.parent("li");
menu_Sub_Li.hover(function() {
if (!($(".header").hasClass("mobile-device"))) {
$(this).find(".sub-dropdown:first").stop(true, true).fadeIn("fast");
}
}, function() {
if (!($(".header").hasClass("mobile-device"))) {
$(this).find(".sub-dropdown:first").stop(true, true).delay(100).fadeOut("fast");
}
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="nav-menu">
<ul class="nav-menu-inner">
<li>
Home
</li>
<li>
<a class="menu-has-sub" href="about-us">About us <i class="fa fa-angle-down"></i></a>
<!-- Dropdown -->
<ul class="sub-dropdown dropdown">
<li>
<a class="menu-has-sub" href="clients-case-studies">Clients and Case Studies</a>
</li>
</ul>
<!-- End Dropdown -->
Any help would be appreciated. Thank you.
The problem arises in your return false call at the end of your first if statement:
menu_Sub.click(function () {
if ($(".header").hasClass("mobile-device")) {
menu_Sub_Li = $(this).parent("li:first");
if (menu_Sub_Li.hasClass("menu-opened")) {
...
}
else {
return false; // this prevents the default click action from occuring
}
});
What you are saying here is basically, if I click on the .menu-has-sub link and it doesn't have a .mobile-device class, I want it to return false.
That essentially means event.preventDefault() - read this SO answer for a great explanation event.preventDefault() vs. return false
But that seems to be your problem, be careful when preventing the default action on links, if you want them to go somewhere.
Here is a fiddle with the line commented out.

Anchor tag is not working

I used different anchor tags on my list but it is not working due to the JavaScript file attach to that list. when I remove that JavaScript file it works but I have to included my JavaScript too. Is there a way to used that same JavaScript file with anchor tag working?
function prepareList() {
$('#expList').find('li:has(ul)')
.click(function (event) {
if (this == event.target) {
$(this).toggleClass('expanded');
$(this).children('ul').toggle('medium');
}
return false;
})
.addClass('collapsed')
.children('ul').hide();
$('#expandList')
.unbind('click')
.click(function () {
$('.collapsed').addClass('expanded');
$('.collapsed').children().show('medium');
})
$('#collapseList')
.unbind('click')
.click(function () {
$('.collapsed').removeClass('expanded');
$('.collapsed').children().hide('medium');
})
};
$(document).ready(function () {
prepareList()
});
I also attach jquery-1.4.2.min.js file as well
here is my html code:
<div id="listContainer">
<ul id="expList">
<li>
<p class="exp1">INDUSTRIAL</p>
<ul>
<li>
<p class="exp1">APPARELS</p>
<ul class="italic">
<li>
<a>Coveralls</a>
</li>
<li >
Uniforms
</li>
<li >
Aprons
</li>
<li >
Trousers
</li>
<li >
Kevlar Lined Denim Jeans
</li>
</ul>
</li>
<li>
<p class="exp1">GLOVES</p>
<ul class="italic">
<li >Seamless</li>
<li>Cut & Sewn</li>
<li>Leather</li>
<li>Mechanics</li>
</ul>
</li>
<li>
SLEEVES
</li>
</ul>
</li>
</ul>
</div>
I cannot tell you the reason for the anchor tags not working without seeing the javascript file you have linked to your page.
If you place this after you include your javascript file, your links should be working as normal.
If you have any anchors being created after the page has loaded (dynamic data) you can simply call Links(); to apply the onclick event handlers or you can manually add addEventListener('click',Anchors,false) when creating the anchor tag.
function Links(){
//Get all Anchor elements
var a=document.getElementsByTagName('a');
//Loop through each anchor element found.
for(var i=0; i<a.length; i++){
//Set on click event for the anchor element
a[i].addEventListener('click',Anchors,false);
}
}
function Anchors(){
//Set new window location using the anchor href that triggers this function.
window.location.href=this.href;
}
window.onload=Links;
If you have any questions about the source code above please leave your comment(s) below.
I hope this helps. Happy coding!
You have screwed up tag id in :
$('#expList') // <-- it was #expandList
.unbind('click')
.click(function () {
$('.collapsed').addClass('expanded');
$('.collapsed').children().show('medium');
})
Check out here: https://jsfiddle.net/urahara/u809p5yr/
But it's still foggy to me what you are trying to accomplish, and how. Cheers ;)
I had similar issues with my web page. I post the workaround here in case anyone else is struggling with it.
In my case I've accidentally removed the class name from my javascript code and the function was triggering with every <a> tag in my page!!
The old one:
$("a").on("click", function (e) {
// ... my function ...
});
and the right way:
$(".the-classname").on("click", function (e) {
// ... my function ...
});
In your case I think the return false is preventing the tag from working. Go ahead and delete it and check if it works fine.

Creating a Mac OS X title bar-style menu with HTML and Javascript

I am working on a web site. The type of menu that I want to create is one where you click on something in the menu, and a submenu pops up. But then you can also hover over any other menu item and another submenu will come up, hiding the first one you clicked. You can click anywhere to close the submenu.
I hope that was clear enough, and would appreciate any help you can give.
Here's my very, very simple, cheap, brief, ugly, lazy, father-disappointing version. It uses jQuery, and it probably doesn't actually look anything like what you wanted. But it accomplishes (I think) the one important thing: "locking" the sub-menu open until either another one is opened, or the user clicks somewhere else on the page.
The HTML looks like this...
<ul>
<li>
<a class="author" href="#">Menu Item 1</a>
<ul class="books">
<li><a class="book" href="#">Sub-Menu Item 1</a></li>
<li><a class="book" href="#">Sub-Menu Item 2</a></li>
</ul>
</li>
<!-- ... -->
</ul>
...and here's the JavaScript:
(function ($) {
var $current,
closeSubMenu = function () {
if ($current) {
$current.slideUp();
}
},
openSubMenu = function (e) {
var $books = $(this).next();
e.preventDefault();
e.stopPropagation();
if (!$current || $current[0] !== $books[0]) {
closeSubMenu();
$current = $books;
$books.slideDown();
}
};
$(document).click(function (e) {
var $target = $(e.target);
if ($target.hasClass('author')) {
openSubMenu.call(e.target, e);
} else if ($target.hasClass('book')) {
e.preventDefault();
} else {
closeSubMenu();
$current = null;
}
});
$('.books').slideUp();
}(jQuery));
If nothing else, it should help give you some ideas for how you do decide to do it.

Categories

Resources