I made an click event for .menu li which has ul in it using $(".menu li:has(ul)"). It works but it also assigns the same event to .menu li ul li. I tried using e.stopPropagation();, e.PreventDefault(); and return false; inside function but that didn't worked at all. How to prevent that?
Here's the fiddle to show up actual problem.
jQuery I used:
$(".menu li:has(ul)").click(function() {
console.log('has ul');
if($(this).children("ul").is(':visible')){
$(this).children("ul").slideUp();
}else{
$(this).children("ul").slideDown();
}
});
Try this instead:
$('.menu a').click(function() {
var next=$(this).next();
if(next.prop('tagName')=='UL') {
if(next.is(':visible')){
next.slideUp();
}else{
next.slideDown();
}
}
});
It's Works now Fiddle you need to add return false on child UL
Related
I have a simple ol li based list which toggles when i click on parent item or child item. I want it to toggle only when parent item is clicked.
$("#expList > li").click(function () {
$(this).find("ol").slideToggle();
});
https://jsfiddle.net/k2jqqbbk/3/
I tried to target it with $("#expList ol li") but this is not working. I tried few other options which didn't work either.
You could use the event.target to check whether its closest li contains an ol, and only toggle if it does:
$('#expList > li').click(function(evt) {
if ($(evt.target).closest('li').has('ol').length) {
$(this).find("ol").slideToggle();
}
});
Here's a fiddle
You need to target the a tag. Because the ol is the next child, the find call has been replaced with a call to next:
$("#expList > li > a").click(function () {
$(this).next().slideToggle();
});
If you want the functionality to extend to children of children, just omit #expList from the selector:
$("li > a").click(function () {
$(this).next().slideToggle();
});
Fiddle
Try to add the following code :
$("#expList > li").click(function () {
$(this).find("ol").slideToggle();
});
$("#expList > li ol li").click(function () {
return false;
});
The click event bubbles up to ancestor elements. So the click is fired first against the second-level list items, then bubbles up to the first-level list items. This is why you're seeing the toggling happen.
All you need to do is stop the click event bubbling up the element chain from the second-level list items.
Add this to fix:
$("#expList ol li").click(function(e) {
e.stopPropagation();
});
Here's the example: https://jsfiddle.net/sxn5bg3x/
DEMO
What Iam trying to Achieve...
If the user clicks on 1st list item, - background is added
If the user AGAIN Clicks on same List Item - background should be removed
which is not happening. can someone plz look into this.. i tried toggleClass as well, but its not working..
Thanks!!
ageUrl = "";
$('.ageUrl li a').on('click', function(e){
e.preventDefault();
ageUrl = $(this).attr("href");
if($(this).hasClass('selectedBg')){
$('.ageUrl li, .ageUrl li a').removeClass('selectedBg');
}
else {
//$(this).addClass('selectedBg');
$('.ageUrl li, .ageUrl li a').removeClass('selectedBg');
$(this).closest('li').addClass('selectedBg');
//$(this).closest('li').toggleClass('selectedBg')
console.log(ageUrl);
}
});
$('.crossIconSel').on('click', function(){
alert('hi');
$('.ageUrl li, .ageUrl li a').removeClass('selectedBg, crossIconSel');
});
Demo Fiddle Try this one
$('.ageUrl li a').on('click', function(e){
e.preventDefault();
ageUrl = $(this).attr("href");
if($(this).parent('li').hasClass('selectedBg')){
$('.ageUrl li, .ageUrl li a').removeClass('selectedBg');
}
else {
//$(this).addClass('selectedBg');
$('.ageUrl li, .ageUrl li a').removeClass('selectedBg');
$(this).closest('li').addClass('selectedBg');
//$(this).closest('li').toggleClass('selectedBg')
console.log(ageUrl);
}
});
$('.crossIconSel').on('click', function(){
alert('hi');
$('.ageUrl li, .ageUrl li a').removeClass('selectedBg, crossIconSel');
});
Your if condition was wrong as you were checking on a element that it has class SelectedBg whereas you have applied the class on .closest(li):
Just make the if condition like this:
if ($(this).closest('li').hasClass('selectedBg')) {
$('.ageUrl li, .ageUrl li a').removeClass('selectedBg');
}
Working Demo
See if this works
Jquery
$('.ageUrl li a').on('click', function (e) {
e.preventDefault();
$('.ageUrl li a').not(this).removeClass('selectedBg');
if( $(this).hasClass('selectedBg')){
$(this).removeClass('selectedBg');
}
else{
$(this).addClass('selectedBg');
}
});
Working Code ->JSFIDDLE
I am not sure toggleClass is the best way to do this, but I have a accordion menu and I am attempting to alternate the icon/image on the right side from a RIGHT arrow to a DOWN arrow.
The first click on the 3 menu items shows the DOWN image (.icon-03) but when I switch between the accordion items it does not go back to the RIGHT arrow image/class (.icon-04).
thoughts?
/* Accordion */
$(document).ready(function () {
$('#accordionFAQ > li > a').click(function(e){
if ($(this).attr('class') != 'active'){
$('#accordionFAQ li ul').slideUp();
$(this).next().slideToggle();
$('#accordionFAQ li a').removeClass('active');
$(this).addClass('active');
//add down arrow
$('> span', this).toggleClass('icon-03 icon-04');
//prevent page reload
e.preventDefault();
}
});
});
Demo JS Fiddle: http://jsfiddle.net/957Fs/
First of all, $(this).attr('class') != 'active' is very inefficient (and possibly fails to work altogether), use $(this).hasClass('active') instead.
After your comment, I re-added the classes - the following should work:
$('#accordionFAQ > li > a').click(function(e){
if (! $(this).hasClass('active') ){
$('.active')
.find('span').toggleClass('icon-03 icon-04')
.end().removeClass('active')
.next().slideUp();
$(this).find('span').toggleClass('icon-03 icon-04')
.end().addClass('active')
.next().slideDown();
//prevent page reload
e.preventDefault();
}
});
When I look at the JSFiddle example it works for me, so I guess it's updated already. I'd like to make a suggestion though: it's perhaps a good idea to just toggle a class (e.g. 'is-active') on your list items and handle the rest with pure CSS. For example:
var $faq = $('#accordionFAQ');
$faq.on('click', '> li > a', function (event) {
$(this).parent().toggleClass('is-active');
});
In your CSS you could do something like this:
#accordionFAQ > li > a span {
// width, height etc
background-position: x y;
}
#accordionFAQ > li.is-active > a span {
background-position: x y;
}
Just an idea; hope it's helpfull.
/* Accordion */
$(document).ready(function () {
var accordionFAQ = $('#accordionFAQ');
// let's use jQuery's .on() rather than .click()
accordionFAQ.find('a').on({
click:function(e){
// prevent the default action
e.preventDefault();
// setup some variables
var that = $(this);
// close open ULs
accordionFAQ.find('ul').slideUp();
// remove .active from other controller
accordionFAQ.find('.active').removeClass('active');
// add .active to clicked controller and show UL
that.addClass('active').next().slideDown();
// remove .right from span
accordionFAQ.find('.right').removeClass('right');
// add .right to current controller's span
that.find('span').addClass('right');
}
});
});
Then, you can have span's default image be the left arrow. and when you add a .right class, it will override the default image with a right arrow using CSS.
hope this helps.
I want to add a class to the selected 'li' and at the same time, remove the class:selected from previous selected li element.
I have worked on it hours and still haven't got any luck. I also checked others questions, but their solutions don't work for me.
Help please....
<ul id='mainView' class='menu' style='float: left; clear: both;'>
<li>Patient</li>
<li>Recommendations</li>
</ul>
<script type="text/javascript">
$(document).ready(function () {
$('.menu ul a').on('click', function (event) {
$('.menu ul a.selected').className = '';
alert($(this).attr('id'));
$(this).attr('class') = 'selected';
});
});
// $('.menu li').on('click', function () {
// $('.menu li.selected').className = '';
// this.className = 'selected';
// });
</script>
Update:
I did put a inside li, but if I click on the li not the a inside of the li, the webpage does not redirect. That's the reason why I do it in a reversed way.
Update 2
The reason why the selected li does not get the "selected" class is because the whole webpage is redirected to a new page which has the same navigation bar.
So now the question is how to highlight the selected li(it was selected on the previous page) on the new webpage.
Inside an UL everybody (even a browser) is expecting to see a LI
so your HTML:
<ul>
<li>Patient</li>
<li>Recommendations</li>
</ul>
And your jQ:
$('ul li').click(function(){
$(this).addClass('selected').siblings().removeClass('selected');
});
Building web pages you should know how to treat LI elements. Simple, like dummy containers with minimal styling.
That means that you rather add a display:block ... float:left and other cool stuff to the <A> elements, than setting a padding there you go with your full-sized-clickable A elements.
Additionally (if you don't have time to play with CSS) to make a LI fully clickable use:
$('ul li').click(function(){
var goTo = $(this).find('a').attr('href');
window.location = goTo ;
// $(this).addClass('selected').siblings().removeClass('selected'); // than you don't need this :D
});
After the OP late edit - and to answer the question
After the pages refreshes to get which one is the active one use:
// ABSOLUTE PATH
var currentPage = window.location;
// RELATIVE PATH
// var currentPage = window.location.pathname;
$('li a[href="'+ currentPage +'"]').addClass('selected');
<script type="text/javascript">
$(document).ready(function () {
$('.menu ul a').on('click', function (event) {
$('.menu ul a.selected').removeClass('selected');
alert($(this).attr('id'));
$(this).addClass('selected')
});
});
</script>
Try addClass and removeClass, they're jQuery functions:
$(document).ready(function () {
$('.menu ul a').on('click', function (event) {
$('.menu ul a.selected').removeClass("selected");
$(this).addClass('selected');
});
});
I have a problem with jQuery selectors:
$("ul.questions li").not(".title, .content").click().live('click', function(){
$(".inspector").slideToggle();
if($(this).hasClass("selected")) {
$(this).removeClass("selected");
} else {
$(this).addClass("selected");
}
});
In that code it works if I remove .not(".title, .content"). but if I add it, it just doesn't gets the click. I use live because usually the elements are added through .append(), except some ones. This is an example: http://jsfiddle.net/88w8N/ . Basically I want to handle click on the li element, but not if it clicks on the .title and .content divs. What I'm doing wrong? Thanks!
You need to stop jQuery from triggering an event attached to the parent when the child is triggered.
You need to use jQuery's event.stopPropagation() function, which
Prevents the event from bubbling up the DOM tree, preventing any parent handlers from being notified of the event.
In your code specifically: http://jsfiddle.net/88w8N/21/
$("ul.questionssel li div, ul.questionsnosel li div").on('click', function(e) {
e.stopPropagation();
});
UPDATE
To fix your "live" issue, try the following modification: http://jsfiddle.net/88w8N/25/
$("ul.questionssel").on('click', 'li', function() {
//$(".inspector").slideToggle();
if($(this).hasClass("selected")) {
$(this).removeClass("selected");
} else {
$(this).addClass("selected");
}
});
$("ul.questionsnosel").on('click', 'li', function() {
//$(".inspector").slideToggle();
if($(this).hasClass("selected")) {
$(this).removeClass("selected");
} else {
$(this).addClass("selected");
}
});
$("ul.questionssel li div, ul.questionsnosel li div").on('click', function(e) {
e.stopPropagation();
});
You can use not selector instead of not function
http://api.jquery.com/not-selector/
Try :not("...") instead of .not("...")
please double-check these links:
http://api.jquery.com/attribute-not-equal-selector/
http://api.jquery.com/not-selector/
http://api.jquery.com/category/selectors/