Smooth toggle in jQuery - javascript

I am using some simple jQuery to animate a toggle button. The toggle works, however, no matter how I try changing values, I cannot seem to change the speed or smoothness of the animation.
I have looked at different methods and tried changing the values within the .sliderUp section, it just isn't working for me.
The code I am using is:
$(document).ready(function(){
$("a.toggle").click(function(){
if ($("nav ul").hasClass("expanded")) {
$("nav ul.expanded").removeClass("expanded").slideUp(250);
$(this).removeClass("open");
} else {
$("nav ul").addClass("expanded").slideDown(250);
$(this).addClass("open");
}
});
});
-
<nav>
Toggle Menu
<ul>
<li>Menu Item</li>
<li>Menu Item</li>
</ul>
</nav>
-
nav {
width: 100%;
ul {
display: none;
width: 100%;
&.expanded {
display: block;
}
}
.toggle {
display: block !important;
}
}

Try to use slideToggle
Syntax
$(selector).slideToggle(speed,callback);
Here the optional speed parameter can take the following values: "slow", "fast", milliseconds.
So i think you need to put more time to get smooth animation.
Jquery
$(document).ready(function(){
$("a.toggle").click(function(){
$("nav ul").slideToggle(1500);
$(this).toggleClass("open");
});
});
Here is the working jsfiddle:https://jsfiddle.net/88bm4x6z/1/

If any of you still not been able to slide smoothly, just set transition: none;. if you'r using it in your parent item or child, I stuck in it for 3 hours. Then I just set it to none, it worked.

Related

Activate ':hover' only when mouse moves down list and remove when mouse moves up

So I have to implement a Jquery function in which every li Element is executing the :hover pseudo class (which only changes the background color). So if I hover down to the 4th Element ALL previous li Elements (1st, 2nd, 3th) should have the changed background color from the :hover pseudo class!! But if I move up with the mouse again the :hover effect should disappear (normal background color again) up to the point where my mouse is (if it is on 2nd element only 1st and 2nd have the hover effect now) ... I have absolutely no idea how I can create such a method... I did something like
$('ul li').on('mouseenter') {
$(this).addClass('hover'); //alternatively $(this).css('background-color', 'grey');
}
but it does not remove any :hover effect and it makes failures possible like that only the first and the 5th li Element have the :hover effect but all in between remain normal which I don't want... Could you please help me?
Link to working example on jsfiddle.net
So lets start with some sample markup for a list:
<ul>
<li>1</li>
<li>2</li>
<li>3</li>
<li>4</li>
</ul>
Then some css for your 'hover':
.hover {
background-color: red;
}
And some javascript to give the functionality:
$(function(){
// Our list items.
var listItems = $('ul').children();
// An event listener over all list items.
$('li').hover(hoverIn, hoverOut);
// Find the index of the current element
// and set all elements up to this element as hover.
function hoverIn() {
var index = listItems.index(this);
$.each(listItems, function(idx, ele) {
if (idx <= index) {
$(this).addClass('hover');
} else {
$(this).removeClass('hover');
}
});
}
// Remove all hover.
function hoverOut() {
$.each(listItems, function(idx, ele) {
$(this).removeClass('hover');
});
}
});
In fact this could be done entirely with css. No jQuery or JavaScript is required for this. You should consider using some html structure like this:
<ul>
<li><span>Menu item 1</span></li>
<li>
<span>Menu item 2</span>
<ul>
<li><span>Submenu item 1</span></li>
<li>
<span>Submenu item 2</span>
<ul>
<li><span>Subsubmenu item 1</span></li>
<li><span>Subsubmenu item 2</span></li>
<li><span>Subsubmenu item 3</span></li>
</ul>
</li>
<li><span>Submenu item 3</span></li>
</ul>
</li>
</ul>
Then you can use css like this
li:hover > span {
background: #9a0000;
}
See this jsfiddle: https://jsfiddle.net/aey5cusm/
Or if you ment by first, second, thirth of a single list, it can be done with css too.
ul {
list-style: none;
margin: 0;
padding: 0;
}
ul:hover li {
background: #9a0000;
}
li:hover ~ li{
background: none;
}
Just look at this jsfiddle: https://jsfiddle.net/aey5cusm/1/

How to get rid the inline style using jquery or javascript

How to remove these two inline style beside the .dropdwon menu, I tried the remove attribute [ jQuery('.dropdown-menu').removeAttr('style'); ] unfortunately it doesn't remove the inline style. Every time I hover the nav the inline style change to display block and when it hover out the inline style is set to display:none
<ul role="menu" class=" dropdown-menu" style="display: none;">
<ul role="menu" class=" dropdown-menu" style="display: block;">
Here's my code. I'm trying to remove this on size 767 or mediaquery max-width(767)
jQuery(window).resize(function() {
var width = jQuery(window).width();
if( width < 767 ) {
jQuery('.dropdown-menu').removeAttr("style");
}
});
jQuery(document).resize(function() {
var width = jQuery(document).width();
if( width < 767 ) {
jQuery('.dropdown-menu').removeAttr("style");
}
});
please see the two attached image for better visualization
When I hover the nav(About) the subpage show(ul.dropdown-menu) and the inline style will set to display block
When I hover out the nav(About) the subpage (ul.dropdown-menu) inline style will set to display none
Please help me get rid these two inline style the style="display:none"; and style="display:block";
Try with show()
jQuery('.dropdown-menu').show()
or css()
jQuery('.dropdown-menu').css('display','block')
Drag the output window of the fiddle .They will show the menu on resize
Demo Fiddle
There is a JavaScript somewhere that is adding those styles. I guess you are using some framework or template you found in the Internet. Now you either have to remove the not-needed code that adds the styles (recommended!) or bind over it to be removed each time, something like what you have written but in different event:
jQuery('.dropdown-menu').hover(function() {
jQuery('.dropdown-menu').removeAttr("style");
}, function() {
jQuery('.dropdown-menu').removeAttr("style");
});
Ensuring this is after the piece of code that does the style adding at first place.
Or you can try totally removing the behaviour for the menu and write your own:
jQuery('.dropdown-menu').unbind();
Try to append at the end of your main css file a rule-set declaration on .dropdown-menu selector with the property display:none for media-query < 767:
#media screen and (max-width: 766px) {
.dropdown-menu {
display:none;
}
}
You can use click instead of hover for mobile, and display: none; by default, set in CSS. Then add a media queries for PC (here > 767px) to force display: block;. The good thing is that you limit the use of JS.
This is a working example of what can be done.
EDIT
I updated the snippet with an example which is, I think, closer to your code.
$('.menu-item').click(function() {
$(this).toggleClass("active");
});
.menu-item .dropdown-menu {
display: none;
}
.menu-item.active .dropdown-menu {
display: block !important;
}
#media only screen and (min-width: 767px) {
.menu-item .dropdown-menu {
display: block !important;
}
}
<ul role="menu" class="menu">
<li class="menu-item">Menu 1</li>
<li class="menu-item">
Menu 2
<ul role="menu" class="dropdown-menu" style="display: none;">
<li>Submenu 1</li>
<li>Submenu 2</li>
<li>Submenu 3</li>
</ul>
</li>
</ul>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>

jQuery SlideDown only if another `ul` is clicked

I've an unordered list.
<div class="categories-list">
<ul class="display_categories">
<li>
<a class="title"><span><b>1</b></span></a>
<ul class="display_subcategories">
<li><a>22</a></li>
<li><a>22</a></li>
</ul>
</li>
<li>
<a class="title"><span><b>1</b></span></a>
<ul class="display_subcategories">
<li><a>22</a></li>
<li><a>22</a></li>
</ul>
</li>
</ul>
</div>
I want that when a user clicks on any category, its sub-category should slidedown and whenever the same category is clicked, nothing should happen. Here's my jQuery
$('.display_subcategories').hide()
$('.title').click(function(){
$('.display_categories').children().children('ul').slideUp('fast');
$(this).next().slideDown('fast');
})
but what happens is that upon clicking on the already slideDown category, it again slides up and then slides down.
Here is the jsFiddle link
You can slideDown the current submenu, then use not() to slideUp() all except the current, like this:
$('.display_subcategories').hide()
$('.title').click(function() {
var $submenu = $(this).next().slideDown('fast');
$('.display_categories').find('> li > ul').not($submenu).slideUp('fast');
});
Updated fiddle
Note also the use of find() with the descendant selector over chained children() calls.
Try this
$('.display_subcategories').hide();
$('.title').click(function(){
if(!$(this).hasClass('down')){
$('.title').removeClass('down');
$('.display_categories').children().children('ul').slideUp('fast');
$(this).next().slideDown('fast');
$(this).addClass('down');
}
})
Updated JS Fiddle
I would suggest letting CSS manage your animations by triggering or disabling classes. A simple example would be adding the .active class to an open <ul>, and the following CSS:
.display_subcategories { max-height: 0; overflow: hidden; transition: all 300ms; }
.display_subcategories.active { max-height: 50px; }
Here is a modified JSFiddle with my suggestion.

Dropdown Menu: Infinite Slide on Hover with jQuery

I have created a simple dropdown menu with jquery
https://jsfiddle.net/pmksgz3w/
HTML
<ul>
<li>Page A</li>
<li>Page B
<ul>
<li>Dropdown</li>
<li>Dropdown</li>
</ul>
</li>
</ul>
Jquery
$(document).ready(function(){
$('ul> li').hover(function() {
$(this).find('ul').slideToggle();
});
});
When I hover over Page B, then the dropdown menu is shown. If I move the curser from Page B very slowly to the right (see picture) then the drop-down menu will close, since the li is not hovered for a short moment. How can I prevent that the dropdown menu will instantly close?
An even worse problem happens if I move the cursor extremely fast to the dropdown menu. Because then, the dropdown menu will slideUp and slideDown in an infinite loop.
I found at How to tell .hover() to wait? a promising solution from 2009 but the answer does not work when I try it,(Edit note: It works now, see edit below). Further it is mentioned that one should use hoverIntend plugin. I downloaded the plugin and changed my jQuery code to
$(document).ready(function(){
$('ul> li').hoverIntend(function() {
$(this).find('ul').slideToggle();
});
});
and although it improves some things, the above problem that it instantly closes and the infinite loop remains. How can I solve this problem?
Edit: I managed to solve the first problem! Now the dropdown does not close instantly!
https://jsfiddle.net/5sxvsu8w/
I had to change the jQUery code as follows:
$(document).ready(function(){
var timer;
$('ul> li').hover(function() {
clearTimeout(timer);
$(this).find('ul').slideDown('fast');
}, function() {
var list = $(this).find('ul');
timer= setTimeout(function() {
list.slideUp('fast');
}, 2000);
});
});
However, the infinite loop problem remains.
The solution you found in here is usefull, this javascript code maybe can help:
$(document).ready(function(){
$('.menu li').hover(
function () {
$('.sub', this).stop().slideDown(650);
},
function () {
$('.sub', this).stop().slideUp(650);
}
);
});
/*$('ul >li').hover(function() {
clearTimeout($(this).data('timeout'));
$('li > ul').slideDown('fast');
}, function() {
var t = setTimeout(function() {
$('li > ul').slideUp('fast');
}, 650);
$(this).data('timeout', t);
});*/
li{
list-style-type:none;
display: inline-block;
position: relative;
padding: 20px;
background-color: #08c;
}
li ul li{
min-width:200px;
}
li ul{
margin:0;
padding:0;
position: absolute;
top: 100%;
left:0;
display: none;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>
<ul class="menu">
<li>Page A</li>
<li>Page B
<ul class="sub">
<li>Dropdown</li>
<li>Dropdown</li>
</ul>
</li>
</ul>
EDIT: I have changed my javascript code after some reseach; this solution unfortunately does not solve completely the first problem (it is still based on a timer) but avoids the infinite loop.

Problems creating sidebar toggle dropdown menu

I'm working on http://www.variied.com/market/men/. I'm trying to create a toggle dropdown menu on the sidebar that is triggered when someone hits the "Tops" link on the sidebar, which will then toggle the content in the sub-menu to be displayed. Here's my current code
<style>
ul.category ul.sub-menu ul.sub-menu li a{
display:none
}
</style>
<script>
jQuery(document).ready(function() {
jQuery("#menu-item-746").click(function() {
jQuery(this).next("ul.category ul.sub-menu ul.sub-menu li a").toggle();
return false;
});
});
</script>
There are a few issues in this fiddle:
You have a class called #submenu it should just be submenu
You're passing the event so you can use e.preventDefault() (unless you prefer return false)
I would suggest setting the subnav ul to display: none and just toggling that and I would use slideToggle for a nicer effect.
JS
$("#menu-item-746").click(function(e) {
e.preventDefault();
$(this).next("ul").slideToggle();
});
HTML
<ul class="submenu">
<li id="menu-item-746">Test Item</li>
<ul>
<li>Test1</li>
<li>Test2</li>
</ul>
</ul>
CSS
.submenu ul{
display: none;
}
FIDDLE
UPDATE
I looked at your HTML on your site and it appears that your ul subnav is a child of your li not a sibling (it was a sibling in your fiddle). Try this:
$(this).find("ul").slideToggle();
Also from the code you have provided you are targeting an id which means this would only work for that 1 element. It appears the ones with a subnav have a class called .menu-item-has-children so I would target that, like so:
$(".sub-menu .menu-item-has-children").click(function(e) {
e.preventDefault();
$(this).find("ul.sub-menu").slideToggle();
});
NEW UPDATE
Target the a instead then:
$(".sub-menu .menu-item-has-children").on("click", " a:first", function(e) {
e.preventDefault();
$(this).siblings("ul.sub-menu").slideToggle();
});

Categories