slideDown on a drop down menu - javascript

I want to do this(photoshop image) on my page:
On hover(over the ACTORS link) I want the yellow drop down list(where Fotis J.Colakides etc is) to show up slowly. From up till down.
I don't know what is the best way to do this on my page.
Of course I have to use an unorder list() like this:
<ul id="showInfoNav">
<li><a class="slideBtn" href="#">MEDIA</a>
<ul class="slideShow">
<li>assa</li>
</ul>
</li>
<li><a class="slideBtn" href="#">ACTORS</a>
<ul class="slideShow">
<li>ACTOR1</li>
<li>ACTOR2</li>
</ul>
</li>
</ul>
[Update]
Util now I have done this: (http://jsfiddle.net/bMGhC/)
But I am doing it from css. I have the left:-9999px; and on hover I am doing it left:0px;
I want to do it slideDown. But it is not working.
here is my css:
ul#showInfoNav
{
list-style:none;
float:left;
width:100%;
}
ul#showInfoNav li
{
float:left;
margin-right:50px;
position:relative;
}
ul#showInfoNav a.slideBtn
{
padding:5px;
display:block;
text-decoration:none;
}
ul#showInfoNav ul a:hover{
color:#898989;
}
/*--- DROPDOWN ---*/
ul#showInfoNav ul
{
background-color:#F4F9B6;
padding:50px 10px 10px 10px;
list-style:none;
left:-9999px; /* Hide off-screen when not needed (this is more accessible than display:none;) */
position: absolute;
top:-20px;
/*z-index:-1;*/
}
ul#showInfoNav ul li
{
float:none;
}
ul#showInfoNav ul a{
white-space:nowrap;
}
ul#showInfoNav li:hover ul{ /* Display the dropdown on hover */
left:0; /* Bring back on-screen when needed */
}
I have also this z-index problem. If I set it -1 it is hidden behind the image too.

Check out jQuery UI effects, specifically slide():
http://docs.jquery.com/UI/Effects/Slide

You could also look into the slideToggle() method that jQuery supplies.
See an example here.
Similar functions would be slideUp(), slideDown() and the more general, animate()

Take a look at .hover(), and .slideUp/Down(). You can also replace .hover with .toggle in the following code, if you'd like a more 'permanent' state. The key to both is utilizing their callback functions.
HTML
Click to see a list
<ul>
<li>List Item</li>
<li>List Item</li>
<li>List Item</li>
<li>List Item</li>
</ul>
jQuery
$('ul').hide(); // doing this rather than via CSS for a fail-safe for JS
$('a').hover(function() {
$('ul').slideDown('fast');
}, function() {
$('ul').slideUp('slow')
})​

When using jQuery fadeIn() you can specify the duration too.
Some simple sample would be:
Give the li's some id or class ( <li id="actor1">soemthing</li>)
In the JS file or script tag use:
$("#actor1).hover(function(){ $(this).slideDown('slow')}, function(){ $(this).slideUp('slow') });
EDIT: I see that you want a sliding effect so, I changed fadeIn() and fadeOut() to slideDown() and slideUp(). You can read their documentation here

This is the solution I found, I used this because I didn't want the <ul> to slideUp when I was navigating among his <li> tags.
$('ul.slideShow').hide();
$("#showInfoNav li").click(function () {
$(this).find('ul.slideShow').slideDown('fast').show();
$(this).hover(function () { // PARENT
}, function () {
$(this).parent().find("ul.slideShow").slideUp('slow'); //When the mouse hovers out of the subnav, move it back up
});
});

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>

Extendable menu using CSS and Javascript

I would like to create a menu like the screenshot
the red arrow means when I click on the button it will either show /
hide the menu
the orange arrow means when menu is hide the box should increase the
width, and vice versa
So far I have created the html, the problem is
1) the sliding effect seems not exactly what I expected, it slide after the content is show , but what I would like to achieve is hide and slide at same time
$("#menu_btn").on("click", function () {
var menu = $("#left_menu #btn");
if (menu.css('display') !== "none") {
$("#left_menu #btn").hide("slide", {direction: "left"}, 1000);
} else {
$("#left_menu #btn").show("slide", {direction: "right"}, 1000);
}
});
2) how to combine the code to extend / decrease width after the slide effect, and the box is absolute in the container , can I keep the same top after the content expend / reduce?
$(".content #bg").css("width","600");
$(".content #bg").css("width","1000");
Thanks for helping.
Something like this may work:
https://jsfiddle.net/7k4kdmxu/4/
CSS:
.container{width:100%; margin:0 auto;}
nav{
width:20%;
float:left;
background:#efefef;
}
.openNav{ width:20%;}
#content.openNavContainer{ width:80%!important;}
.closeNav{width:10%;}
#content.closeNavContainer{ width:90%!important;}
#content{
width:80%;
float:right;
background:#e9e9e9;
}
nav ul {list-style:none;}
nav ul li{list-style:none; display:block;}
HTML
<div class="container">
<nav>
Open ->
<ul>
<li>HOME</li>
<li>ABOUT</li>
<li>OUT VALUE</li>
<li>SEASONAL</li>
<li>CONTACT</li>
</ul>
<- Close
</nav>
<div id="content"><p>Body Content Can Go Here</p></div>
</div>
JS/JQ
$(function(){
$("#open").click(function(){
$("nav").addClass("openNav");
$("nav").removeClass("closeNav");
$("#content").addClass("openNavContainer");
$("#content").removeClass("closeNavContainer");
});
$("#close").click(function(){
$("nav").addClass("closeNav");
$("nav").removeClass("openNav");
$("#content").addClass("closeNavContainer");
$("#content").removeClass("openNavContainer");
});
});

trigger visibility of sublist on class change

I've been trying to achieve this for the last two days, but I'm fairly new to javascript, so maybe I'm just not seeing something.
What I'm trying to create is a Sidenavigation, that highlights the current section you are at. I have found a jquery plugin that does that like a charm http://trevordavis.net/blog/jquery-one-page-navigation-plugin/
But I am working with subitems and I would like to trigger the visibility of this subitem, as soon as the current section is active. So the ul would be visible if the containing list item has the class of .current, and if one of the sublist's list items has the class .current.
I have found out, that I'd probably need to trigger an event on the class change. I have tried the following, but it has not yet worked.
Markup:
<ul id="nav">
<li class="current">Section 1</li>
<li>Section 2</li>
<li class="parent">Section 3
<ul class="sublist">
<li>Subsection 1</li>
<li>Subsection 2</li>
<li>Subsection 3</li>
</ul>
</li>
</ul>
For the jquery I have tried this:
$('#nav').on('event', function(){
$('.parent').addClass('current').trigger('visibility');
});
$('.parent').on('visibility', function(){
$('.parent .sublist').addClass('visible');
});
What I am basically trying to do is what Bootrap does in its documentation. When scrolling down, you can see Glyphicons, as soon as you reached this section, the subitems pop open (available glyphs, how to use, examples) http://getbootstrap.com/components/
SASS applied to the Navigation so far:
.overview{
transition: .3s all;
ul{
margin-left: 10px;
ul{
max-height: 0;
transition: max-height 1s ease-out;
overflow: hidden;
}
}
}
.current{
> a{
font-weight: $bold;
}
ul{
max-height: 9999px !important;
transition: max-height 1s ease-out;
}
}
I have been able to show the sublist if the parent is set to current, but as soon as the child is current, the sublist will be hidden, so I figured, I'd need some javascript
I see now :)
What you could do, (there's probably multiple way, but what I'd do) is create a function that checks on scroll if a class is nearing the top of the window, if so, add a class to the relating item in the nav bar.
Should be relatively simple to do without a plugin, something along the lines of:
var checkSide = function(){
$('.container p').each(function(){
var item = $(this).offset().top,
$window = $(window),
navItem = $('#nav a[data-id="'+$(this).data('id')+'"]');
if ($window.scrollTop() >= item) {
if (!navItem.hasClass('current')) {
$('#nav .current').removeClass('current');
navItem.addClass('current');
}
}
});
};
$(window).scroll(function(){
checkSide();
});
See http://codepen.io/jhealey5/pen/GjJFI - Should be able to adapt it to your needs.
Assuming I understood correctly :)

How to change arrow icon once click dropdown

HTML:
<div class="selectContainer">
<ul>
<li class="init">Select</li>
<li data-value="value 1">Option 1</li>
<li data-value="value 2">Option 2</li>
</ul>
</div>
CSS:
.selectcontainer ul li
{
border:1px solid green;
width:100%;
cursor:pointer;
}
.selectcontainer ul li:not(.init){
display:none;
float:left;
}
li.init{cursor:pointer; background:url("../images/arrow-down.png") right no-repeat;}
li.init1 { cursor: pointer; background:url("../images/arrow-up.png") right no-repeat;}
JQuery:
jQuery(document).ready(function () {
$( "ul" ).click(function() {
$(this).closest("ul").children('li:not(.init)').slideToggle(200);
});
$( "li" ).click(function() {
$("li .init").addClass("li .init1");
});
});
Hi I just have to change my image when dropdown is open up arrow and when close down arrow.
This code is not working please help.
Solved:
You were not toggling "init1" class (first <li>) on click of <ul>, so your arrows were not changing on click.
$("ul").click(function () {
$(this).children('li:not(.init)').slideToggle(200);
$(this).find("li.init").toggleClass("init1");
});
Below is the JS fiddle working example, i have used special characters and :after pseudo class for up/down arrows , you can change as it suits you.
http://jsfiddle.net/4C5ND/
SO simple .U could use transform:rotate(180deg); CSS on click.
You could try:
if($(this).hasClass("class1")){
$(this).removeClass("class1").addClass("class2");
}else{
$(this).removeClass("class2").addClass("class1");
}

Child ul not showing when parent ul set with overflow hidden

HTML
<div id="gadget">
<span id="nav_up">UP</span>
<ul>
<li>LIST1
<ul>
<li>Child1.1</li>
<li>Child1.2</li>
</ul>
</li>
<li>LIST2
<ul>
<li>>Child2.1</li>
</ul>
</li>
<li>LIST3
<ul>
<li>>Child3.1</li>
</ul>
</li>
</ul>
<span id="nav_down">Down</span>
</div>
CSS
#gadget{width:75px; height: 100%;}
#gadget ul{height:450px; width:100%; overflow:hidden;}
#gadget ul li ul{display:none;}
#gadget ul li:hover ul{display:block;}
JS
$('#nav_down').click(
function () {
$('#gadget ul').animate({scrollTop: '100px'}, 800);
}
);
$('#nav_up').click(
function () {
$('#gadget ul').animate({scrollTop: '0px'}, 800);
}
);
Here on click <span> up and down the gadget <ul> moves up and down according to the overflow.
But when overflow:hidden is applied the child <ul> is not showing. And when I remove it child <ul> shows but the <span> scroll dosenot work. How can i solve this?
I believe the problem is all of your ULs are height:450px, would applying the height to only the top element solve the problems?
#gadget > ul{height:450px; width:100%; overflow:hidden;}
Your nested ul needs to be absolutely positioned and for proper scrolling grab the body element and apply the animate method http://jsfiddle.net/PJ3gp/
#gadget ul li ul{display:none;position:absolute;}
Add position:absolute to child elements

Categories

Resources