Doing slideToggle and toggleClass at the same time - javascript

I'm trying to do a slideToggle and a toggleClass at the same time:
css
li ul { display: none; }
html
<li>
<div class="group"><i class="arrow_maximize"></i> Title</div>
<ul>
<li>anything</li>
</ul>
</li>
js
'click .group': function (event) {
$(event.currentTarget).next('ul').slideToggle(200);
$(event.currentTarget).children('i').toggleClass('arrow_minimize');
}
What I try to get is:
Clicking on .group will slideDown the ul; at the same time the class of i should be changed to 'arrow_minimize'.
Clicking again should set it back: slideUp of ul, change class of i to 'arrow_maximize'

In the toggleClass you also need to specify the other class which the element already has:
$(function(){
$('.group').on('click', function(){
$(this).next('ul').slideToggle(200);
$(this).children('i').toggleClass('arrow_minimize arrow_maximize');
});
});
li ul { display: none }
i.arrow_maximize:before { content: "\25ba" }
i.arrow_minimize:before { content: "\25bc" }
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>
<li>
<div class="group"><i class="arrow_maximize"></i> Title</div>
<ul>
<li>anything</li>
</ul>
</li>

Related

jQuery on click, add class but also remove if the class is already present

I have a nav menu that needs to trigger with clicks rather than hovers. When the links are clicked, an .open class would be added to the parent li. If that parent already has the .open class, then it would get removed. It would also be removed if another link is clicked on. So far I can get the class added when clicked and removed when a sibling is clicked, but not removed when it's already .open.
I tried adding a hasClass conditional, but that didn't work either. Seemed like it reruns the function every time it's clicked and therefore ignores the hasClass conditional.
Can anyone provide help? I tried toggleClass, but that didn't work.
$('li a').on('click', function() {
$('li a').parent().removeClass('open');
$(this).parent().addClass('open');
});
ul {
list-style: none;
}
li {
display: inline-block;
padding: 10px;
}
.open {
background-color: yellow;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<nav>
<ul>
<li>
Item 1
</li>
<li>
Item 1
</li>
</ul>
</nav>
To do what you require you can use toggleClass() on the parent li when the element is clicked. To remove the class from all other li elements you can use removeClass() along with not() to exclude the current li. Try this:
$('li a').on('click', function() {
let $li = $(this).parent().toggleClass('open');
$('li').not($li).removeClass('open');
});
ul {
list-style: none;
}
li {
display: inline-block;
padding: 10px;
}
.open {
background-color: yellow;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<nav>
<ul>
<li>
Item 1
</li>
<li>
Item 1
</li>
</ul>
</nav>
You can use
jquery toggleClass() to toggle yellow highlight (.open css class) on click/unclicking the same link.
jquery siblings() to remove .open class on all the other li items.
Below is the link for the demo
https://jsfiddle.net/so1u8hq6/
$('li a').on('click', function() {
$(this).parent().siblings().removeClass('open');
$(this).parent().toggleClass('open');
});
ul {
list-style: none;
}
li {
display: inline-block;
padding: 10px;
}
.open {
background-color: yellow;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<nav>
<ul>
<li>
Item 1
</li>
<li>
Item 2
</li>
<li>
Item 3
</li>
</ul>
</nav>
Late to the party, but, after seeing the provided answers and some of the CSS you use I had to urge with my suggestions:
UX. Avoid styling LI tags in general, or at least set the desired display and move on. Style directly the a tag (with the necessary paddings etc.). You'll not only get less CSS to take care of, but also a larger touch interaction area. Makes no sense to style something yellow if it's not a UI part of something interactable. Also in JS, you don't need to take care about the LI wrappers any more - but only about the actual A Elements.
Don't use common selectors like $('li a') - those might target any LI→A elements in your app. Instead be more specific and use a Class like i.e: .tabs for the parent UL. Both in CSS and JS.
Try to use Event Delegation (in jQuey using the .on() method). Not only it will help you to catch the Event.delegateTarget parent UL where needed, but also the this (the clicked element), but mainly reference all the "group" of a elements enclosed in the common parent. That way you can have as many .tabs in a single page as you like. And yes, thanks to Event delegation you can even add dynamically LI Elements - and your JS will still work as expected.
Since you're using <a href="#"> Anchor elements, instead of (more properly) <button type="button>" Elements, you need to also use Event.preventDefault() in order to prevent the browser its default behavior and that's to follow anchors (scroll the page, navigate, etc...)
Use the selector "a.open" when you want to target and remove the "open" class. By just using "a" (or in other answers on this page - "li") you're uselessly touching elements trying to remove a class that's not there in the first place.
Finally, here's the CSS retouch and the proper jQuery needed for your task:
$(".tabs").on("click", "a", function(ev) {
ev.preventDefault();
$("a.open", ev.delegateTarget).not(this).removeClass("open");
$(this).toggleClass("open");
});
.tabs {
display: flex;
list-style: none;
padding: 0;
}
/* Style your Anchors, not the dummy LI wrappers */
.tabs a { padding: 10px; }
.tabs a.open { background-color: yellow; }
<ul class="tabs">
<li>Item 1</li>
<li>Item 2</li>
<li>Item 3</li>
</ul>
<script src="//cdnjs.cloudflare.com/ajax/libs/jquery/3.6.0/jquery.min.js"></script>
To explain the only complicated line:
$(
"a.open", // Target just the ones (if any) of class "open"
ev.delegateTarget // inside the common ".tabs" ancestor
)
.not(this) // ... not the clicked element (since later we'll use .toggleClass on it)
.removeClass("open"); // ... remove that class "open"
the rest is pretty self explanatory.
Further read:
jQuery Event Delegation
jQuery event.delegateTarget
Event.preventDefault
So you only want the yellow background to appear as a signifier of user interaction rather than for the background color to be displayed? Have you tried using the mousedown/mouseup functions instead of .on('click', function(){...}?
I was able to simulate the click event where the color showcases via this method:
$('li a').mousedown(function() {
$('li a').parent().removeClass('open');
$(this).parent().addClass('open');
});
$('li a').mouseup(function() {
$('li a').parent().removeClass('open');
});
ul {
list-style: none;
}
li {
display: inline-block;
padding: 10px;
}
.open {
background-color: yellow;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<nav>
<ul>
<li>
Item 1
</li>
<li>
Item 1
</li>
</ul>
</nav>

Display image when hover over button

This is my site.
What I am trying to do: display an image when user hovers over the links.
I am definitely making some stupid mistake but I am not really sure which.
This is what I have done:
HTML
<ul class="nm">
<li>Cork
<div class="place-image">
<img src="http://classichits.ie/wp-content/uploads/2016/02/cork.png">
</div>
</li>
.......Remaining li's.....
</ul>
CSS
.place-image{
display:none;
}
div.place-image{
width:326px;
height:326px;
}
javascript
$('.place-image').hover(
function() {
$('.place-image').fadeIn('slow');
},function() {
$('.place-image').fadeOut('slow');
}
);
Please help me out.
You where tying to hover a hidden element. That is why your code was not working. You cannot trigger an event on a hidden element.
$('a').hover(
function() {
$('.place-image').fadeIn('slow');
},function() {
$('.place-image').fadeOut('slow');
}
);
.place-image{
display:none;
}
div.place-image{
width:326px;
height:326px;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<li>
Cork
<div class="place-image"><img src="http://classichits.ie/wp-content/uploads/2016/02/cork.png"></div>
</li>
You need to add hover event to li like following.
$('li').hover(
function() {
$(this).find('.place-image').fadeIn('slow');
}, function() {
$(this).find('.place-image').fadeOut('slow');
});
What I am trying to do display an image when hover over the links.
make it
<li>
Cork
<div class="place-image"><img src="http://classichits.ie/wp-content/uploads/2016/02/cork.png"></div>
</li>
$('li a').hover(
function() {
$(this).next('.place-image img').fadeIn('slow');
},function() {
$(this).next('.place-image img').fadeOut('slow');
}
);
Issue: you cannot detect a :hover state on an element with display: none
A possible solution might be to hide only the img itself, and listen to the :hover on the wrapper .place-image or on the a or li as you wish. See the demo below:
$('.place-image').hover(
function() {
$('img', this).fadeIn('slow');
},function() {
$('img', this).fadeOut('slow');
}
);
.place-image{
width:326px;
height:326px;
}
.place-image img {
display: none;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<li>
Cork
<div class="place-image">
<img src="http://classichits.ie/wp-content/uploads/2016/02/cork.png">
</div>
</li>
Alternative solution
Depending on your circumstances you could achieve this also without js:
.place-image {
width:326px;
height:326px;
}
img {
opacity: 0;
transition: opacity .4s ease;
/*TODO: add crossbrowser prefixes*/
}
li:hover img{
opacity: 1;
}
<ul>
<li>
Cork
<div class="place-image">
<img src="http://classichits.ie/wp-content/uploads/2016/02/cork.png">
</div>
</li>
</ul>
You just have to change your Javascript:(In your website ul has class nm use it to target specific li in ul. )
HTML
<li>
Cork
<div class="place-image"><img src="http://classichits.ie/wp-content/uploads/2016/02/cork.png"></div>
</li>
CSS
.place-image{
display:none;
}
div.place-image{
width:326px;
height:326px;
}
javascript
$( "ul.nm > li" ).
$('li').hover(
function() {
$(this).find('.place-image').fadeIn('slow');
}, function() {
$(this).find('.place-image').fadeOut('slow');
});
$('a').hover(
function() {
$('.place-image').fadeIn('slow');
},function() {
$('.place-image').fadeOut('slow');
}
);
.place-image{
display:none;
}
div.place-image{
width:326px;
height:326px;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<li>
Cork
<div class="place-image"><img src="http://classichits.ie/wp-content/uploads/2016/02/cork.png"></div>
</li>

Javascript/jQuery cancel a function in another

I have a function that on hover, it shows the image next to the list item. That works fine. However, I need to have it so that when the user clicks the link, the image stays there. As of right now when the user clicks the link the hover function still prevails and the image will only show if the link is being hovered over.
$('[href]').hover(function() {
$(this).closest('li').prev('li').removeClass('hidden');
}, function() {
$(this).closest('li').prev('li').addClass('hidden');
});
$('[href]').click(function(ev) {
ev.preventDefault();
$(this).closest('li').prev('li').removeClass('hidden');
});
ul, li {
list-style: none;
display: inline-block;
}
.hidden {
visibility: hidden;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<ul>
<li class="hidden"><img src="https://placehold.it/30x30" /></li>
<li>Link</li>
</ul>
This happening because hover overwrites click. I create this solution so when click the link the image remains visible:
var clickHref = false;
$('[href]').hover(function() {
$(this).closest('li').prev('li').removeClass('hidden');
}, function() {
if (!clickHref)
$(this).closest('li').prev('li').addClass('hidden');
});
$('[href]').click(function(ev) {
ev.preventDefault();
$(this).closest('li').prev('li').removeClass('hidden');
clickHref = !clickHref;
});
ul,
li {
list-style: none;
display: inline-block;
}
.hidden {
visibility: hidden;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<ul>
<li class="hidden">
<img src="https://placehold.it/30x30" />
</li>
<li>Link
</li>
</ul>
Probably the off method fit your needs:
$('[href]').click(function(ev) {
ev.preventDefault();
$(this).off("mouseenter mouseleave").closest('li').prev('li').removeClass('hidden');
});

How to cancel a CSS style set by 'hover child' selector on event?

I am making a CSS based menu, with submenu items that pop up when the root element is hovered. the problem I have is that I want the CSS menu to close when I click an item in the list, but at that point I am still technically hovering over the top element, so I figured I had to use javascript to hide the menu. But when I set the display property, I set it forever and it overrides the hover selector of the parent node. And so the submenu doesn't show up anymore.
This must be pretty common, but I can't find any answers...
Any help much appreciated!
html:
<ul class="level1">
<li>one
<ul class="level2">
<li id="test">two</li>
<li>three</li>
</ul>
</li>
</ul>
css:
.level1 li:hover > ul {
display: inline;
}
.level2 {
display: none;
}
js:
document
.getElementById('test')
.addEventListener('click',function () {
this.parentNode.style.display = 'none';
// After this the menu doesn't open anymore
// because the style is overriden
});
Here's the jsfiddle
You can try this.
<ul class="level1">
<li class="hoverMe">one
<ul class="level2">
<li id="test">two</li>
<li>three</li>
</ul>
</li>
</ul>
.hoverMe:hover > ul {
display: inline;
}
var test = document.getElementById('test');
test.onclick = function () {
this.parentNode.parentNode.className = "";
};
var level1 = document.getElementsByClassName('level1')[0];
level1.getElementsByTagName("li")[0].onmouseover = function () {
if (this.className != "hoverMe") {
this.className = "hoverMe";
}
};

Activate dropdown with pure javascript

Right now I have a pure HTML CSS navigation bar with some dropdowns. However on ipad the hover will obviously not work.
I want to add a click event to the relevant menu items so the dropdown will also activate with an onclick event.
I've look at other answers but I'm not capable of reading javascript well enough so that I can modify them for my specific site.
here is a link to where I'm at now: http://2ftrade.nl/kareem/eindopdracht/
and this is the relevant html. In my css the default is display:none for the dropdown menus and is changed to display:block when hovered over the li that contains it.
<ul>
<li>Home</li>
<li><a title="">Opleiding</a>
<!-- the dropdown -->
<ul>
<li>Visie & Beleid</li>
<li>Opbouw Studieprogramma</li>
<li>Competenties</li>
<li>Diploma</li>
<li>Beroepen</li>
</ul>
</li>
<li>Onderwijsprogramma</li>
<li>Organisatie</li>
<li><a title="">Stages en Projecten</a>
<!-- another dropdown -->
<ul>
<li>Stages</li>
<li>Projecten</li>
</ul>
</li>
<li>Top</li>
</ul>
This is the css that hides the dropdown section
nav > ul > li > ul {
display: none;
position: absolute;
}
and this is what will display it when hovering
nav > ul > li:hover ul {
display: block;
}
you can attach event listener to your element:
var dropdown_button = document.getElementById('#your-button-that-activates-dropdown');
dropdown_button.addEventListener('click', function() {
//here do what you want to do when the button is clicked.
}, false);
you should use javascript events , some thing like this :
var btn = document.getElementById('btn') // this button is a key to run what you want
var drp = document.getElementById('drp') // this is your dropdown list
btn.onclick = function()
{
drp.style.display = 'block'
// other codes . . .
}
You can achieve this without using javascript.
Use the :target selector
example
Add an id and href for each target in the html
<ul>
<li>Home</li>
<li id="Opleiding">
<a title="" href="#Opleiding">Opleiding</a>
<!-- the dropdown -->
<ul>
<li>Visie & Beleid</li>
<li>Opbouw Studieprogramma</li>
<li>Competenties</li>
<li>Diploma</li>
<li>Beroepen</li>
</ul>
</li>
<li>Onderwijsprogramma</li>
<li>Organisatie</li>
<li id="StagesenProjecten">
Stages en Projecten
<!-- another dropdown -->
<ul>
<li>Stages</li>
<li>Projecten</li>
</ul>
</li>
<li>Top</li>
</ul>
in the css specify the style for the :target
nav > ul > li:target ul {
display: block;
}
nav > ul > li:hover ul {
display: block;
}
nav > ul > li > ul {
display: none;
position: absolute;
}

Categories

Resources