I'm working on a basic dropdown element in HTML and jQuery and I'm trying to get better at understanding JavaScript and jQuery so this questions is a bit about code refactoring as well.
So here is what I've gotten so far:
HTML
<li class="nav-item">
<a class="nav-link" href="#">Foo</a>
<div class="subnav">
...
</div>
</li>
JavaScript
const navLink = $('.nav-link');
navLink.each(function () {
let $this = $(this);
$this.click(function (e) {
let hasSubnav = $this.parent().find('.subnav');
if(hasSubnav.length !== 0) {
e.preventDefault();
$this.toggleClass('dropdown-active');
}
hasSubnav.stop(true, true).slideToggle(200);
})
});
This solutions works fine. So what I want to do next is to check if another element in my loop is active, close is accordingly and then open the one I just clicked.
I thought about just putting a default click function before the each function like this:
navLink.click(function () {
$('.subnav').slideUp();
});
navLink.each(function () {
let $this = $(this);
$this.click(function (e) {
let hasSubnav = $this.parent().find('.subnav');
if(hasSubnav.length !== 0) {
e.preventDefault();
$this.toggleClass('dropdown-active');
}
hasSubnav.stop(true, true).slideDown(200);
})
});
But this does not seem to work. So my question is, is there a pretty way to achieve this maybe even inside of the each function? I've red about .not(this) in this post, which will maybe work (haven't tried it yet) but I thought that this would be duplicated code and that there might be a better way to get this to work.
eachhere, since you're setting an event handler. JustnavLink.on('click', function (e) { ... })will apply the click function to all elements innavLink. Then, just setnavLink.removeClass('dropdown-active')to remove the class from all, and$(this).addClass('dropdown-active')to add it to the current one.