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');
});
});
Related
I'm working on a pricing table with some hover.
You can see it right here: http://lhit.nl/lucid/
As you see, when you hover on a pricing table all the divs toggle the classes.
And thats not what I want. I want it to be seprate ofcourse.
My jQuery:
$('.package').hover(function(){
$('.name').toggleClass('name-hover')
$('.price-container').toggleClass('price-hover')
$('.price').toggleClass('white-hover')
$('.month').toggleClass('white-hover')
});
The css is just to overwrite current colors:
.package .price-hover {
background: #008ed6;
}
.package .white-hover {
color: #fff;
}
I already tried to use $(this) but it doesn't work.
$('.package').hover(function(){
$(this).find('.name').toggleClass('name-hover')
$(this).find('.price-container').toggleClass('price-hover')
$(this).find('.price').toggleClass('white-hover')
$(this).find('.month').toggleClass('white-hover')
});
This can be simply achieved just by css. Why to add Js for this ?
package:hover .price-container{
background: #008ed6;
}
You could use each():
$('package').each(function() {
var _this = this;
$(this).hover(function() {
$(_this).find('.name').toggleClass('name-hover')
$(_this).find('.price-container').toggleClass('price-hover')
$(_this).find('.price').toggleClass('white-hover')
$(_this).find('.month').toggleClass('white-hover')
});
})
First you need to use find to only change the classes for elements
inside the currently hovered over .package, otherwise it will
change classes for all these elements.
Secondly, hover event takes
2 functions, one when mouse enters the hover area, second when cursor
exits the hover area. The way you are handling hover event, it toggles the classes twice, once on hover in, once on hover out, so in the end leaving it same as before.
Try this code:
$('.package').hover(function(){
$(this).find('.name').addClass('name-hover');
$(this).find('.price-container').addClass('price-hover');
$(this).find('.price').addClass('white-hover');
$(this).find('.month').addClass('white-hover');
}, function(){
$(this).find('.name').removeClass('name-hover');
$(this).find('.price-container').removeClass('price-hover');
$(this).find('.price').removeClass('white-hover');
$(this).find('.month').removeClass('white-hover');
});
$(".package").hover(function() {
$this = $(this);
$this.find(".name").toggleClass("name-hover");
$this.find(".price-container").toggleClass("price-hover");
$this.find(".price,.month").toggleClass("white-hover");
});
#Spartak Lalaj As of jQuery 1.4 the .hover() may have one parameter. See https://api.jquery.com/hover/
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.
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...
I'm new to Javascript/Jquery and PHP and I'm experimenting with it. Basically, I've created a simple image gallery in which each picture is at an opacity of .4 until you mouse over it and it becomes 100% opacity. Now I've gone a step further and used PHP to scan a directory of images and add them to the list of pictures in the gallery. The current code looks like this:
$(document).ready(function(){
var i = 0;
var names;
function returndata(files){
names = files;
for(i=0; i < names.length ; i++){
$('<li id="img_' + i + '"><img src="../Gallery_pictures/' + names[i] + '"/></li>').appendTo('#thumbnails ul');
}
}
$.post('../php/read_directory.php',function(data){
var files = $.parseJSON(data);
returndata(files);
});
});
The code works and adds the images to the list on the webpage, but how would I go about adding the Jquery fade to the newly created images? I've searched all over the place for an answer to this but maybe I'm just missing the answers. This and the image fade are in separate external Javascript files. Thanks in advance.
*EDIT:*Okay so I got it to work using your suggestions, but the problem now is that the script doesn't start until an image is initially moused over. All the pictures start full opacity until moused over then they all become .4 opacity. Any way to fix this? I'm also going to try if I can easily do this in css.
*DOUBLE EDIT:*So I can easily do this with css and it works like I want it to. Thanks for the replies everyone.
Use on to set events on dynamically added content
$(document).on("mouseover", "#thumbnails img", function() {
$(this).css("opacity", 1);
});
$(document).on("mouseout", "#thumbnails img", function() {
$(this).css("opacity", 0.4);
});
If you're using jQuery pre 1.7, then you can use delegate. Note that delegate takes the selector first, then the event name.
$(document).delegate("#thumbnails img", "mouseover", function() {
$(this).css("opacity", 1);
});
$(document).delegate("#thumbnails img", "mouseout", function() {
$(this).css("opacity", 0.4);
});
Avoid using live since it's deprecated.
Use .live() or .on() to bind event to dynamically added elements.
.live() is deprecated in jQuery 1.7
Try to add class="hoverImg" to your img and then do the following:
$('.hoverImg').on('hover',function(){
// here goes your hover code
});
So every image has the class .hoverImg also the new ones. And you bind the event hover on every single image that has the class .hoverImg. And why do you have to use .on() simply because this makes sure that the code is also executed if img's are added to your dom after it has been fully loaded.
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.