Trying to get away from jQuery crutches and refactoring the bellow functions as plain JS.
//slide toggle navigation
$('#nav-toggle').click(function () {
$('.nav-list').slideToggle();
});
//toggle hamburger menu
$('#nav-toggle').click(function () {
this.classList.toggle('active');
});
I got the last one working as:
const toggle = document.getElementById('nav-toggle');
const navList = document.getElementsByClassName('nav-list');
toggle.addEventListener('click', function(e){
this.classList.toggle('active'); //toggle hamburger menu
e.preventDefault();
}, false);
I hit a blocker when I tried to pass both functionalities to the same click event:
//Add a click event listener
toggle.addEventListener('click', function(e){
//show hide div
if (navList.style.display == 'none') {
navList.style.display === 'block';
} else {
navList.style.display === 'none';
}
this.classList.toggle('active');
e.preventDefault();
}, false);
I have .nav-list
as display none in my CSS
.
Do I need separate event listeners for each event? I tried that, but the error is still the same = TypeError: navList.style is undefined
Also, what would be the refactor for this nasty one bellow as plain JS?
$('nav ul li a:not(:only-child)').click(function (e) {
$(this).siblings('.nav-dropdown').toggle();
// Close one dropdown when selecting another
$('.nav-dropdown').not($(this).siblings()).hide();
e.stopPropagation();
});
You're out of jQuery, but you're still thinking in jQuery. navList
is a NodeList object now, you need to iterate:
//Add a click event listener
toggle.addEventListener('click', function(e){
//show hide div
for( var i = 0; i < navList.length; ++i ){
if (navList[i].style.display == 'none') {
navList[i].style.display === 'block';
} else {
navList[i].style.display === 'none';
}
}
this.classList.toggle('active');
e.preventDefault();
}, false);
Edit: This monstrosity should do the other fuction's job:
(function(){
var navDropdown = document.getElementsByClassName('nav-dropdown');
var nav = document.getElementsByTagName('nav');
for( var i = 0; i < nav.length; ++i ){
var ul = nav[i].getElementsByTagName('ul');
for( var j = 0; j < ul.length; ++j ){
var li = ul[j].getElementsByTagName('li');
for( var m = 0; m < li.length; ++m ){
var a = li[m].getElementsByTagName('a');
if( a.length > 0 ){
for( var k = 0; k < a.length; ++k ){
a[k].addEventListener('click', (function(a){
return function(e){
for( var n = 0; n < a.length; ++n ){
a[n].classList.toggle('nav-dropdown');
}
for( var o = 0; o < navDropdown.length; ++o ){
var found = false;
for( var n = 0; n < a.length; ++n ){
if( navDropdown[o] === a[n] ){
found = true;
break;
}
}
if( !found ){
navDropdown[o].classList.add('hide');
}
}
e.preventDefault();
};
})(a)
);
}
}
}
}
}
})();
It might very possibly be one of the worst things I've ever written, but it should work... Obviously I can't check if it does without the actual page, but at least it runs.
you can iterate over a node list by using Array.from which will treat it as an array.
Array.from(navList).forEach(function(navItem){
navItem.style.display = navItem.style.display === 'none' ? 'block' : 'none';
})
You have the equal signs in your syntax crossed, should be:
if (navList.style.display === 'none') {
navList.style.display = 'block';
} else {
navList.style.display = 'none';
}
Quick cheat sheet:
= : assign
== : equals (also crosses javascript "type borders", ie 0 == "0" is true)
=== : strict equals (0 === "0" is false, 0 === 0 is true)
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.