jQuery toggle image not switching - javascript

I have created expandable links where the arrow changes when you expand the link. Expandable works great and the arrow keeps changing correctly when I expand the other link. It doesn't switch correctly if I expand the same link.
Here is a demo.
HTML
<ul class="side-expand">
<li class="expandor">
<a class="adobe" href="#" id="vid_link3">Adobe Digital Editions</a>
<ul>
<li>
<a href="#" id="link22"><i class="icon-video"></i>
Introduction</a>
</li>
</ul>
</li>
<li class="expandor">
<a class="android" href="#" id="vid_link4">Android</a>
<ul>
<li>
<a href="#" id="link29"><i class="icon-video"></i>
Introduction</a>
</li>
</ul>
</li>
</ul>
JAVASCRIPT
$('.expandor > a:first-child').click(function(e) {
e.preventDefault();
var $this = $(this).next('ul');
$(".side-expand li ul").not($this).slideUp();
$this.slideToggle();
$('.side-expand > li').css('background-color', 'transparent');
$('.side-expand > li').removeClass('dexpandor');
var visibleUL = $('.side-expand li').find('ul').is(':visible');
if (visibleUL) {
$(this).parent('li').css('background-color', 'transparent', 'font-weight', 'normal').addClass('dexpandor');
}
});
arrow not changing for the same toggle

Replacing lines 8 through 13 with the following should toggle your arrow class properly:
$(this).parent().siblings().removeClass('dexpandor');
$(this).parent().toggleClass('dexpandor');

Add the class change code in slideToggle() callback. Because the ul is hidden only when slide is complete, which is when you need to remove the class.
DEMO
$('.expandor > a:first-child').click(function(e) {
e.preventDefault();
var $this = $(this).next('ul');
$(".side-expand li ul").not($this).slideUp();
$this.slideToggle(function() {
$('.side-expand > li').css('background-color', 'transparent');
$('.side-expand > li').removeClass('dexpandor');
var visibleUL = $(this).closest('li').find('ul').is(':visible');
if (visibleUL) {
$(this).parent('li').css('background-color', 'transparent', 'font-weight', 'normal').addClass('dexpandor');
}
});
});
.side-expand li ul {
display: none;
}
.expandor {
background-image: url("https://odhelp.blob.core.windows.net/content/artifacts/img/right-arrow-small.png");
}
.expandor,
.dexpandor {
background-color: transparent;
background-position: right 13px;
background-repeat: no-repeat;
}
.dexpandor {
background-image: url("https://odhelp.blob.core.windows.net/content/artifacts/img/down-arrow-small.png");
}
.side-expand li a {
font-size: 14px;
font-weight: normal;
padding-left: 70px;
}
.side-expand li a {
background-size: 25px auto !important;
border-bottom: 1px solid rgb(235, 235, 235);
color: #000;
display: block;
font-size: 15px;
padding: 5px 10px;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<ul class="side-expand">
<li class="expandor">
<a id="vid_link3" value="6plk07k8op" href="#" class="adobe">Adobe Digital Editions</a>
<ul>
<li><a value="6plk07k8op" href="#" id="link22"><i class="icon-video"></i> Introduction</a></li>
<li><a value="q1kogk5dc2" href="#" id="link23"><i class="icon-video"></i> Install</a></li>
<li><a value="zmdge1whxu" href="#" id="link24"><i class="icon-video"></i> Authorize your computer</a></li>
<li><a value="snl5pnvv27" href="#" id="link25"><i class="icon-video"></i> Read eBooks</a></li>
<li><a value="8ldljcbtw0" href="#" id="link26"><i class="icon-video"></i> Return eBooks </a></li>
<li><a value="tfrp7xjgus" href="#" id="link27"><i class="icon-video"></i> Transfer eBooks to reader </a></li>
<li><a value="men1mw9an3" href="#" id="link28"><i class="icon-video"></i> Remove eBooks from reader</a></li>
</ul>
</li>
<li class="expandor">
<a id="vid_link4" value="ayfssj4211" href="#" class="android">Android</a>
<ul>
<li><a value="ayfssj4211" href="#" id="link29"><i class="icon-video"></i> Introduction </a></li>
<li><a value="aqv1ieh6zd" href="#" id="link30"><i class="icon-video"></i> Install the OverDrive app</a> </li>
<li><a value="ospa26ccnh" href="#" id="link37"><i class="icon-video"></i> Return and share titles</a></li>
</ul>
</li>
</ul>

Add this to the click event, it toggle the class :
$(this).parent('li').css('background-color','transparent', 'font-weight', 'normal').toggleClass('dexpandor','expandor');
Demo : jsfiddle

Related

Change color of current selected element sidebar

I have a sidebar with site pages. I want to change the color of a currently selected page when clicked, assign the class is-active to the currently selected item, and remove it from all the others.
Here is the HTML:
<aside id="side-bar" class="sidebar">
<h3>Pages</h3>
<nav class="menu">
<a onclick="changeColor()" class="menu-item is-active">page 1</a>
<a onclick="changeColor()" class="menu-item">page 2</a>
<a onclick="changeColor()" class="menu-item">page 3</a>
</nav>
</aside>
And CSS:
.sidebar .menu .menu-item:hover,
.sidebar .menu .menu-item.is-active {
color: #f1672c;
border-right: 6px solid #f1672c;
}
Each element has the function change color that should take all the elements, remove the is-active class from previous selected element and add to the curent clicked element.
function changeColor(){
var links = document.getElementsByClassName("menu-item")
links.map(classList.remove("is-active"))
this.classList.add("is-active")
}
What am I missing?
That changeColor() is not necessary....
const pages = document.querySelectorAll(".menu-item");
pages.forEach((item) => {
item.addEventListener('click', active_item);
})
function active_item () {
pages.forEach((item) => {
item.classList.remove('is-active');
});
this.classList.add('is-active');
}
.is-active {
background-color: red;
}
<aside id="side-bar" class="sidebar">
<h3>Pages</h3>
<nav class="menu">
<a class="menu-item is-active">page 1</a>
<a class="menu-item">page 2</a>
<a class="menu-item">page 3</a>
</nav>
</aside>
Just pass the reference of current element with this.
function changeColor(el){
document.querySelector(".menu-item.is-active").classList.remove("is-active")
el.classList.add("is-active")
}
.sidebar .menu .menu-item:hover,
.sidebar .menu .menu-item.is-active {
color: #f1672c;
border-right: 6px solid #f1672c;
}
<aside id="side-bar" class="sidebar">
<h3>Pages</h3>
<nav class="menu">
<a onclick="changeColor(this)" class="menu-item is-active">page 1</a>
<a onclick="changeColor(this)" class="menu-item">page 2</a>
<a onclick="changeColor(this)" class="menu-item">page 3</a>
</nav>
</aside>

How to change dropdown arrow image with javascript

I am trying to make a dropdown navigation menu where I am using arrow up and down images for the dropdown links. What I want is that when I click on a dropdown link means when I open the submenu, the arrow image should be the arrow-up image and when I close the submenu, it will go back to the arrow-down image. I have more than one dropdown link with the arrow images. The problem is that when I click on one of the dropdown links, the other link with an arrow image also gets triggered and changes. But I only want to change the image of one that I clicked. You can see and check the code below.
const nav__items = document.querySelectorAll(".nav__items");
const nav__list = document.querySelector(".nav__list");
function toggleSubMenu() {
if (this.classList.contains("nav__list--sub-active")) {
this.classList.remove("nav__list--sub-active")
} else if (nav__list.querySelector(".nav__list--sub-active")) {
nav__list
.querySelector(".nav__list--sub-active")
.classList.remove("nav__list--sub-active");
this.classList.add("nav__list--sub-active");
} else {
this.classList.add("nav__list--sub-active");
}
}
function toggleArrowUpDown() {
if (this.classList.contains("nav__list--sub-active")) {
document.querySelectorAll('.arrow_down').forEach((arrow) => {
arrow.src = "https://i.postimg.cc/Bb4ttXfk/arrow-up.png"
})
} else {
document.querySelectorAll('.arrow_down').forEach((arrow) => {
arrow.src = "https://i.postimg.cc/Hn9ctbtT/arrow-down.png"
})
}
}
for (let item of nav__items) {
if (item.querySelector(".nav__list--sub")) {
item.addEventListener('click', toggleSubMenu, false);
item.addEventListener('click', toggleArrowUpDown, false);
}
}
* {
box-sizing: border-box;
text-decoration: none;
list-style: none;
}
.nav__list {
margin: 0;
padding: 0;
}
.nav__items {
padding-bottom: 2em;
}
.nav__list--sub {
display: none;
}
.nav__list--sub-active .nav__list--sub {
display: block;
}
<nav class="nav">
<div class="container">
<ul class="nav__list">
<li class="nav__items">
Home
</li>
<li class="nav__items has-submenu">
<a tabindex="0">About <img src="https://i.postimg.cc/Hn9ctbtT/arrow-down.png" class="arrow_down" alt=""
/></a>
<ul class="nav__list--sub">
<li class="nav__items--sub sub-item">
<a href="#">Public Engagement
</a>
<ul class="nav__list--sub-sub">
<li>Cultural Map</li>
<li>Child Culture</li>
<li>Initiatives</li>
<li>Membership</li>
</ul>
</li>
<li class="nav__items--sub">Events</li>
<li class="nav__items--sub">
Publications
</li>
</ul>
</li>
<li class="nav__items has-submenu">
<a tabindex="0">Programs & Initiatives <img src="https://i.postimg.cc/Hn9ctbtT/arrow-down.png" class="arrow_down" alt=""
/></a>
<ul class="nav__list--sub">
<li class="nav__items--sub sub-item">
<a href="#">Public Engagement
</a>
</li>
<li class="nav__items--sub sub-item">
<a href="#">Events
</a>
</li>
<li class="nav__items--sub">
Publications
</li>
</ul>
</li>
</ul>
</div>
</nav>
Instead of document.querySelectorAll in your toggleArrowUpDown() method, change that to this.querySelectorAll so you're only querying on this instead of the entire document.
But you can also take this one step further and use CSS classes to manage the display, so you only need to toggle the class.
const nav__items = document.querySelectorAll(".nav__items");
const nav__list = document.querySelector(".nav__list");
function toggleSubMenu() {
if (this.classList.contains("nav__list--sub-active")) {
this.classList.remove("nav__list--sub-active")
} else if (nav__list.querySelector(".nav__list--sub-active")) {
nav__list
.querySelector(".nav__list--sub-active")
.classList.remove("nav__list--sub-active");
this.classList.add("nav__list--sub-active");
} else {
this.classList.add("nav__list--sub-active");
}
}
function toggleArrowUpDown() {
let spanClasses = this.querySelector('span').classList;
if (this.classList.contains("nav__list--sub-active")) {
spanClasses.remove('arrow_down');
spanClasses.add('arrow_up');
} else {
spanClasses.remove('arrow_up');
spanClasses.add('arrow_down');
}
}
for (let item of nav__items) {
if (item.querySelector(".nav__list--sub")) {
item.addEventListener('click', toggleSubMenu, false);
item.addEventListener('click', toggleArrowUpDown, false);
}
}
* {
box-sizing: border-box;
text-decoration: none;
list-style: none;
}
.nav__list {
margin: 0;
padding: 0;
}
.nav__items {
padding-bottom: 2em;
}
.nav__list--sub {
display: none;
}
.nav__list--sub-active .nav__list--sub {
display: block;
}
.arrow_down {
background-image: url('https://i.postimg.cc/Hn9ctbtT/arrow-down.png');
width: 12px;
height: 9px;
display: inline-block;
background-repeat: no-repeat;
}
.arrow_up {
background-image: url('https://i.postimg.cc/Bb4ttXfk/arrow-up.png');
width: 12px;
height: 9px;
display: inline-block;
background-repeat: no-repeat;
}
<nav class="nav">
<div class="container">
<ul class="nav__list">
<li class="nav__items">
Home
</li>
<li class="nav__items has-submenu">
<a tabindex="0">About <span class="arrow_down" alt=""
></span></a>
<ul class="nav__list--sub">
<li class="nav__items--sub sub-item">
<a href="#">Public Engagement
</a>
<ul class="nav__list--sub-sub">
<li>Cultural Map</li>
<li>Child Culture</li>
<li>Initiatives</li>
<li>Membership</li>
</ul>
</li>
<li class="nav__items--sub">Events</li>
<li class="nav__items--sub">
Publications
</li>
</ul>
</li>
<li class="nav__items has-submenu">
<a tabindex="0">Programs & Initiatives <span class="arrow_down" alt=""
></span></a>
<ul class="nav__list--sub">
<li class="nav__items--sub sub-item">
<a href="#">Public Engagement
</a>
</li>
<li class="nav__items--sub sub-item">
<a href="#">Events
</a>
</li>
<li class="nav__items--sub">
Publications
</li>
</ul>
</li>
</ul>
</div>
</nav>

I am unable to align an HTML image to the text

I'm new to web programming, and I'm having an annoying problem with HTML images alignment... I can't understand why images are always shifted down compared to text lying in the same line, regardless of its CSS settings!
<li class="navbar-item"><a class="nav-link" href="../contact/contact.php" >CONTACT</a></li>
<li class="navbar-item"><a class="nav-link" href="#"><img src="source" style="border-radius:10px;width:35px;height:35px;"></a></li>
This is the basic code I'm running, I've already tried plenty of methods to align "CONTACT" to the image, but no one of them works, giving me the same result:
You can use flexbox to align items very easily. The rule you need that aligns them vertically is "align-items: center;".
ul {
display: flex;
align-items: center;
}
li {
list-style: none;
margin: 0 .5rem;
}
img {
max-width: 100px;
}
<ul>
<li class="navbar-item">
<a class="nav-link" href="#">CONTACT</a>
</li>
<li class="navbar-item">
<a class="nav-link" href="#">
<img src="https://iconarchive.com/download/i47330/icons-land/vista-flags/United-States-Flag-1.ico">
</a>
</li>
</ul>
try
display: inline;
to the image
By default, li displays as list-item. If you change the display property of the element to "inline" it will be displayed next to the text.
Reference: https://www.w3schools.com/cssref/css_default_values.asp
<a class="nav-link" href="#">CONTACT</a>
<a class="nav-link" href="#" style="display:inline"
><img src="source" style="border-radius:10px;width:35px;height:35px"
/></a>
Thanks,
PNS

how to force a hover selector to not occur on a specific div

How do I exclude the first element in a list from being targeted by a :hover selector?
CSS:
.navbar .navbar-nav > li :hover {
color:red !important;
}
HTML:
<li>
#Html.ActionLink("Login", "Login", "Home", new { area = "" }, new
{#class ="navbar-item" })
</li>
What I have tried so far:
document.getElementsByClassName("navbar-item")[0].onmouseover = function () {
mouseOver()
};
function mouseOver() {
document.getElementsByClassName("navbar-item")[0].style.color="blue !important"
}
You dont need to use JavaScript/jQuery for this. Just use the :nth-child css selector like this:
/* target all hovered li elements except the first one */
.navbar .navbar-nav > li:nth-child(n+2) a:hover {
color: red;
}
<nav class="navbar">
<ul class="navbar-nav">
<li>
<a class="nav-link" href="#">Link 1</a>
</li>
<li>
<a class="nav-link" href="#">Link 2</a>
</li>
<li>
<a class="nav-link" href="#">Link 3</a>
</li>
</ul>
</nav>
Or if you're not using the default bootstrap anchor links and just want to target the li element itself, just chain the :nth-child selector and the :hover selector like this:
/* target all hovered li elements except the first one */
.navbar .navbar-nav > li:nth-child(n+2):hover {
color: red;
}
<nav class="navbar">
<ul class="navbar-nav">
<li>
Link 1
</li>
<li>
Link 2
</li>
<li>
Link 3
</li>
</ul>
</nav>
You could also use not().
/* target all hovered li elements except the first one */
.navbar .navbar-nav > li:not(:first-child):hover {
color: red;
}
<nav class="navbar">
<ul class="navbar-nav">
<li>
Link 1
</li>
<li>
Link 2
</li>
<li>
Link 3
</li>
</ul>
</nav>

How to add and remove active class to anchor tag within li using Jquery/Javascript

I need one help. I have multiple li values I need to add active class when clicked any value and removed from others using Jquery/Javascript.I am explaining my code below.
<ul id="ulCategory">
<li><a href='javascript:void(0)' onclick='savesubcat()'>ABC</li>
<li><a href='javascript:void(0)' onclick='savesubcat()'>ABF</li>
<li><a href='javascript:void(0)' onclick='savesubcat()'>ABK</li>
</ul>
My active class is given below.
.active {text-align: left; color: #fff; background-color:#ffbb00; text-decoration: none;}
Here I need while user will click on one value that only will be remain active and other will not have the active class.Please help me.
check below snippet
$(document).ready(function(){
$("#ulCategory li").on('click', function(){
$(this).siblings().removeClass('active');
$(this).addClass('active')
})
})
function savesubcat(){
return null
}
.active {text-align: left; color: #fff; background-color:#ffbb00; text-decoration: none;}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<ul id="ulCategory">
<li><a href='javascript:void(0)' onclick='savesubcat()'>ABC</li>
<li><a href='javascript:void(0)' onclick='savesubcat()'>ABF</li>
<li><a href='javascript:void(0)' onclick='savesubcat()'>ABK</li>
</ul>
Simply bind a click handler to the elements in question and use the .addClass() and .removeClass() methods.
Also, call your savesubcat() function from there too, rather than using the inline onclick= attribute.
var anchors = $("#ulCategory li a").click(function() {
//savesubcat()
$(this).addClass("active")
anchors.not(this).removeClass("active")
})
.active {text-align: left; color: #fff; background-color:#ffbb00; text-decoration: none;}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>
<ul id="ulCategory">
<li><a href='javascript:void(0)'>ABC</li>
<li><a href='javascript:void(0)'>ABF</li>
<li><a href='javascript:void(0)'>ABK</li>
</ul>
Put the JS at the end of the body, and/or wrap it in a document ready handler.
(I'm assuming the savesubcat() function doesn't cause page navigation or refresh, because if it did then any classes set before the refresh would be cleared.)
Try this:
<ul id="ulCategory">
<li><a href="javascript:void(0)" class="subcategory">ABC</li>
<li><a href="javascript:void(0)" class="subcategory">ABF</li>
<li><a href="javascript:void(0)" class="subcategory">ABK</li>
</ul>
Jquery:
$(".subcategory").click(function() {
$(this).addClass("active").not(this).removeClass("active");
});
You can use addClass() and removeClass() as below
HTML:
<ul id="ulCategory">
<li><a href='javascript:void(0)' onclick='savesubcat()'>ABC</li>
<li><a href='javascript:void(0)' onclick='savesubcat()'>ABF</li>
<li><a href='javascript:void(0)' onclick='savesubcat()'>ABK</li>
</ul>
JQuery:
$("#ulCategory>li").click(function(){
$("#ulCategory>li").removeClass("active");
$(this).addClass("active");
})
DEMO HERE
use with this element in the function call
function savesubcat(that){
$('#ulCategory li a').removeClass('active')
$(that).addClass('active')
}
.active {
text-align: left;
color: #fff;
background-color: #ffbb00;
text-decoration: none;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<ul id="ulCategory">
<li><a href='javascript:void(0)' onclick='savesubcat(this)'>ABC</li>
<li><a href='javascript:void(0)' onclick='savesubcat(this)'>ABF</li>
<li><a href='javascript:void(0)' onclick='savesubcat(this)'>ABK</li>
</ul>
You can use siblings method.
siblings method gets the siblings of each element in the set of
matched elements, optionally filtered by a selector.
$("ul li").click(function() {
$(this).addClass('active').andSelf().siblings().removeClass();
});
.active {text-align: left; color: #fff; background-color:#ffbb00; text-decoration: none;}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<ul id="ulCategory">
<li><a href="javascript:void(0)" class="subcategory">ABC</li>
<li><a href="javascript:void(0)" class="subcategory">ABF</li>
<li><a href="javascript:void(0)" class="subcategory">ABK</li>
</ul>
You can try something like this
$('ul li a').click(function() {
$(this).parent().siblings().children().removeClass( "active" );
$(this).addClass( "active" );
});
$('ul li a').click(function() {
$(this).parent().siblings().children().removeClass( "active" );
$(this).addClass( "active" );
});
.active {text-align: left; color: #fff; background-color:#ffbb00; text-decoration: none;}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<ul id="ulCategory">
<li><a href='javascript:void(0)' onclick=''>ABC</li>
<li><a href='javascript:void(0)' onclick=''>ABF</li>
<li><a href='javascript:void(0)' onclick=''>ABK</li>
</ul>
Just add div to your "ul" tag and write onclick event on it.Try below code
//HTML
<div id="list_div">
<ul id="ulCategory">
<li><a href='javascript:void(0)' onclick='savesubcat()'>ABC</li>
<li><a href='javascript:void(0)' onclick='savesubcat()'>ABF</li>
<li><a href='javascript:void(0)' onclick='savesubcat()'>ABK</li>
</ul>
</div>
//JS
$(document).on("click","#list_div a",function() {
$(this).parent().addClass('active').siblings().removeClass('active');
});
$(document).ready(function(){
$('#ulCategory li a').click(function(){
$('#ulCategory li a').removeClass("active")
$(this).toggleClass("active");
});
});
.active {
color: red;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<ul id="ulCategory">
<li><a>ABC</a></li>
<li><a>ABF</a></li>
<li><a>ABK</a></li>
</ul>
$("#ulCategory a").click(function() {
$(this).addClass("active")
$("a").not(this).removeClass("active")
})
.active {
text-align: left;
color: #fff;
background-color: #ffbb00;
text-decoration: none;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<ul id="ulCategory">
<li><a href='#'>ABC</a></li>
<li><a href='#'>ABF</a></li>
<li><a href='#'>ABK</a></li>
</ul>
Use addClass() and removeClass() with not()
In href use #
$('.abc').click(function () {
$('.abc').removeClass('active');
$(this).addClass('active');
});
.active {text-align: left; color: #fff; background-color:#ffbb00; text-decoration: none;}
<!DOCTYPE html>
<HTML>
<head>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.2.0/jquery.min.js"></script>
</head>
<body>
<div>
<ul id="ulCategory">
<li class="abc active"><a href='javascript:void(0)' onclick='savesubcat()'>ABC</li>
<li class="abc"><a href='javascript:void(0)' onclick='savesubcat()'>ABF</li>
<li class="abc"><a href='javascript:void(0)' onclick='savesubcat()'>ABK</li>
</ul>
</div>
</body>
</html>

Categories

Resources