Jquery Rollovers, issue with click state - javascript

Excuse my noobiness when it comes to Jquery, but I have some jquery code that does rollovers for me:
$("img.rollover").hover(function () {
this.src = this.src.replace("_off","_on");
},
function () {
this.src = this.src.replace("_on","_off");
});
Essentially just switching the images from image_on.jpg to image_off.jpg on hover on a bunch of images, now on click i would like to set the state of "image_on" permanently but the hover state seems to overwrite it and it doesn't stay "_on", i'm guessing it something to do with binding of events? I also don't seem to be able to do it so if a user clicks on one image it sets it to on, but if they click another image to return the previous image to the "_off" state and set the current one to the "_on" state.
Any help appreciated, ta.

i would add a "selected" class to the link when it is actually active and filter against that.
$("img.rollover").bind('click',function(){
$('img.rollover').removeClass('selected');
$(this).addClass('selected');
}).hover(function () {
this.src = this.src.replace("_off","_on");
},
function () {
if(!$(this).hasClass('selected')){
this.src = this.src.replace("_on","_off");
}
});
Of course, you would style your .selected images using the _on image.
sidenote:
Note that the recommended way of implementing rollover images is the css sprite technique: you use an image that contains all the states, use that image as a background image, and adjust the background-position according to :hover, :active states. It's a pure CSS solution that works in all recent browsers.

your hover code seems to run two functions one after the other which will effectively undo each others changes. so _off is turned to _on then back again.
so for hover to toggle it "on" you would just want
$("img.rollover").hover(function () {
this.src = this.src.replace("_off","_on");
});
if you just do this 1 function each time you can then control other states as you'd like e.g.
$("img.rollover").mouseout(function () {
this.src = this.src.replace("_on","_off");
});

You could unbind the hover event $(this).unbind('mouseenter mouseleave') when a click occurs, and rebind if necessary later.

Related

check if this element OR this element is hovered with jQuery

I have two separate elements in my DOM that require a change when either one is hovered. When the link is hovered, the image src needs to change (easy) AND the link color needs to change. When the image is hovered, the same effect needs to happen (image src changes & link color changes)
This is actually quite easy to do, but I have a feeling there is a MUCH easier way to do it then the approach I am taking. Currently I am going through each of the 8 elements and testing if they are hovered individually. This works good, but there is so much more jQuery here than I feel there should be.
I tried adding the attribute onmouseover to both of the elements and triggering the same function, but for some reason the function wasn't triggering.
Is there a way to test if either element is hovered and trigger a function if either one is? Something like this:
if($(#elm1).hover() || $('#elm2').hover()) {
//effect here
}
OR
if($('#elm1').is(':hover') || $('#elm2').is(':hover')) {
//effect here
}
I tried my example code above, but wasn't getting any results. Is there a way to do this or am I stuck with checking each individual element?
It works, you're just running it on page load, not when the mouse moves
$(document).mousemove(function() {
if($('#elm1').is(':hover') || $('#elm2').is(':hover')) {
// Do stuff
}
else {
// Revert do stuff or do other stuff
}
});
Example here
But, as other's have said, jQuery already knows the hover state, so doing it this way would be unnecessary. In practice you should use the same selector to apply the function to it
$('#idOne, #idTwo').hover(function() { /* Do stuff */ });
I would register events on mouseover and whenever the event happens trigger a function
$("#elm1, #elm2").on("mouseover", function () {
// effect here
});
Why not simply add the handler to both elements like this :
$('#elm1, #elm2').hover(function(){
// ... do stuff here ...
});
Should work . . .

JQuery hover fade with default div transition stutter

I am attempting to use hover with with to swap div visibility when mousing over navigation buttons.
When there is no mouseover, there is a 'default' div that should appear.
My problem is that every time the mouse transitions between links, the default div briefly reappears.
Is it possible to make the swap seamless, or will a different approach to the swap work? I attempted to set the nav container div with a fadeout/fadein event for the default div, but I didn't have any luck with that.
Refer to the following fiddle for an example: http://jsfiddle.net/ElectricCharlie/Wk8Yd/
$('div.hmnav').hover(function()
{
$('#_wnr00').stop(true,true).fadeOut();
$('#_'+this.id).stop(true,true).fadeIn(400);
},
function ()
{
$('#_'+this.id).stop(true,true).fadeOut(400);
$('#_wnr00').stop(true,true).fadeIn();
});
I just got rid of true,true and it worked fine:
$('div.hmnav').hover(function () {
$('#_wnr00').stop().fadeOut();
$('#_' + this.id).stop().fadeIn(400);
},
function () {
$('#_' + this.id).stop().fadeOut(400);
$('#_wnr00').stop().fadeIn();
});
Updated your jsFiddle as well.
EDIT: took the time to clean up your jQuery as well:
$('#navbox_inner')
.corner("round 12px")
.parent()
.css({padding:1})
.corner("round 14px")
$('#navbox_inner').on({
mouseenter: function () {
$('#_wnr00').stop().fadeOut();
$('#_' + this.id).stop().fadeIn(400);
},
mouseleave: function(){
$('#_' + this.id).stop().fadeOut(400);
$('#_wnr00').stop().fadeIn();
}
},'.hmnav');
This is much faster, as it binds to one item, and delegates appropriately. I also removed the element selector, as a pure class based / id based selector is faster. Updated your jsFiddle a second time.

Change css when tab has active class

I'm trying to change the background colour of the <body> depending on what tab specific is active.
When a tab is active, a class called 'st_view_active' is added onto the tab content. In the tab content I add a hidden div with the hex code of what my body background colour should be when that tab is active, my jQuery code looks like this:
$(document).ready(function() {
$(function(){
$('body').css('backgroundColor',$('.st_view_active').find('.background').text());
});
});
And my html code when the tab is active is following:
<div class="tab-6 st_view st_view_active" >
<div style="display:none" class="background">yellow</div>
<div class="st_view_inner">
tab 6
</div>
</div>
So when tab6 is active the background of the body should be yellow. However, this is not working, the background colour is not changing, what am I doing wrong here?
DEMO and JSfiddle
Thanks
PS: The red and blue square is the next and previous tab handler..
See here: http://jsfiddle.net/CNYDU/25/
I put the default color at the end of sColor, but you could instead grab the first view and use its color. I did it this way to cut down on testing since your fiddle is painful to work with.
$(document).ready(function() {
var hsh = window.location.hash.replace('#','');
var sColor = hsh ? $("#slidetabs_45").find("."+hsh+" .background").text() : "#3b0";
$("body").css("background-color", sColor);
$("#slidetabs_45").slidetabs({
onContentVisible:function(e){
var color = $("#slidetabs_45").find(".st_view_active .background").text();
$("body").css("background-color", color);
}
});
});
I also added the .st_view_active class to the first view so that it will start correctly.
I also added a CSS3 transition to the background color, which isn't necessary.
This sounds like a great opportunity to use data elements in html. Rather than having a hidden div with the background color you want, you can simple add a data-color attribute to your tab a tag. Then when the div is clicked you can set the color easily with an event handler.
link to an updated fiddle - http://jsfiddle.net/CNYDU/15/
Note: The next and previous tabs do not work in this example, but it should be easy to get them working, just attach a listener to each that runs
$('body').css('background-color', $(".st_tab_active").attr('data-color'));
as its callback.
Check out the livequery plugin for jQuery.
Live Query also has the ability to fire a function (callback) when it matches a new element and another function (callback) for when an element is no longer matched. This provides ultimate flexibility and untold use-cases. For example the following code uses a function based Live Query to implement the jQuery hover helper method and remove it when the element is no longer matched.
Their example:
$('li')
.livequery(function(){
// use the helper function hover to bind a mouseover and mouseout event
$(this)
.hover(function() {
$(this).addClass('hover');
}, function() {
$(this).removeClass('hover');
});
}, function() {
// unbind the mouseover and mouseout events
$(this)
.unbind('mouseover')
.unbind('mouseout');
});
You should be able to adapt this to your css changes like fired events, and therefor perform your actions based on which tab is active.
I have forked Jlange's jsfiddle, which uses the data attribute, for a demo of how this plugin would be used:
http://jsfiddle.net/nj6ZY/2/
http://jsfiddle.net/nj6ZY/2/show/#tab-10 - Also works with a link to activate a specific tab
And the relevant bits:
$('.st_tabs_ul li a.st_tab_active').livequery(function(){
$('body').css('background-color', $(this).data('color'));
});
Put ID's on your tabs. Example for id="tab6":
$(document).ready(function() {
if ($('#tab6').attr('class') == 'tab-6 st_view st_view_active') {
$('body').css('background-color', 'yellow');
}
});
However, why would you attach this function to document ready only? I would bind the function to when the element is clicked...

Fade in/out buttons on mouseover of an image with jQuery. A few bugs to work out

So, I essentially have what I want already, very simple, but there are some bugs. I just want so when you hover over an image, two left/right buttons appear on the image that allow you to click through other images. Then when you leave the image area (excluding the left/right buttons), the buttons fade out again. Here's what I've got:
$(document).ready(function() {
$('#image-slider').mouseenter(function(){
$('.next').fadeIn('50');
$('.prev').fadeIn('50');
}).mouseout(function(){
$('.next').fadeOut('50');
$('.prev').fadeOut('50');
});
});
Bug #1: However, when you mouseover the image the buttons appear, and if you mouse over the buttons, they disappear. Naturally, of course they do, this is because I told them to fade away when I left the image area. First of all, I need them to stay visible even when you hover over them. So I need to somehow include the buttons as part of my image area in my javascript. That's the first problem/
Bug #2: This is a common problem I see in javascript. When you hover over the image, the buttons fade in, hover off, they fade out. Of course, there's a duration to this, and if you keep hovering in/out/in/out/in/out before the duration can finish, then when you let it fly, it will go on and off and on and off. How can I prevent this? So that is you hover out of the image area while the buttons are fading in, it just stops the animation sequence in its tracks so you don't get that continuous fading in/out.
Thanks in advance!
~ Jackson
ETA: the fix
I got it solved! A combination of your fix and #Pumou's.
I made another div just to wrap the two items and expanded it to cover the image, then I set the mouseover to be that div. Problem #1 solved.
I used puormo's .fadeTo() trick to solve problem #2.
Then, I used tweaks from everyone to shorten up the code so it was neat and tidy. Thanks to all!
I've decided on #jfriend00's solution. It's the shortest, great work!
Here's my final javascript:
$(document).ready(function() {
var b = $('.ps_next, .ps_prev');
$('#slider-wrapper').bind('mouseenter mouseleave', function(e) {
var check = ( e.type === 'mouseenter' ) ?
( b.stop(0,1).fadeIn(100) ) :
( b.stop(0,1).fadeOut(100) ) ;
});
});
Problem #2 can be fixed with .stop() which forces any previous animations to just to their conclusion before starting the next one.
$(document).ready(function() {
$('#imageContainer').hover(function() {
$('.ps_next').stop(true, true).fadeIn(400);
$('.ps_prev').stop(true, true).fadeIn(400);
}, function () {
$('.ps_next').stop(true, true).fadeOut(400);
$('.ps_prev').stop(true, true).fadeOut(400);
});
});
It may be better to use the .hover() jQuery function which handles both enter and leave rather than mouseenter() and mouseout().
You can see both an example of .stop() and .hover() on this jQuery doc page doing almost the exact same thing you are.
For problem #1, I think we'd need to see the structure of your HTML to know how best to advise on that as their are several choices depending upon how things are structured. You could also do the fadeOut on a delay that was cancelled if they hovered over the button so there was time to get the mouse to the buttons before they disappeared. Or, you could use .hover() on a container that contained both image and buttons.
You can see it working here: http://jsfiddle.net/jfriend00/Zk6rY/.
Shortened the code (as seen in the above jsFiddle) even more to this:
$(document).ready(function() {
$('#imageContainer').hover(function() {
$('.ps_button').stop(true, true).fadeIn(400);
}, function () {
$('.ps_button').stop(true, true).fadeOut(400);
});
});
$(document).ready(function() {
var $buttons = $('.next, .prev')
$('#image-slider').mouseenter(function(){
$buttons.stop().fadeTo('50','1');
$buttons.mouseenter(function() { $buttons.show(); });
}).mouseout(function(){
$buttons.stop().fadeTo('50','0');
});
});
I have also used stop();. I've also shortened it to use one selector to select both buttons (in this case, it was set to the variable $buttons).
I noticed that if your mouse entered the image div, and then left, and then entered again, the buttons were fading in to 50% opacity because of the stop();. I fixed this by using the fadeTo(); feature: the first one is the duration, which was set to 50 like yours, and the second one is the opacity to fade to (a number between 0 and 1).
I also solved the problem of keeping the buttons there when you hover over them. See this line:
$buttons.mouseenter(function() { $buttons.show(); });
This just uses show();, which gives the element display:block; on mouseover.
Example here: http://jsfiddle.net/purmou/MM4ba/1/
More about stop(); here: http://api.jquery.com/stop
More about fadeTo(); here: http://api.jquery.com/fadeto
EDIT: Updated the code so that it now uses jQuery's hover(); function. Shorter code is always better.
$(document).ready(function() {
var $buttons = $('.next, .prev')
$('#image-slider').hover(function(){
$buttons.stop().fadeTo('50','1');
$buttons.mouseenter(function() { $buttons.show(); });
},
function(){
$buttons.stop().fadeTo('50','0');
});
});
Example: http://jsfiddle.net/purmou/MM4ba/2/
More on hover(); here: http://api.jquery.com/hover
DEMO FIDDLE
var b = $('.btn');
$('#image-slider').bind('mouseenter mouseleave', function(e) {
var check = ( e.type === 'mouseenter' ) ?
( b.stop(false, true).fadeIn(300) ) :
( b.stop(false, true).fadeOut(300) ) ;
});
(with your markup and the use of ternary-operators)
You all might be looking for this awsmness.....
$(document).ready(function () {
$('#content').hover(function () {
$('.a').stop(true).fadeTo(500, 0.7);
$('.i').stop(true).fadeTo(500, 0.9);
}, function () {
$('.a').stop(true).fadeOut(500);
$('.i').stop(true).fadeTo(500, 1);
});
$('.a').hover(function () {
$('.i').stop(true).fadeTo(500, 0.95);
}, function () {
$('.a').stop(true).fadeTo(500, 0.7);
$('.i').stop(true).fadeTo(500, 0.9);
});
});
http://jsfiddle.net/Sourav242/p0z0oh82/

CSS Change in multiple locations on hover (jquery solution needed)

I'm working in wordpress, trying to figure out how to change the css color of a side nav element when a remote image is hovered.
I would have done this easily with CSS and just assign the CSS hover class for each item, but since this is a CMS, the navigation and the image gallery will change dynamically.
So, I'm looking for a JQuery of how to accomplish this. Any suggestions?
Here's an example of the html:
<div class="imgGallery">
<img class="page-item-54" src="/image1.jpg">
<img class="page-item-66" src="/image2.jpg">
<div>
When someone hovers over the specific image above, it changes the css of the image below:
<ul class="pageNav">
<li class="page-item-54">Sub Gallery 1</li>
<li class="page-item-66">Sub Gallery 2</li>
</ul>
Thanks!
Troy
You can use the jQuery hover function to hook up handlers for the mouseenter and mouseleave events of the images (which jQuery will happily simulate on browsers that don't support them):
$(".imgGallery img").hover(
function() {
// Code for when the hover starts, the (raw) hovered `img`
// element is `this`, from which we can get the class name
// to feed into a selector for finding the relevant `li`
$(".pageNav ." + this.className).css(/* your change here */);
},
function() {
// Code for when the hover ends, the (raw) unhovered `img`
// element is `this`
$(".pageNav ." + this.className).css(/* your change here */);
}
);
Here's a live example with just one pageNav, and a revision with multiple pageNavs just to show that it is updating multiple locations simultaneously.
mouseenter and mouseleave (IE innovations that still aren't supported natively by many browsers, but which jQuery provides if missing) are a lot less difficult to work with for this sort of thing than mouseover and mouseout, since mouseover and mouseout bubble. (In your case, it may not matter much, as you're using imgs; if you were using elements that could have child elements, though, it would make a big difference.)
Here is a possible solution.
You may want to look at changing <ul class="pageNav"> to <ul id="pageNav"> (unless you know for sure you will never duplicate this class).
Edit: updated to allow for multiple classes in the img tag.
$(function() {
var $pageNav = $('.pageNav');
// hook up hover function to all images under the imgGallery class
$('.imgGallery').find('img').hover(function() {
// find "page-item-" class
var pageItemClassName = this.className.replace(/.*(page-item-\d+).*/, "$1");
// toggle hovered class on matching item under unordered list
$pageNav.find('.' + pageItemClassName).toggleClass('hovered');
});
});​
You can then make a hovered css class which will apply when hovered. For example:
.pageNav .hovered {
background-color: #009900;
}
You can FAKE a CSS HOVER with the code bellow
$(document).ready(function() {
var images = $(".imgGallery img");
$.each(images, function(i, item) {
$(item).mouseover(function() {
$(this).css({
"background-image": "url('alternate_image.png')",
"background-repeat": "no-repeat"
});
}).mouseout(function() {
$(this).css({
"background-image": "url('original_image.png')"
});
});
});
});
In this jQuery script, I add and remove a second class class "over" that you can style accordingly.
$(function () {
$('div.imgGallery img').hover(
function () {
$('ul.pageNav li[class=' + $(this).attr('class') + ']').addClass('over');
},
function () {
$('ul.pageNav li[class=' + $(this).attr('class') + ' over]').removeClass('over');
});
});

Categories