jQuery Animated List - Cant click nested items - javascript

I'm trying to create an animated nested list using jQuery Animations but I'm not sure what the best way to go about solving this problem is.
The way I've been doing this is by changing the length of the parent list-item and then making the nested list items visible.
The problem is that the length of the parent list item covers the nested list-items. I want to be able to click on a nested list item (such as Edit Profile, Add Music, Playlists, etc) and have it perform something else. For now, I'm trying to just get alerts to prompt to the screen for testing.
HTML
<div id="sidebar-menu" class="col-md-12">
<ul>
<li class="sidebar-menu-item" data-length="2"><span id="IWantToClickHere">Profile</span>
<ul class="blue-special sublist">
<li>Edit Profile</li>
<li>Other</li>
</ul>
</li>
<li class="sidebar-menu-item" data-length="2">Library [<span class="purple-special">3537</span>]
<ul class="blue-special sublist">
<li>Add Music</li>
<li>Playlists</li>
</ul>
</li>
<li class="sidebar-menu-item" data-length="0">Friends</li>
<li class="sidebar-menu-item" data-length="0">Stations</li>
<li></li>
<li class="sidebar-menu-item" data-length="0">Settings</li>
<li class="sidebar-menu-item" data-length="0">Logout</li>
</ul>
</div>
JS
$(document).ready(function() {
$('.sidebar-menu-item').click(function() {
//When: Menu is opened,
if ($(this).hasClass('opened-menu-item')) {
$(this).removeClass('opened-menu-item');
//Reset Menu-Item to default height of 20px per menu-item
$(this).animate({
height: "20px"
},
1000,
//Hide nested content
function() {
$(this).find('.sublist').css('display', 'none');
});
} else {
//When: Menu is closed
$(this).addClass('opened-menu-item');
$(this).find('.sublist').css('display', 'inherit');
//Set Menu-Item length to be the number of nested li * 35
var animateHeight = Number($(this).data("length")) * 35;
if (animateHeight != 0) {
$(this).animate({
height: animateHeight + "px"
},
1000);
}
}
});
});
I put together a simple jsfiddle here: http://jsfiddle.net/W4Km8/8065/

Use event.stopPropagation()
http://jsfiddle.net/W4Km8/8066/
$('.blue-special.sublist').click(function(e){
alert('click');
e.stopPropagation();
})
This prevents the click event from "bubbling" up to the parent. Without this function, an alert would fire, but the parent list would also close.

Related

jquery how can i return a moved unordered list item back to its original position in the list?

so im working on a mobile menu and what i want to have happen is for the user to click on a list item and have that item move to the top of the list, then when the user clicks another item it moves the first item back to its original position and the second item up into the first position.
so im stuck on the second part and im not sure how to execute it. i've tried storing the list in an array and adding and removing items with splice, but i couldn't get it to work properly, any help would be great thanks.
$(".article-featured__navigation-menu-mobile li").click(function(){
var item = $(this).addClass('active-state');
$(".article-featured__navigation-menu-mobile").prepend(item);
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<ul>
<li class="menu-item active-state"><a href="#" class="tax-filter" >0</a></li>
<li class="menu-item">1 </li>
<li class="menu-item">2 </li>
<li class="menu-item">3 </li>
<li class="menu-item">4 </li>
</ul>
You can do it with the Flexbox and take advantage of the order property which specifies the layout order of flex-items inside flex-containers. In other words, you can manipulate element's order regardless of the their position in the DOM.
I've also made some corrections to jQuery to give you the desired result:
$("ul li").click(function(){
$(this).addClass('active-state').siblings().removeClass('active-state');
});
ul {
display: flex; /* displays flex-items (children) inline */
flex-direction: column; /* stacks them vertically (assuming the mobile menu layout) */
list-style: none;
}
.active-state {
order: -1; /* the initial value of the order property is set to 0, i gave it -1 because of the changed direction, otherwise it would have been 1, i.e. place it above the others because of the higher value */
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<ul>
<li class="menu-item"><a href="#" class="tax-filter" >Link 0</a></li>
<li class="menu-item">Link 1 </li>
<li class="menu-item">Link 2 </li>
<li class="menu-item">Link 3 </li>
<li class="menu-item">Link 4 </li>
</ul>

After link's first click, make link unclickable, wait for transition end + 1s, then make link clickable again

I have a main menu.
The sub-menu opens when the link of any of the PARENT <li> that have children is clicked.
At this point, a class moves-out is added to the main menu and a CSS transition is started.
After the transition ends, the sub-menu is displayed.
The sub-menu contains the clicked <li> (if clicked again will take us back to the main menu) and it's children.
Here, my goal is to disable the click event on the parent <li> for 1 second,
then after this 1 second give it back the ability to be clicked so we can go back to the main menu.
An example of the navigation would be :
<ul class="main-nav">
<li>Home</li>
<li>Blog</li>
<li>About</li>
<li>Contact</li>
<li>
<span>PARENT</span>
<ul>
<li>Child 1</li>
<li>Child 2</li>
<li>Child 3</li>
And so on...
</ul>
</li>
</ul> <!-- .main-nav -->
The only way that worked for me was to hide/show the PARENT when the main menu has the moves-out class added to it like so :
$('.subnav-trigger').on('click', function(event) {
event.preventDefault();
if ($('.main-nav').hasClass('moves-out')) {
var $this = $(this);
$this.hide();
setTimeout(function(){
$this.show();
}, 1000);
}
}
I've tried A LOT off things, this is the only one that is near to my goal.
Instead off $this.hide(), $this.off('click') is working
but inside the setTimeout what ever I do to regain the click doesn't work.
Any help would be greatly appreciated.
NOTE : I want this to prevent fast click/re-click. Don't forget the transition ;)
Thanks again in advance for any help.
SYA :)
Try setting pointer-events on the li tag and resetting it after 1 second.
$('.subnav-trigger').on('click', function(event) {
event.preventDefault();
var $this = $(this);
$this.parent().css("pointer-events","none");
if ($('.main-nav').hasClass('moves-out')) {
$this.hide();
setTimeout(function(){
$this.show();
$this.parent().css("pointer-events","auto");
}, 1000);
}
});
Here's a way using a recursive function that enabled the click handler, disables it on click, enables the transitionend event, adds your class that enables the transition, then re-enables the function. Enabled a 3s transition to slow it down for the example.
var $lis = $('li'),
clicker = function() {
$lis.on('click', function() {
$lis.off('click');
$(this).on('transitionend', function() {
clicker();
}).addClass('color');
});
}
clicker();
li {
transition: background 3s;
}
li.color {
background: red;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<ul class="main-nav">
<li>Home</li>
<li>Blog</li>
<li>About</li>
<li>Contact</li>
</ul>
More like a debounce problem, you might want to take a look at it if you have not used it before, it will help a lot in design you code.
For the following example, I added moves-out to ul for testing, you can check the console.log to see the result. To use in your app don't forgot to remove it (moves-out) from the <ul...>
<ul class="main-nav moves-out">
function debounce() {
if ($('.main-nav').hasClass('moves-out')) {
console.log("Clicked - click event Disabled..");
$(this).off('click');
setTimeout(function() {
$(".subnav-trigger").on('click', debounce);
console.log("click event enabled!");
}.bind(this), 1000);
}
};
$(".subnav-trigger").on('click', debounce);
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.9.1/jquery.min.js"></script>
<ul class="main-nav moves-out">
<li>Home</li>
<li>Blog</li>
<li>About</li>
<li>Contact</li>
<li>
<span>PARENT</span>
<ul>
<li>Child 1</li>
<li>Child 2</li>
<li>Child 3</li>
And so on...
</ul>
</li>
</ul>
<!-- .main-nav -->

List element needs to be clicked twice when checking if it has a class

made a basic list with the option to click the items and then it would show the next ul.
This works, but when there is already a list shown, and you try to click on another heading you need to click that heading twice before it shows the related ul.
An example is this fiddle: http://jsfiddle.net/yu8ac6g7/
By default, the extra lists are hidden. To replicate my issue:
click on the first item so the next ul is shown
then click on the second so the first ul is hidden and the second is shown.
Now, if you try to click on the first item nothing happens. You have to click the item again before the jQuery action happens. This will be the same until you reload the page.
Any help / a better way of doing what I am trying?
Backup code:
$(".expanding_mobile_tab").on('click', function () {
if ($(this).hasClass('mobile_tab_closed')) {
$(this).removeClass('mobile_tab_closed').addClass('mobile_tab_open');
$(".features_mobile_details_tab").hide();
$(this).next('ul').fadeToggle();
$('html,body').animate({
scrollTop: $(".mobile_detail_tabs").offset().top
}, 800);
} else {
$(this).removeClass('mobile_tab_open').addClass('mobile_tab_closed');
$(this).next('ul').fadeOut();
console.log('close');
}
});
<div class="mobile_detail_tabs count_detail_tabs_1 only_mobile">
<ul>
<li class="expanding_mobile_tab mobile_tab_closed"><a class="mobile_smoothscroll">Features <i class="fa fa-plus-circle"></i></a>
</li>
<ul class="features_mobile_details_tab">
<li><span>Registration</span> <b>FFF FFFF</b>
</li>
<li><span>Colour</span> <b>Black</b>
</li>
<li><span>Year</span> <b>2013</b>
</li>
<li><span>Fuel Type</span> <b>Diesel</b>
</li>
<li><span>Mileage</span> <b>16336</b>
</li>
<li><span>Combined MPG</span> <b>62.80</b>
</li>
<li><span>Transmission</span> <b>Automatic</b>
</li>
<li><span>Tax Band</span> <b>C</b>
</li>
<li><span>Engine Size (cc)</span> <b>1,995</b>
</li>
<li><span>CO2 (g/km)</span> <b>118</b>
</li>
<li><span>Body Style</span> <b>2</b>
</li>
<li><span>4 Wheel Drive</span> <b>No</b>
</li>
</ul>
<li class='expanding_mobile_tab mobile_tab_closed'><a class='mobile_smoothscroll'>Spec Check <i class='fa fa-plus-circle'></i></a>
</li>
<ul class='features_mobile_details_tab'>
<li class='HPI_spec_list_item'>Armrest front, sliding : £140</li>
<li class='HPI_spec_list_item'>Automatic transmission : £1550</li>
<li class='HPI_spec_list_item'>Centre armrest for rear seats : £75</li>
<li class='HPI_spec_list_item'>Enhanced Bluetooth telephone preparation with USB audio interface and Voice Control : £430</li>
<li class='HPI_spec_list_item'>Exterior mirrors - folding, auto dimming : £300</li>
<li class='HPI_spec_list_item'>Media package - BMW Business : £990</li>
<li class='HPI_spec_list_item'>Metallic paint : £645</li>
<li class='HPI_spec_list_item'>Seat heating for driver and front passenger : £325</li>
<li class='HPI_spec_list_item'>Sun protection glass : £265</li>
</ul>
</ul>
You can simply do it as follows:
$(".expanding_mobile_tab").on('click', function () {
$('.expanding_mobile_tab').toggleClass('mobile_tab_closed')
.toggleClass('.mobile_tab_open');
$(".features_mobile_details_tab").not($(this).next()).hide();
$(this).next('ul').fadeToggle();
$('html,body').animate({
scrollTop: $(".mobile_detail_tabs").offset().top
}, 800);
});
Updated Fiddle
That is because clicked element does not have the required class used in if condition. You can rather check for visibility of next ul element to make show/hide decision :
$(".expanding_mobile_tab").on('click', function () {
if (! $(this).next('ul').is(':visible')) {
$(this).removeClass('mobile_tab_closed').addClass('mobile_tab_open');
$(".features_mobile_details_tab").hide();
$(this).next('ul').fadeToggle();
$('html,body').animate({
scrollTop: $(".mobile_detail_tabs").offset().top
}, 800);
} else {
$(this).removeClass('mobile_tab_open').addClass('mobile_tab_closed');
$(this).next('ul').fadeOut();
console.log('close');
}});
Working Demo
try this
Fiddle
$(".expanding_mobile_tab").on('click', function () {
if ($(this).hasClass('mobile_tab_closed')) {
$(".mobile_tab_open").removeClass('mobile_tab_open').addClass('mobile_tab_closed');
$(this).removeClass('mobile_tab_closed').addClass('mobile_tab_open');
$(".features_mobile_details_tab").hide();
$(this).next('ul').fadeToggle();
$('html,body').animate({
scrollTop: $(".mobile_detail_tabs").offset().top
}, 800);
} else {
$(this).removeClass('mobile_tab_open').addClass('mobile_tab_closed');
$(this).next('ul').fadeOut();
console.log('close');
}
});

How do i .removeClass('active') for just one of my <li> elements with jQuery?

I am having some issues figure out how i can just remove a class ="active" from a just one of my lists.
I have a navigation bar:
<div class="container">
<ul class="nav">
<li class="active">Home</li>
<li>About</li>
<li>Contact</li>
</ul>
</div>
I also have a menu within Home:
<div class="container_2">
<ul>
<li class="left-main-list active">Subject 1</li>
<ul class="list-in-list">
<li>Sub subject 1</li>
<li>Sub subject 2</li>
</ul>
<li class="left-main-list>Subject 2</li>
<li class="left-main-list>Subject 3</li>
</ul>
</div>
While i browse my menu on the home page, i want to change the the active list items class to active when clicked, so i now have this jQuery code:
$(document).ready(function() {
$('li').click(function() {
$('li').removeClass('active');
$(this).addClass('active');
});
});
This works for my menu, the class change to the current one, but it also delete my navigation bars class, which i don't want. :)
I have tried something like:
$(document).ready(function() {
$('.left-main-list').click(function() {
$('.left-main-list li').removeClass('active');
$(this).addClass('active');
});
});
I've tried '.left-main-list li' & 'li.left-main-list' without any success.
Greatful for answer to this question, and i hope my question (this time) is more accurate than my previous ones. :)
/Bill
ps: Can a sub subject AND a main subject be active at the same time, and that sub subject's class of active, be removed if you for example click another sub subject, but the main item still have it's class of active?
While i browse my menu on the home page, i want to change the the
active list items class to active when clicked
You could just target the lis within the relevant div, similar to this:
$(document).ready(function() {
var $listItems = $('div.container_2 li');
$listItems.click(function() {
$listItems.removeClass('active');
$(this).addClass('active');
});
});
DEMO - target lis within .container_2 only
Can a sub subject AND a main subject be active at the same time, and
that sub subject's class of active, be removed if you for example
click another sub subject, but the main item still have it's class of
active?
Still targeting the container you could use jQuery's parent(), similar to this:
$(document).ready(function () {
$('div.container_2 li').click(function () {
var $this = $(this);
var $children = $this.parent().find('li');
$children.removeClass('active');
$this.addClass('active');
});
});
DEMO - Using parent() to allow active menu and sub-menu but not when main menu changes
I looked at the possibility of making this more dynamic to add activation of items going up the chain when switching between sub menus located within different main menu elements.
Fixing the HTML of the nested uls whereby your nested uls are inside lis instead of just inside the upper ul you can do a fully dynamic implementation.
Assume your HTML like this:
<div class="container">
<ul class="nav">
<li class="active">Home</li>
<li>About</li>
<li>Contact</li>
</ul>
</div>
<div class="container_2">
<ul>
<li class="left-main-list active">Subject 1
</li>
<li>
<ul class="list-in-list">
<li>Sub subject 1
</li>
<li>Sub subject 2
</li>
<li>
<ul class="list-in-list">
<li>Sub subject 1
</li>
<li>Sub subject 2
</li>
</ul>
</li>
</ul>
</li>
<li class="left-main-list">Subject 2
</li>
<li class="left-main-list">Subject 3
</li>
</ul>
</div>
Now, using the following script, you can also make parents of any sub menu items active when changing from a sub menu to another which is within another main menu item, similar to this:
$(document).ready(function () {
$('div.container_2 li>a').click(function () {
var $this = $(this);
var $relatedElements = $this.parents('ul').find('li');
if($this.hasClass('active')){
return;
}
$relatedElements.removeClass('active');
$this.parent('li').addClass('active');
var $parents = $this.parents('li');
$parents.each(function(){
$(this).not($this.parent()).prev().addClass('active');
});
});
});
DEMO - Chain-like activation
I think this should have all possible examples to get you started from here.
Hope this helps.
Try this:
$("li").click(function() {
$(this.parentNode).children("li").removeClass("active");
$(this).addClass("active");
});
This will affect only the siblings of the element you click on.
$('.left-main-list').click(function() {
$('.left-main-list').removeClass('active');
$(this).addClass('active');
});
I think what you're looking for is this:
$(document).ready(function() {
$('li').click(function() {
$('li.left-main-list').removeClass('active');
$(this).addClass('active');
});
});
How about
$('li').on ('click', function (){
$(this).addClass ('active').siblings ('li').removeClass ('active');
})

Show/hide content for menu sublink and close the content when click next new link

I'm looking for a solution, it must work in IE also, that I can have the content hidden and then when you click one of the menu items it shows the content. However, the content doesn't hide until a user clicks on the next link...
Please check this link
http://jsfiddle.net/varada/YLX9x/
you can use jquery hide() and show() functions for that.
Let the id of div that is to be hidden be hidden_div, let menu item be menu_item, next button be next,
Import the jquery.js
and write the ready function as below..
$(document).ready(function() {
$('#menu_item').click(function() {
$('#hidden_div').show();
});
$('#next').click(function() {
$('#hidden_div').hide();
});
});
or if you mean the content be visible till he click the next link on the menu item, add a class name say, menu_class to the menu items and write the code
$('.menu_class').click(function() {
$('#hidden_div').hide();
});
instead of $('#next').click(function()
if you have a menu like
<ul>
<li class='menu_class'>item 1</li>
<li id='menu_item' >item 2</li>
<li class='menu_class'>item 3</li>
</ul>
and the div
<div id='hidde_div' style='display:none'>
content
</div>
then if you click item 2 the div will get displayed. and if you click item 1 or item 3 it will get hidden. make sure you are using the code $('.menu_class').click(function() {
html:
<li class="main">Web
<ul>
<li>Designing</li>
<li>Development</li>
</ul>
</li>
<li class="main">IT
<ul>
<li>Sales & Service</li>
<li>CCTV</li>
<li>DVR</li>
</ul>
</li>
<li class="main">ITES
<ul>
<li>BPO</li>
<li>Online Portal</li>
<li>Online Marketing</li>
</ul>
</li>​
js:
$(document).ready(function(){
$('li ul:not(:first)').hide();
$('ul li').click(function(){
$(this).closest('.main').next().find('ul').show();
$(this).closest('ul').hide();
});
});​
http://jsfiddle.net/7QheB/

Categories