on my Demo, I add and remove the class Selected. If I click through the links and then click again the
OPEN FORM the toggleClass doesn't work on a first click. why? what am I missing?
Basically by clicking OPEN FORM I should addClass('selected') and toggleClass('open') .
Please see my Demo, and click the links.
http://jsfiddle.net/y8oL13Ld/
my js:
$('.cta a').on('click', function (e) {
e.preventDefault();
$('.cta a').removeClass('selected');
$(this).addClass('selected');
if ($('.Contact-form.selected').is(':visible')) {
$('.cloned-contactform').addClass('open');
} else {
$('.cloned-contactform').removeClass('open');
}
$('.Contact-form.selected').bind('click', function () {
$('.cloned-contactform').toggleClass('open');
});
});
html:
<ul class="cta">
<li>OPEN FORM</li>
<li>LINK</li>
<li>LINK</li>
</ul>
<div class="cloned-contactform">
<div class="contactform"></div>
</div>
are you look for soemthing like this?: http://jsfiddle.net/y8oL13Ld/1/
$('.Contact-form').on('click', function() {
$('.cta a').removeClass('selected');
$(this).addClass('selected');
if ($('.cloned-contactform').is(':visible')) {
$('.cloned-contactform').removeClass('open');
$('.cloned-contactform').hide();
}
else {
$('.cloned-contactform').addClass('open');
$('.cloned-contactform').show();
}
});
explanation: the OP js is a little convoluted in the logic. although i'm not exactly sure exactly the functionality of what the OP wants, i ripped all unnecessary js and fulfilled the requirements that:
clicking OPEN FORUM adds the class selected to the anchor (and removes selected from other links if they have class selected)
the div cloned-contactform's class open gets toggled
the div cloned-contactform's visibility toggles
EDIT: due to the refined definition of requirements i updated the jsfiddle: http://jsfiddle.net/y8oL13Ld/2/
the following jquery handles the fact that if the other links are clicked, it closes the div cloned-contactform and are selected.
$('.Globe, .Search').on('click', function() {
$('.cta a').removeClass('selected');
$(this).addClass('selected');
$('.cloned-contactform').removeClass('open');
$('.cloned-contactform').hide();
});
FINAL EDIT: hopefully lol, due to scope change. http://jsfiddle.net/y8oL13Ld/4/
$('.cta a').on('click', function(){
// if clicked contact link
if ($(this).hasClass('contact')) {
// if already selected
if ($(this).hasClass('selected')) {
// toggle
$('.contact-div').removeClass('open');
$(this).removeClass('selected');
}
// if not already selected
else {
// remove selected and open classes from all others
$('.cta a').removeClass('selected');
$('.section').removeClass('open');
// apply selected and open classes to this
$('.contact-div').addClass('open');
$(this).addClass('selected');
}
}
});
and i switched the html structure a little:
<div class="contact-div section">contact div</div>
<div class="global-div section" style="background:gray;">global div</div>
<div class="search-div section" style="background:lightgray;"> search div</div>
Kinda guessing here, but it looks like you're making a nav and clicking a link in it shows a certain div. If that's what you're trying to achieve maybe some refactoring advice could be this:
Have a div for each of your sections
<div class="section contact-form">Form Stuff</div>
<div class="section globe">Globe Stuff</div>
<div class="section search">Search Stuff</div>
Then your links could be like:
<li>OPEN FORM</li>
<li>LINK</li>
<li>LINK</li>
Then your javascript code is ambiguous to which link you clicked:
$('a').click(function(){
// Grab the value of data-section
var selected = $(this).data('section')
$('.section').hide()
// Show the corresponding div
$("'."+ selected + "'").show()
});
http://jsfiddle.net/4brfejw5/
Related
I have a large area that I need to make clickable. Imagine I have a list of items:
<ul class="my-area">
<li>...</li>
<li>...</li>
</ul>
The items <li> have a lot of stuff inside including working links or links that trigger modal windows etc. As long as someone clicks on one of the links inside, it should do whatever it is designated to do - redirect, open modal window, etc. However, if the click was not on a link but just a <div>, <span> etc, then I need to redirect to a specific location.
I've tried this:
$("ul.my-area li:not(a)").click(function (event) {
location.href='SOME_LOCATION';
});
However, it's not working. I considered using .stopPropagation() as well but then the modal windows stop working so that's not an option. Any ideas?
edited: There is two posible solutions:First solution:event.stopPropagation() *(not an option for this specific question because of modals)*- this would look like:
$("ul.my-area li").on('click',function (event) {
//location.href='SOME_LOCATION';
});
$("ul.my-area li a").on('click',function(e){
e.stopPropagation();
});
Second solution: Since you have nested DIV, IMG... inside the anchors, here it is checking if clicked element is not an anchor or if it don't have any ancestor anchor, and inside you can change location.href/do some action:
$("ul.my-area li ").on('click', function(event) {
if (!((event.target.tagName == "A") || $(event.target).closest('a').length)) {
console.log("This is not an anchor");
//location.href='SOME_LOCATION';
}
else{ //it's an anchor }
});
Check the below snippet
$("ul.my-area li ").on('click', function(event) {
if (!((event.target.tagName == "A") || $(event.target).closest('a').length)) {
console.log("This is not an anchor");
//location.href='SOME_LOCATION';
}
else{ //it's an anchor }
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<ul class="my-area">
<li>
<p>This is Paragraf This is Anchor
</p>
<div>This is DIV</div>
</li>
<li>
<p>This is another Paragraf</p>
<a href="#">
<div>This Div inside Anchor<span> This is span inside div inside the anchor</span>
</div>
<img src="" alt="Image part of the anchor">
</a>
<p>Some paragraf</p>
</li>
</ul>
I have a JavaScript menu that I want to unfold/fold when I click on the #dropdown button. First, it took three clicks for it to unfold and after those three clicks, it worked perfectly fine.
I edited my code, I have to click it three times again for it to work, but after that, each click makes the menu fold/unfold three times in a row.
buttonClickHandler
function buttonClickHandler(e) {
e.preventDefault();
$(document).ready(function(){
$('#main').hide();
$('a#dropdown-button').click(function(){
$('#main').toggle(function(){
$('#main').addClass('active').fadeIn();
}, function(){
$('#main').removeClass('active').fadeOut();
return false;
});
});
});
}
Init
function init(){
var button = document.getElementById('dropdown-button');
button.addEventListener("click", buttonClickHandler, false);
}
window.addEventListener("load", init, false);
HTML
<section id="nav-bar">
<figure>
<span class="helper"></span><img src="img/Logo.png" alt="Zien Woningmarketing"/>
</figure>
<img src="img/Menu.png" alt="Menuknop: open het menu"/>
</section>
<nav id="main">
<ul id="firstLevel">
<li>Home</li>
<li>Producten</li>
<li>Woningmarketing</li>
<li>Over Zien!</li>
<li>Werkwijze</li>
</ul>
<ul>
<li class="login">Inloggen</li>
<li>Registreren</li>
</ul>
</nav>
Link to JSFiddle
The thing is that this menu should easily drop down, thus showing its contents.
Hope this help :
http://jsfiddle.net/x7xu4/2/
$(function(){
$("a#dropdown-button").on("click",function(event ){
$("#main").toggleClass('active').fadeToggle();
event.preventDefault();
});});
Since you are using jquery 2.1, instead of "click" use "on" for it saves a bit of memory, and I edited your code for a simpler solution.
I make simpler your code
$(function(){
$('a#dropdown-button').click(function(){
if(!$('#main').hasClass('active')){
$('#main').addClass('active');
$('#main').show();
}else {
$('#main').removeClass('active');
$('#main').hide();
}
return false;
});
});
Here is jsFiddle sample
I have this menu
<ul id="menu" class="clearfix">
<li>
Product 1
</li>
<li>
Product 2
</li>
<li>
Product 3
</li>
<li class="last">
Product 4
</li>
</ul>
I want to make this effect. when you enter the page the text color of the menu items are white. If you click on one item it becomes active (keeping the white color text) and all the other items change it's color to gray, also when you hover over one the affected items are all the others.
I have tried with the .addClass but I have only managed to add the active class to the current item, but not change the others that aren´t active after the first click.
Anyone know the best jquery approach to this?
$("#menu li").hover(function() {
$(this).removeClass('grey').siblings().addClass('grey');
}, function() {
$(this).addClass('grey').siblings('.active').removeClass('grey');
//
}).on('click', function() {
$(this).removeClass('grey').addClass('active').siblings().addClass('grey').removeClass('active')
});
http://jsfiddle.net/y7Cn5/
Perhaps something like this: Updated, with hover functionality
jsFiddle
$("#menu > li").on("click", function(e) {
e.stopPropagation();
$(".active").removeClass("active");
$(this).removeClass("non-active").addClass("active").siblings().addClass("non-active");
})
.hover(function(e) {
$(".non-hover").removeClass("non-hover");
$(this).addClass("hover").siblings().addClass("non-hover");
}, function(e) {
$(".hover, .non-hover").removeClass("hover non-hover");
})
and if this doesn't answer the question, then the question is not understood and needs some rewording, this is everything asked about in the question
Here you go (siblings) selects all OTHER items in the same node
$("#menu li").click(function(){
$(this).addClass("active").css("color","white")
$(this).siblings().css("color","gray")
})
Try
$("#menu > li").hover( function( ) {
$(this).removeClass("hovered").siblings().addClass("hovered");
}, function( ) {
$(this).addClass("hovered");
});
$("#menu > li").click( function( ) {
$(this).addClass("active").siblings().removeClass("active");
});
My 1st question on here so I'll try to be as concise as possible.
I have a series of nav elements, some of which have nav sub-elements. My basic structure is:
<nav role="navigation" class="primary-nav main-nav">
<ul>
<li>home</li>
<li class="about-item">about</li>
<li class="study-item">study</li>
<li class="apply-item">apply</li>
<li>people</li>
<li>shows</li>
<li>contact</li>
</ul>
</nav>
<!-- secondary navs -->
<!-- about -->
<nav role="navigation" class="sec-nav sec-nav-about">
<ul>
<li>history</li>
<li>facility</li>
<li>alumni</li>
<li>friends</li>
<li>patrons</li>
<li>singers</li>
</ul>
</nav>
<!-- study -->
<nav role="navigation" class="sec-nav sec-nav-study">
<ul>
<li>foundation</li>
<li class="study-undergrad-item">undergrad</li>
<li class="study-postgrad-item">postgrad</li>
<li>part time</li>
<li>exams</li>
<li>saturday school</li>
<li>sunday school</li>
<li>summer school</li>
</ul>
</nav>
<!-- apply -->
<nav role="navigation" class="sec-nav sec-nav-apply">
<ul>
<li>loans</li>
<li>auditions</li>
<li>fees</li>
<li>exams</li>
<li>saturday school</li>
<li>sunday school</li>
<li>summer school</li>
</ul>
</nav>
(I know these lists could - and should - be nested but this is code I've inherited rather than written myself and I don't want to screw with anything else that might be in the styles).
So - what I want is when the 3rd, 4th and 5th main-nav items are clicked, their corresponding submenu animates using margin-left.
I'm currently using jQuery .toggle() to try and achieve this effect. Here is my jQuery:
$(document).ready(function(){
$('.main-nav .about-item a').toggle (
function(){
$('.sec-nav-about').animate({marginLeft: "480"}, 500);
},
function(){
$('.sec-nav-about').animate({marginLeft: "-250"}, 500);
});
$('.main-nav .study-item a').toggle (
function(){
$('.sec-nav-study').animate({marginLeft: "480"}, 500);
},
function(){
$('.sec-nav-study').animate({marginLeft: "-250"}, 500);
});
$('.main-nav .apply-item a').toggle (
function(){
$('.sec-nav-apply').animate({marginLeft: "480"}, 500);
},
function(){
$('.sec-nav-apply').animate({marginLeft: "-250"}, 500);
});
});
Up to this point, its fine. However, I cannot get beyond this point. I have no idea how to re-work the code to achieve the following:
1) When each main menu item is clicked, if it has a sub-menu and if its not already showing, then the sub-menu animates out (this is working fine).
2) If a sub-menu is already showing, then when its main menu item is clicked then the sub menu animates back in until its not showing (this is also working).
3) If a sub menu is showing and another sub menu item is clicked, the first sub-menu animates back in until its not showing and the new sub-menu animates out. This not working.
I have attempted to add/remove an .active class to each sub-menu like so (just one here for illustrative purposes but all three sub-menus have this applied to them):
$('.main-nav .about-item a').toggle (
function(){
$('.active').animate({marginLeft: "-250"}, 500).removeClass('active');
$('.sec-nav-about').animate({marginLeft: "480"}, 500).addClass('active');
},
function(){
$('.sec-nav-about').animate({marginLeft: "-250"}, 500).removeClass('active');
});
});
Then what happens is that, it seems to work and then after awhile, it stops removing/adding the .active class. I double checked in Chrome's Element Inspector and can see it (not) happening. I need to click the links twice to get the toggle() to work and drive the animation.
Any ideas/suggestions/solutions would be very gratefully appreciated.
(edited for spelling errors).
Thanks,
Will Moore's answer explains why your current method doesn't work. The following should fix your problem. Using the regex on the className property means that we can apply this to all items in your list without having to set each one up individually.
Also, note that we query the 'sub menus to hide' before adding the .active class to the currently selected sub-menu; this avoids hiding it as soon as we show it.
$('.main-nav li').click(function() {
var itemType = this.className.match(/(^| )([^ ]+)-item( |$)/);
if(itemType != null) {
itemType = itemType[2];
}
$secNavItem = $('.sec-nav-' + itemType);
$subMenusToHide = $('.active');
if(!$secNavItem.hasClass('active')) {
$secNavItem
.addClass('active')
.animate({marginLeft: "480"}, 500);
}
$subMenusToHide
.animate({marginLeft: "-250"}, 500)
.removeClass('active');
});
You can see it working in this fiddle: http://jsfiddle.net/ET475/23/
When you click 'Study' it SHOWS the study submenu.
Then you click the 'About' and it HIDES the study menu (shows the about menu).
Now you click 'Study' again. This is only the second click on the study button, so it's going to do the opposite of the last time you clicked it: ie it's going to HIDE the study submenu when you want it to show the study menu.
This works for me:
$('.main-nav .about-item a').click (function(){
var $submenu = $('.sec-nav-about');
// if the submenu you want isn't showing...
if (!$submenu.hasClass('active')) {
// if any other submenu is showing, hide it...
if ($('.active').length > 0){
$('.active').animate({marginLeft: "-250"}, 500, function(){
// ...show submenu AFTER previous submenu is hidden
$submenu.animate({marginLeft: "480"}, 500).addClass('active');
}).removeClass('active');
} else {
// no submenus showing: simply display
$submenu.animate({marginLeft: "480"}, 500).addClass('active');
}
}
});
There are several advanced jQuery plugins which filter <div>s by corresponding id or class. This is indeed based on a simple jQuery idea, but I am not sure how to implement it. Consider a menu to show/hide the content as
<ul id="filters" class="menu" indicator="filter">
<li>All</li>
<li>First</li>
<li>Third</li>
</ul>
and we want to control the display of contents:
<div class="box first">Something</div>
<div class="box first third">Something</div>
<div class="box third">Something</div>
What is the simplest jQuery Javascript code to do so?
By default, all <div>s are shown, when we click on a <li> from menu (e.g. FIRST), jQuery will filter the <div>s to only show <div>s in which the class is "first".
Don't use attribute "indicator" as it doesn't exist. Use the class element as below. Also the A elements are not needed.
<ul id="filters" class="menu">
<li class="selected all">All</li>
<li class="first">First</li>
<li class="third">Third</li>
</ul>
Then your script
// hide all divs
$('div.box').css('display','hidden');
// add click handler on control list
$('ul#filters li').click(function() {
var classList =$(this).attr('class').split(/\s+/);
$.each( classList, function(index, item){
if (item != 'selected') {
$('div.'+item).css('display','block');
}
});
});
$(function(){
$('#filters li a').live('click', function(){
$('.box').hide();
indirector = $(this).attr('indicator');
indirector = indirector.substring(1);
if(indirector == '')
$('.box').show();
else
$('div.' + indirector).show();
});
});
Reference
Use the class attribute instead of indicator and try the following:
$('#filters li').click(function(){
$('div.' + $(this).attr('class')).show();
});
for this to work you would have to assign an all class to your first LI as well as all of your DIVs. Hope this helps!
try this code,
$('#filters li').click(function(){
$("div.box").hide();
$('div.box' + $(this).children('a').attr('indicator')).show();
});