jQuery fade in active element, fade out inactive elements - javascript

Update
Using:
$(event.currentTarget).fadeTo(0, 1);
Seems to work, while using:
$('.btn .active').fadeTo(0, 1);
Does not. Any idea why?
The Code
jsFiddle link here: http://jsfiddle.net/SeanKilleen/fwerK/
JavasScript code below:
var global_loggedOnUser = "User1";
$(document).ready(function () {
var viewmodel = (function () {
this.feedbacktype = ko.observable("None");
this.currentPage = ko.observable(location.href);
this.currentUsername = global_loggedOnUser;
this.updateFeedbackType = function (item, event) {
var newText = $(event.currentTarget).children("span").text();
$('#buttonList button').removeClass('active');
$(event.currentTarget).addClass('active');
feedbacktype(newText);
$('.btn').not('.active').fadeTo('fast', 0.3);
$('.btn .active').fadeTo('fast', 1);
};
return {
pageUserIsOn: currentPage,
theUser: currentUsername,
feedbackType: feedbacktype
};
})();
ko.applyBindings(viewmodel);
});
The Goal
I have a list of buttons.
When someone clicks on the button, I want to ensure the button they click on becomes 100% opacity, and the rest of the buttons become 30% capacity.
I'm trying to accomplish this by adding an "active" class to the button and removing it from all others, and then performing the fade based on class.
The Issue
The first click, it works as expected. The clicked button is at 100% opacity and all others fade.
The second time, the previously highlighted element fades, but the clicked button doesn't become 100% opacity, despite being given the "active" css class.
I added a border-size element to the active class so I could verify this. The clicked item expands its border, but does not fade to 100% opacity.
What am I missing?

Remove the space between the classes, you want to select elements with both classes not .active descendants of .btn
$('.btn .active').fadeTo('fast', 1);
should be
$('.btn.active').fadeTo('fast', 1);
Updated fiddle

Related

jquery show hide not working properly

I've made an animation which fades in and out.
I have two buttons $('.point li') to show two different contents $("#"+classVal+" .table-cell")
However, when I click $('.point li'), I'd like to gradually show its content from white background.
But its opacity remained when I click another button and click back.
Is there a way to show the content from zero opacity every time I click the button?
var q = $('#intro .table-cell'); //this is a first content to show
var qIndex;
$(window).ready(function(){
$('.point li').click(function(){ //click a button
$('.point li').removeClass('active');
var classVal = $(this).attr('class');
$(this).addClass('active');
q.stop(true,false);
$('.bg > div').css('display','none');
$('.bg > div .table-cell').css('display','none');
$('#'+classVal).css('display','block');
q = $("#"+classVal+" .table-cell");
qIndex = -1;
showNextQ();
});
});
function showNextQ() {
++qIndex;
q.eq(qIndex % q.length).show(2000).delay(1000).hide(2000, function(){
showNextQ();
});
}
I found a solution.
The reason why the animation's attributes remained is that JQuery store it to a variable.
So I change the second parameter in a function "stop"
q.stop(true,false);
to True
q.stop(true,true);
which means "jump to end"
Than it works

Reinstate hover rules after click

I am using the below script to hide/show my main nav menu items. You can see it live here: http://205.134.239.12/~artscr6/artscrush/#!
One part of my menu uses down arrows (represented using font awesome with the <i> tags) and when the user hovers over the menu item, the arrow appears. This works in the initial state, but once the user clicks one of the menu items to show the flyout, the hover effect no longer works to show the arrows.
What would I need to add to keep that hover effect happening, but still keep the current behavior as well?
/Remove the link elements from the main nav top level
$('.menuItem a').attr('href', '#!');
//Show the down arrows on hover
$('menuItem').hover(function() {
$(this).find('i').css('opacity', '1');
})
//Once menu is clicked
$('.menuItem').click(function() {
//Reset
menuReset();
//Find the correct flyout
var item = $(this).attr('id');
var id = item.substring(item.indexOf("_") + 1);
var findFlyout = '#acFly_' + id;
//Make this item active
$(this).addClass('active');
//Bumps the current down arrow down a bit and shows it
$(this).find('i').css('opacity', '1');
$(this).find('i').css('top', '7px');
//Show the flyout
event.stopPropagation(); //This prevents dom from overriding us
$(findFlyout).toggle();
//Prevent clicks on the current menu from hiding the flyout
$(findFlyout).click(function(){
event.stopPropagation();
})
})
//Hide the menu when the user clicks anywhere
$(document).click( function(){
menuReset();
})
function menuReset() {
$('.flyMenu').hide();
//Resets the down arrows to orig position and hidden
$('.menuItem').find('i').css('opacity', '0');
$('.menuItem').find('i').css('top', '0px');
$('.menuItem').removeClass('active');
}
//Show the down arrows on hover
$('menuItem').hover(function() { // Shouldn't this be .menuItem instead?
$(this).find('i').css('opacity', '1');
})
Also, in the css file on the link you gave me I find the following:
#menu .ul .li:hover i{
opacity: 1;
}
I don't think ul and li are classes, so why is there a . ?
EDIT: Oh, I see now. You named your divs ul and li. :)

Toggling Background Color on Click with Javascript

I am working on a class project and need to be able to toggle the background color of a transparent png on click. I have been working through a number of examples from the site, but I can't get it working. I am a total novice at Javascript and haven't had luck trying to plug in jQuery code either.
Here is the targeted section:
<div class="expenseIcon"><a href="#">
<img src="images/mortgage.png"></a><br/>
<p>Rent or Mortgage</p>
</div>
On clicking the linked image, the goal is for the background on the image to change to green. Clicking it again would change it back to the default, white. Here's the CSS I'd like to toggle on/off with click.
.colorToggle {
background: #A6D785;
}
I had tried adding class="iconLink" to the href and class="iconBox" to the image with the following Javascript adapted from another post, but it didn't work.
var obj = {};
$(document).ready(function () {
$(".iconLink").click(function () {
var text = $(this).find(".iconBox");
obj.var1 = text;
//alert(obj.var1);
//return false;
$('.iconBox').removeClass('colorToggle');
$(this).addClass('colorToggle')
});
});
Any advice would be greatly appreciated!
Let's break down what is happening with your current code when you click the link.
var obj = {};
$(document).ready(function () {
$(".iconLink").click(function () {
var text = $(this).find(".iconBox");
obj.var1 = text;
$('.iconBox').removeClass('colorToggle');
$(this).addClass('colorToggle')
});
});
JQuery finds all elements with the classname "iconBox". In your case, this is the img element. The reference to that element is then saved in "obj.var1". You do not end up doing anything with this reference, so these two lines can be removed.
All elements with the class "iconBox" have the class "colorToggle" removed. Your img element didn't have this class on it, so nothing happens.
The class "colorToggle" is added to the anchor element. Yes! Now the element wrapping the img has a background color.
Unfortunately, clicking the anchor tag again won't do anything, since the anchor tag will already have the "colorToggle" class and all we would be doing would be trying to add it again. Hmm. Let's try changing addClass to toggleClass. Here's our new code:
$(document).ready(function () {
$(".iconLink").click(function () {
$(this).toggleClass('colorToggle');
}
});
Also, note that because we're working with the anchor element, the p element won't be affected by this change. If you want the entire div to change background colors, use this line instead:
$(".expenseIcon").toggleClass('colorToggle');
Using the given markup:
<!-- to toggle the bg-color onClick of anchor tag -->
<div class="expenseIcon">
<a href="#">
<img src="images/mortgage.png">
</a>
<br/>
<p>Rent or Mortgage</p>
</div>
since the question asks for javascript, heres an option for updating the background-color of an element using the built-in js.style method
//get a handle on the link
//only one element w/ className 'expenseIcon'
//first child of 'expenseIcon' is the anchor tag
var link = document.getElementsByClassName('expenseIcon')[0].children[0];
//get a handle on the image
var image = link.children[0];
//listen for click on link & call bgUpdate()
link.addEventListener('click', bgUpdate, false);
function bgUpdate() {
if(image.style.backgroundColor === 'lightgoldenrodyellow'){
image.style.backgroundColor = 'aliceblue';
} else if (image.style.backgroundColor === 'aliceblue') {
image.style.backgroundColor = 'lightgoldenrodyellow';
}
else console.log('image bgColor: ' + image.style.backgroundColor);
}
a similar example
css
.expenseIcon{
background: red;
}
.colorToggle {
background: blue;
}
jquery
$(".expenseIcon").click(function () {
$('.expenseIcon').toggleClass('colorToggle');
});
By default, the div will have expenseIcon background. ToggleClass will toggle the div class with colorToggle so will override the previous color.
You don't need an hyperlink tag A to manage clicks, just put it on the DIV.

jQuery Accordion | Open first element on pageload & active state confusion

I am using the Javascript below to animate an accordion (it's a slightly modified variant of the one explained here: http://tympanus.net/codrops/2010/04/26/elegant-accordion-with-jquery-and-css3/.
Now I wanted to have the first element to be open on pageload, so I figured I just give it some sort of extra-class via Javascript (and define that .active state via CSS) to have it open up.
This worked, however if I hover over any but the first-element with said .active class, the first element keeps its state, and stays open until I hover over it at least once.
So, what I want is: the first element of my accordion is open and collapses if the user hovers over any of the elements that are not the first. I think I need to add a line in the hover function to either take the class away of the first element or to give the new element the active state, but I don't know how to do it and keep breaking the thing.
<script type="text/javascript">
jQuery(function() {
activeItem = jQuery("#accordion li:first");
jQuery(activeItem).addClass('active');
jQuery('#accordion > li, #accordion > li.heading').hover(
function () {
var jQuerythis = jQuery(this);
jQuerythis.stop().animate({'height':'280px'},500);
jQuery('.heading',jQuerythis).stop(true,true).fadeOut();
jQuery('.bgDescription',jQuerythis).stop(true,true).slideDown(500);
jQuery('.description',jQuerythis).stop(true,true).fadeIn();
},
function () {
var jQuerythis = jQuery(this);
jQuerythis.stop().animate({'height':'40px'},1000);
jQuery('.heading',jQuerythis).stop(true,true).fadeIn();
jQuery('.description',jQuerythis).stop(true,true).fadeOut(500);
jQuery('.bgDescription',jQuerythis).stop(true,true).slideUp(700);
}
);
});
</script>
Looks like this is happening because each accordion item has its own hover event that takes care of its own animation. You can refactor the code slightly to make this easier to understand and reuse:
var activeItem = jQuery("#accordion li:first");
jQuery('#accordion > li, #accordion > li.heading').hover(
function () { hoverMe(jQuery(this)); },
function () { unhoverMe(jQuery(this)); }
);
//This gets called when cursor hovers over any accordion item
var hoverMe = function(jQuerythis) {
//If the first item is still active
if (activeItem) {
contract(activeItem); //...Shrink it!
activeItem = false;
}
//Expand the accordion item
expand(jQuerythis);
};
//This gets called when cursor moves out of accordion item
var unhoverMe = function(jQuerythis) {
contract(jQuerythis);
};
//I have moved the hover animation out into a separate function, so we can call it on page load
var expand = function(jQuerythis) {
jQuerythis.stop().animate({'height':'280px'},500);
jQuery('.heading',jQuerythis).stop(true,true).fadeOut();
jQuery('.bgDescription',jQuerythis).stop(true,true).slideDown(500);
jQuery('.description',jQuerythis).stop(true,true).fadeIn();
};
//I have moved the unhover animation out into a separate function, so we can contract the first active item from hoverMe()
var contract = function() {
jQuerythis.stop().animate({'height':'40px'},1000);
jQuery('.heading',jQuerythis).stop(true,true).fadeIn();
jQuery('.description',jQuerythis).stop(true,true).fadeOut(500);
jQuery('.bgDescription',jQuerythis).stop(true,true).slideUp(700);
};
//Now expand the first item
expand(activeItem);
I have put together a simplified version demonstrating the logic. Please let me know how you get on.

Problem with a jQuery script that sets an active element on hover and animation callbacks

I am working on a site in which there are a series of elements, and only one of them must be active at any time. When that element is active, a 'Details' div is shown.
These elements become active when you hover on them, but as I said, only one of them can be active at the same time. I am currently setting the active element with an active class.
In my current code, this is what happens when a user hovers on any of the elements:
The previous active element gets the class 'active' removed , and is fadeOut
On the fadeOut callback, the hovered element becomes active (gets the class 'active'), and is fadeIn
If there is no current active element, the hovered element becomes active (class 'active') and is fadeIn
This works out OK, but when you hover very quickly between elements, there is a brief moment where no element is active, so more than element gets the active class and is shown.
How would you approach this problem?
Here is my code:
function setActive(selected) {
//stores the active element in a variable
active = selected;
//checks if there are currently elements with the 'active' class in the DOM
if ( $('#info article.active').length > 0) {
//if there is any currently active element, and its element_id attribute is not the one stored in the active variable
//it gets the 'active' class removed, its hidden, and in the callback of the animation
//the newly selected element gets the class 'active' and is shown with fadeIn
$('#info article.active[element_id!="' + selected + '"]').removeClass('active').fadeOut('fast', function(){
$('#info article[element_id="' + selected +'"]').addClass('active').fadeIn('normal');
});
} else {
//if there is no current active element, the newly selected one is applied the class active, and shown with fadeIn
$('#info article[element_id="' + selected +'"]').addClass('active').fadeIn('normal');
}
}
Stray (mis)firings on mouse flyovers, and/or finicky targets is a common problem. The standard solution is to have a small delay before a hover "sticks".
Important: The question did not show how setActive() was being called!
But if you structure the HTML something like this:
<div id="flyOverControls">
<ul>
<li rel="Article_1">Show 111</li>
<li rel="Article_2">Show 222</li>
<li rel="Article_3">Show 333</li>
<li rel="Article_4">Show 444</li>
</ul>
</div>
<div id="info">
<article id="Article_1">First article.</article>
<article id="Article_2">Second article.</article>
<article id="Article_3">Third article.</article>
<article id="Article_4">Fourth article.</article>
</div>
Then activate the controls like this:
$("#flyOverControls li").hover (function (zEvent) {setActiveArticle (zEvent); } );
Then this code should do the trick. Adjust speeds to taste. Personally, I'd kill that fade-out.
function setActiveArticle (zEvent)
{
var dDelay;
var ActionFunction = null;
var targetID = $(zEvent.currentTarget).attr ('rel');
if (zEvent.type == 'mouseenter')
{
//--- Hovering over a new article control... Pause for an ergo delay.
dDelay = 300;
ActionFunction = function (targetID, context) {
//--- If we are setting the same article, then nothing needs be done here.
if ( ! (context.lastArticle && context.lastArticle == targetID) ) {
//checks if there are currently elements with the 'active' class in the DOM
if ( $('#info article.active').length > 0) {
/* If there is any currently active element, and its element_id attribute is not the one stored in the
active variable it gets the 'active' class removed, it's hidden, and in the callback of the animation
the newly selected element gets the class 'active' and is shown with fadeIn.
*/
$('#info article.active').removeClass ('active').fadeOut ('fast', function () {
$('#info article#' + targetID).addClass ('active').fadeIn ('normal');
} );
} else {
//if there is no current active element, the newly selected one is applied the class active, and shown with fadeIn
$('#info article#' + targetID).addClass ('active').fadeIn ('normal');
}
context.lastArticle = targetID;
}
};
}
else //-- zEvent.type == 'mouseleave'
{
//--- Done hovering, no action is needed, other than to wait, in case of user jitter.
dDelay = 200;
ActionFunction = function (targetID, context) {
var noOp = 0;
};
}
if (typeof this.delayTimer == "number")
{
clearTimeout (this.delayTimer);
}
context = this;
this.delayTimer = setTimeout (function() { ActionFunction (targetID, context); }, dDelay);
}
See it in action at jsFiddle.
If you can, set up a link in jsfiddle with HTML, so that I can have a more detailed look.
But I think your problem is caused by the animation of the fadeIn and/or fadeOut. Try stopping the hover while animated, $('selector').is(':animated') == false, e.g.
UPDATED
function setActive(selected) {
//*******if animate is happening, hide elements and removes class
if ($('#info article').is(':animated')) {
$('#info article.active').removeClass('active').hide();
}
//*******Check if everything is not animated and do hover
if (!$('#info article').is(':animated')) {
//stores the active element in a variable
active = selected;
//checks if there are currently elements with the 'active' class in the DOM
if ($('#info article.active').length > 0) {
//if there is any currently active element, and its element_id attribute is not the one stored in the active variable
//it gets the 'active' class removed, its hidden, and in the callback of the animation
//the newly selected element gets the class 'active' and is shown with fadeIn
$('#info article.active[element_id!="' + selected + '"]').removeClass('active').fadeOut('fast', function() {
$('#info article[element_id="' + selected + '"]').addClass('active').fadeIn('normal');
});
} else {
//if there is no current active element, the newly selected one is applied the class active, and shown with fadeIn
$('#info article[element_id="' + selected + '"]').addClass('active').fadeIn('normal');
}
}
}

Categories

Resources