I want to create multiple thumbnails with the same .class. The thumbnail div contains 3 other divs. The first on is an image, the second one is a description which appear on mouseenter and the third one is a bar which change the opacity.
When the mouse hovers above the .thumbnail both elements should execute their function.
My Problem is that now every thumbnail executes the function, so every thumbnail is now highlighted. How can I change this so only one Thumbnail highlights while hovering above it?
HTML:
<div class="thumbnail">
<div class="thumbnail_image">
<img src="img/Picture.png">
</div>
<div class="thumbnail_describe">
<p>Description</p>
</div>
<div class="thumbnail_footer">
<p>Text</p>
</div>
</div>
jQuery:
$(document) .ready(function() {
var $thumb = $('.thumbnail')
var $thumb_des = $('.thumbnail_describe')
var $thumb_ft = $('.thumbnail_footer')
//mouseover thumbnail_describe
$thumb.mouseenter(function() {
$thumb_des.fadeTo(300, 0.8);
});
$thumb.mouseleave(function() {
$thumb_des.fadeTo(300, 0);
});
//mouseover thumbnail_footer
$thumb.mouseenter(function() {
$thumb_ft.fadeTo(300, 1);
});
$thumb.mouseleave(function() {
$thumb_ft.fadeTo(300, 0.8);
});
});
You code behave like this because you apply the fadeTo function to the $thumb_des and $thumb_ft selectors which contain respectively all the descriptions and footers of the page.
Instead, you should select the description and footer of the thumbnail triggering the mouse event, inside the mousenter or mouseleave functions.
Another thing you could change to optimize your code is to use only once the event listening functions, and perform both actions on the description and on the footer at the same time:
$thumb.mouseenter(function() {
var $this = $(this)
$this.find('.thumbnail_describe').fadeTo(300, 0.8);
$this.find('.thumbnail_footer').fadeTo(300, 1);
});
full working jsfiddle: http://jsfiddle.net/Yaz8H/
When you do:
$thumb_des.fadeTo(300, 0.8);
it fades all nodes in $thumb_des. What you want is to fade only the one that corresponds to the correct node in $thumb.
Try this:
for (i = 0; i < $thumb.length; i++)
{
$thumb[i].mouseenter(function (des) {
return function() {
des.fadeTo(300, 0.8);
};
}($thumb_des[i]));
});
}
You'll want to access the child objects of that particular thumbnail, something like this would work:
$(this).children('.thumbnail_describe').fadeTo(300, 0.8);
Here is a fiddle example.
Related
Im creating a fixed header where on load, the logo is flat white. On scroll, it changes to the full color logo.
However, when scrolling back to the top, it stays the same colored logo instead of going back to white.
Here's the code (and a pen)
$(function() {
$(window).scroll(function() {
var navlogo = $('.nav-logo-before');
var scroll = $(window).scrollTop();
if (scroll >= 1) {
navlogo.removeClass('.nav-logo-before').addClass('nav-logo-after');
} else {
navlogo.removeClass('.nav-logo-after').addClass('nav-logo-before');
}
});
});
http://codepen.io/bradpaulp/pen/gmXOjG
There's a couple of things here:
1) You start with a .nav-logo-before class but when the logo becomes black you remove that class and then try to get the same element using a class selector that doesn't exist anymore
2) removeClass('.nav-logo-before') is different than removeClass('nev-logo-before), notice the "." in the first selector.
3) You get the element using the $('.selector')in every scroll event, this can be a performance issue, it's better to cache them on page load and then use the element stored in memory
4) It's not a good practice to listen to scroll events as this can be too performance demanding, it's usually better to use the requestAnimationFrame and then check if the scroll position has changed. Using the scroll event it could happen that you scroll up really fast and the scroll event doesn't happen at 0, so your logo won't change. With requestAnimationFrame this can't happen
$(function() {
var navlogo = $('.nav-logo');
var $window = $(window);
var oldScroll = 0;
function loop() {
var scroll = $window.scrollTop();
if (oldScroll != scroll) {
oldScroll = scroll;
if (scroll >= 1) {
navlogo.removeClass('nav-logo-before').addClass('nav-logo-after');
} else {
navlogo.removeClass('nav-logo-after').addClass('nav-logo-before');
}
}
requestAnimationFrame(loop);
}
requestAnimationFrame(loop);
});
body {
background-color: rgba(0,0,0,.2);
}
.space {
padding: 300px;
}
.nav-logo-before {
content: url(https://image.ibb.co/kYANyv/logo_test_before.png)
}
.nav-logo-after {
content: url(https://image.ibb.co/jYzFJv/logo_test_after.png)
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div>
<img class="nav-logo nav-logo-before">
</div>
<div class="space">
</div>
Dont need to add the dot . in front of the class name in removeClass and addClass:
Use this:
navlogo.removeClass('nav-logo-before')
Secondly, you are removing the class that you are using to get the element in the first place.
I have an updated codepen, see if this suits your needs: http://codepen.io/anon/pen/ZeaYRO
You are removing the class nav-logo-before, so the second time the function runs, it can't find any element with nav-logo-before.
Just give a second class to your navlogo element and use that on line 3.
Like this:
var navlogo = $('.second-class');
working example:
http://codepen.io/anon/pen/ryYajx
You are getting the navlogo variable using
var navlogo = $('.nav-logo-before');
but then you change the class to be 'nav-logo-after', so next time the function gets called you won't be able to select the logo using jquery as it won't have the '.nav-logo-before'class anymore.
You could add an id to the logo and use that to select it, for example.
Apart from that, removeClass('.nav-logo-before') should be removeClass('nav-logo-before') without the dot before the class name.
The problem is that you removes nav-logo-before and then you want to select element with such class but it doesn't exist.
I've rafactored you code to avert it.
Another problem is that you uses dot in removeClass('.before') while it should be removeClass('before') - without dot
$(function() {
var navlogo = $('.nav-logo');
$(window).scroll(function() {
var scroll = $(window).scrollTop();
if (scroll >= 1) {
navlogo.removeClass('before').addClass('after');
} else {
navlogo.removeClass('after').addClass('before');
}
});
});
body {
background-color: rgba(0,0,0,.2);
}
.space {
padding: 300px;
}
.before {
content: url(https://image.ibb.co/kYANyv/logo_test_before.png)
}
.after {
content: url(https://image.ibb.co/jYzFJv/logo_test_after.png)
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div>
<img class="nav-logo before">
</div>
<div class="space">
</div>
I'm working on a web design assignment and I'm fairly uncomfortable with most css styles thus far, this task involves 3 coloured boxes in a div. I have to turn the white background of this div to the same colour of the box when the box is hovered.
HTML:
<div id="t1_color_one" class="t1_colors" style="background: goldenrod;"></div>
<div id="t1_color_two" class="t1_colors" style="background: lightgreen;"></div>
<div id="t1_color_three" class="t1_colors" style="background: palevioletred;"></div>
Not trying to be "that guy" who asks stupid questions.. but I literally have no idea how to approach this. Thanks for any tips, greatly appreciated
I think Jeremy means that the outside div id="task1" has to assume the color of the hovered inside div, so the solution is to use javascript:
$('.t1_colors').hover(function(){
$('#task1').css('background-color', $(this).css('background-color'));
},
function(){
$('#task1').css('background-color', white);
}
);
here is working example, is this what you wanted >> http://jsfiddle.net/mbTBu/
$(document).ready(function(){
$(".t1_colors").hover(function(){
var $c=$(this).css("background-color");
$("#task1").css('background-color', $c);
});
});
you can also use, mouseover & mouseout function to revert back the color.
http://jsfiddle.net/mbTBu/2/
Here is answer in pure javascript
window.addEventListener('load', function(event)
{
var divs = document.getElementsByClassName('t1_colors');
var count_of_divs = divs.length;
for(var i = 0; i<count_of_divs; i++)
{
divs[i].addEventListener('mouseover', function(e)
{
document.getElementById('task1').setAttribute('style', e.target.getAttribute('style'));
}, false);
divs[i].addEventListener('mouseout', function(e)
{
document.getElementById('task1').removeAttribute('style');
}, false)
}
}, false);
And you can check it in jsFiddle link.
I have a div with class 'bannergroup' that contains multiple divs 'banneritem'. I want these items to rotate (fade in then fade out) in place of each other.
I can have several divs with the class bannergroup and each one should rotate separately.
Here is the HTML:
<div class="bannergroup">
<div class="banneritem">Only visible one at a time</div>
<div class="banneritem">Only visible one at a time</div>
<div class="banneritem">Only visible one at a time</div>
<div class="banneritem">Only visible one at a time</div>
</div>
<div class="bannergroup">
<div class="banneritem">Only visible one at a time</div>
<div class="banneritem">Only visible one at a time</div>
<div class="banneritem">Only visible one at a time</div>
<div class="banneritem">Only visible one at a time</div>
</div>
My Jquery looks like:
$('.banneritem').css('display', 'none');
$('.bannergroup').children('.banneritem').each(function( i ) {
$(this).fadeIn().delay(4000).fadeOut();
});
The problem: the each statement continues to run before the previous div completes. I want it to wait until the previous child is gone. Also, I need this to continuously run. After a single time it stops. I can put this into a function, but I am not sure how to know to call it again.
EDIT: There are not always 4 child items. Also one group may have a different number of children than the others, but they should both rotate in-sync. It is ok if one completes before the other and then just restarts itself.
I have answered this question multiple times before. This time I will try wrapping it in a jQuery plugin. The .rotate() function will apply the effect you want to the children of the matched elements, a fade in/out effect per children in a continuous animation.
$.fn.rotate = function(){
return this.each(function() {
/* Cache element's children */
var $children = $(this).children();
/* Current element to display */
var position = -1;
/* IIFE */
!function loop() {
/* Get next element's position.
* Restarting from first children after the last one.
*/
position = (position + 1) % $children.length;
/* Fade element */
$children.eq(position).fadeIn(1000).delay(1000).fadeOut(1000, loop);
}();
});
};
Usage:
$(function(){
$(".banneritem").hide();
$(".bannergroup").rotate();
});
See it here.
jsFiddle example
$('div.bannergroup').each(function () {
$('div.banneritem', this).not(':first').hide();
var thisDiv = this;
setInterval(function () {
var idx = $('div.banneritem', thisDiv).index($('div.banneritem', thisDiv).filter(':visible'));
$('div.banneritem:eq(' + idx + ')', thisDiv).fadeOut(function () {
idx++;
if (idx == ($('div.banneritem', thisDiv).length)) idx = 0;
$('div.banneritem', thisDiv).eq(idx).fadeIn();
});
}, 2000);
});
You can solve this problem in 2 ways. The one below is the easiest, using the index to increase the delay per item.
$('.banneritem').css('display', 'none');
$('.bannergroup').children('.banneritem').each(function( i ) {
$(this).delay(4000 * i)).fadeIn().delay(4000 * (i+1)).fadeOut();
});
I have 10 divs with class "animate" and IDs from "one" to "ten", for example:
<div class="animate" id="six">
bla bla content
</div>
I need to cycle the visibility of these ten layers in a continuous loop.
The method doesn't have to be very efficient, it just has to work OK.
I have tried running them through a for loop and fade in then fade out them one by one but they all became visible at the same time then faded out together at each iteration.
The code I used for that:
layer_ids = ['one','two','three','four','five','six','seven','eight','nine','ten'];
for(i = 0; i < 300; i++)
{
animate_id = layer_ids[i%10];
element_selector = '.animate#'+animate_id;
$(element_selector).fadeIn(1500).delay(1000).fadeOut(1500);
}
I expected that at the first iteration the first one would be shown then hidden, then the second one, etc.
How can I show then hide them in sequence?
Another thing I'd like to know is how I can run this continuously. I tried with a while(1) but the page froze.
Would rather do this without 3rd party plugins if possible.
Smoothly transitions between content.
Use the setInterval milliseconds value to decide how long you would like to display each section.
Add as many DIVs as needed to the HTML, the code will count them.
Demo: http://jsfiddle.net/wdm954/QDQhu/4/
Any specific reason you want to do this with cycle?
Think the same could be accomplished with much less code:
var els = $("div.animate").hide();
function rotate(){
for (var i=0;i<els.length;i++){
$(els[i]).delay(i*1000).fadeIn(1500).delay(1000).fadeOut(1500);
}
setTimeout(rotate, i*1000);
}
rotate();
Example on jsfiddle, and it isn't restricted to the number of elements.
Version 1, fades in the next element while the currently visible element is still fading out. This looks nice if they're positioned on top of each other.
var roller = $('.animate'),
curr = roller.length-1;
function fadeOut() {
roller.eq(curr).fadeOut(1500, fadeIn);
}
function fadeIn() {
curr = (curr+1) % roller.length;
roller.eq(curr).fadeIn(1500, fadeOut);
}
fadeOut();
http://jsfiddle.net/kaFnb/2/
Version 2, fades the next element in only once the previous element has been faded out. This works well when the content isn't positioned on top of each other (like in the fiddle example).
var roller = $('.animate'),
curr = roller.length-1;
function toggleNextRoller() {
roller.eq(curr).fadeOut(1500);
curr = (curr+1) % roller.length;
roller.eq(curr).fadeIn(1500, toggleNextRoller);
}
toggleNextRoller();
http://jsfiddle.net/kaFnb/1/
I put together a little example for you. hope it helps:
$(function () {
function animateBoxes(targetElement, delay) {
var anims = targetElement;
var numnberOfAnims = anims.size();
anims.eq(0).addClass('visible').fadeIn();
setInterval(function () {
$('.visible').fadeOut(function () {
$(this).removeClass('visible').next().addClass('visible').fadeIn();
if ($(this).index() + 1 == numnberOfAnims) {
anims.eq(0).addClass('visible').fadeIn();
}
});
}, delay);
}
animateBoxes($('.animate'), 2000);
});
Html:
<div class="animate visible">
Content 1
</div>
<div class="animate">
Content 2
</div>
<div class="animate">
Content 3
</div>
<div class="animate">
Content 4
</div>
<div class="animate">
Content 5
</div>
CSS:
.animate
{
display:none;
border:solid 1px red;
padding:30px;
width:300px;
}
I have the following code for my popup menu, the parent link is the top level link. It causes a popup to show. Popup fades in and fades out when the mouse enters and exits parent link.
However, I need it to not fade out the popup, if the mouse is over the popup! At the moment, as soon as the mouse enters the popup it fades it out. I need both divs to act as one for the hover, if this makes any sense!
// Hovering over the parent <li>
ParentLink.hover(
function()
{
Popup.fadeIn(300, function() {
});
},
function()
{
Popup.fadeOut(400, function() {
});
}
);
You should nest the popup inside the parent. This way when you move the mouse from the parent to the popup, the parent will still be in a mouse-over state because popup's mouse-over event is bubbled onto the parent. When the mouse is out of the parent (plus its children), mouse-out event will fire on the parent.
Edit
If you are not able to (or want to) change the markup, one possibility is to move the elements to the recommended positions using jQuery, like:
ParentLink.append(Popup); // moves the Popup element from its current position
// and places it as the last child of ParentLink
Most probably you'll have to modify your CSS to match the changes so you may want to think first.
you could unbind the hover-event for the parentlink on completion of the fadein.
Popup.fadeIn(300, function() {
$(ParentLink).unbind('hover');
});
This is not a direct answer to your question but a hint how this could work.
Why don't you nest the the 2nd <div> into the first one, so the out will not occur?
<div id="ParentLink">
<div id="Popup"></div>
</div>
Have #ParentLink { display: relative; } and #Popup { display: absolute; } and you will be fine.
But for those menu's I would always use a nested unordered list structure like this one:
<ul id="topLevel">
<li id="level1item">
Link
<ul id="subLevel">
<li>
Link 2
</li>
</ul>
</li>
</ul>
As said, unbind the event while you are hover the popup and then re-bind it when you are hovering out :
ParentLink.hover(
handlerIn,
handlerOut
);
var handlerIn = function()
{
Popup.fadeIn(300, popupFadeIn);
};
var handlerOut = function()
{
Popup.fadeOut(400);
};
var popupFadeIn = function() {
$(ParentLink).unbind('hover');
$(this).mouseleave( function () {
$(ParentLink).hover(
handlerIn,
handlerOut
);
});
};
btw, I didn't tested this
You can try this:
var inn;
$('ParentLink').hover(function() {
inn = false;
$('p').fadeIn(1000);
},
function() {
$('Popup').bind('mouseenter mousemove',
function() {
inn = true;
}).mouseout(function() {
inn = false;
});
if (!inn) $('Popup').fadeOut(1000);
});