Hover(), mouseenter(), mouseover(), etc jumping back and forth - javascript

I am trying to make a situation when you hover over an image then it will hide an image and show another. and the other way around when you hover out.
I have tried using all the various hover effects that comes to mind like mouseenter, mouseover, hover, etc.
They all cause the same problem. If i very firmly and quickly drag my cursor into the field of action then it will give me the desired effect. however if i slowly drag my cursor into the field of action then it will jump between the images a couple of times before finally stopping at the correct image.
this looks very unprofessional and i want it to be much more consequent doing this action so that no matter if i do it slow or fast then it will only jump once.
this is my script:
$("#DenmarkMap").hide();
$("#InfoBadge1").hover(function(){
$("#InfoLogo").hide("puff");
$("#DenmarkMap").show("puff");
}, function(){
$("#DenmarkMap").hide("puff");
$("#InfoLogo").show("puff");
});
this is a non working fiddle
https://jsfiddle.net/ydeLvxx2/
hope you guys can help me figure this out.

Here is a pure Javascript solution (no jQuery needed)
https://jsfiddle.net/uL0hpxbu/
Update: version with CSS3 "puff" effect: https://jsfiddle.net/230ta4tk/2/
Here is how the main script looks like:
var InfoBadge1 = document.getElementById("InfoBadge1");
var InfoLogo = document.getElementById("InfoLogo");
var DenmarkMap = document.getElementById("DenmarkMap");
InfoBadge1.addEventListener("mouseover", function() {
InfoLogo.classList.toggle("puff");
DenmarkMap.classList.toggle("puff");
});
InfoBadge1.addEventListener("mouseout", function() {
InfoLogo.classList.toggle("puff");
DenmarkMap.classList.toggle("puff");
});
and CSS part (just an example, change it as you want)
#DenmarkMap {
position: absolute;
left: 0;
top: 0;
transition: .5s all;
}
#InfoLogo {
position: absolute;
left: 250px;
top: 120px;
transition: .5s all;
}
#InfoBadge1 {
position: absolute;
left: 0px;
top: 120px;
}
.puff {
transform: scale(1.2);
opacity: 0;
}
and HTML:
<img id="InfoBadge1" src="http://dummyimage.com/200x100/803580/ffffff&text=InfoBadge1" alt="" />
<img id="InfoLogo" src="http://dummyimage.com/200x100/803580/ffffff&text=InfoLogo" alt="" />
<img id="DenmarkMap" class="puff" src="http://dummyimage.com/200x100/3c8036/ffffff&text=DenmarkMap" alt="" />

You should not bind your hover's mouseleave/mouseout event to the same image, because you've just hidden it.
Instead, consider binding the hover functions to the parent DOM node (a DIV for example):
<div id="images">
<img id="InfoBadge1" src="./Photos/DenmarkInfoBadge.png">
<img id="InfoLogo" src="./Photos/InfoLogo.png">
<img id="DenmarkMap" src="./Photos/DenmarkMap.png">
</div>
Your javascript can then become:
$("#DenmarkMap").hide();
$("#images").hover(function(){
$("#InfoLogo").hide("puff");
$("#DenmarkMap").show("puff");
}, function(){
$("#DenmarkMap").hide("puff");
$("#InfoLogo").show("puff");
});

Related

Pieces of image stick around after altering display to "display: none"

I've been using the following function to hide my div's when I no longer wanted them to be visible
function hide(div) {
document.getElementById(div).style.display = 'none';
}
However the problem has arrived with the div inparticular.
<div id="loading">
<img src="./img/loading.gif"/>
</div>
When I call the function hide('loading') only parts are the image are hidden, and slices of it are burnt onto the page. Considering this is supposed to be a little loading icon, having is stamped into the page isn't really what I'm going for, how can I prevent this?
I'm using the loading icon while processing network data, then hiding it upon receiving and processing data from the server(nodejs).
css as requested:
#loading {
position: fixed;
top: 50%;
left: 50%;
margin-top: -64px;
margin-left: -64px;
z-index: 999;
}
can u try this..??
Html
<div id="one">
<img src="https://elora.aerb.gov.in/ELORA/images/loadingnew.gif">
</div>
<div id="two">
<img src="http://www.schultzlawoffice.com/img/loading/loading.gif">
</div>
Script
$(document).ready(function () {
$("div").on("click", function () {
var thisId = $(this)
hide(thisId);
});
});
function hide(thisId) {
$(thisId).hide();
}
Fiddle Sample

Have created a click effect for a single image, but would like to have the other images have the same effect

I'm at a point where I've tried every other option, but I can't seem to solve this problem. Here's an explanation of the experience:
When visiting the page, the person is introduced to a number of images (tagged with classes, for example two of the images are tagged img01 and img02). When an image is clicked, the image maintains it's place (img01's z-index is risen) while all the other images fade away (DIV with a white fill fades in and covers img02), and a text that explains the piece fades in as well (DIV tagged object-text with img01's supporting text fades in).
While I got the img01 functionality to work, I can't seem to do the same for img02. I'm also planning on adding more tags (such as img03 and img04) and am wondering if there is a smarter, more effective way this can be structured.
For functionality reference, here's a http://jsfiddle.net/kenhimself/nvwzgus0/4/
Below, is the html, css, and the java code.
Thanks in advance!
html
<img class="img01" src="http://media.tumblr.com/tumblr_mcepyv1Qfv1ru82ue.jpg"/>
<div id="object-text" class="img01">
<h1>img01 Text<br/>img01 Text</h1>
</div>
<img class="img02" src="http://media.tumblr.com/tumblr_mcepyv1Qfv1ru82ue.jpg"/>
<div id="object-text" class="img02">
<h1>img02 Text<br/>img02 Text</h1>
</div>
<div id="filler"></div>
CSS
html, body {
width:100%;
height:100%;
}
#object {
top: 100px;
left:100px;
}
#object-text {
display:none;
z-index:100000;
bottom: 0;
left: 0;
}
#filler {
display:none;
width:100%;
height:100%;
position:fixed;
background-color: white;
z-index:1000;
opacity: 0.8;
}
h1 {
font-size:20px;
font-family: sans-serif;
font-weight: 100;
font-style: normal;
color: red;
}
.img01, .img02 {
position:absolute;
}
.img01 img, .img02 img {
width:200px;
height:auto;
}
.img01 {
top: 20px;
left: 20px;
}
.img02 {
top: 20px;
right: 20px;
}
Javascript
$("#object").click(function (e) {
e.stopPropagation();
});
$("#object").click(function (e) {
e.preventDefault();
e.stopPropagation();
$("#object").css("z-index", "2000");
$("#object-text").fadeIn("slow");
$("#filler").fadeIn("slow");
$("#inner").css("z-index", "2000");
});
$(document).click(function () {
$("#filler").fadeOut("slow");
$("#object-text").fadeOut("slow");
});
There are a few issues with your code. You should be using unique ID's for each DOM element, and targeting your images by class name. I've made a few changes to your example and restructured it slightly to show you a better approach.
http://jsfiddle.net/nvwzgus0/6/
Wrapped each image in a containing tag, removed duplicate ID's and using class names instead
<a href="#" class="img img01">
<img class="img01" src="http://media.tumblr.com/tumblr_mcepyv1Qfv1ru82ue.jpg"/>
<div class="object-text">
<h1>img01 Text<br/>img01 Text</h1>
</div>
</a>
<a href="#" class="img img02">
<img class="img02" src="http://media.tumblr.com/tumblr_mcepyv1Qfv1ru82ue.jpg"/>
<div class="object-text">
<h1>img02 Text<br/>img02 Text</h1>
</div>
</a>
<div id="filler"></div>
Added CSS class for changing z-index instead of setting it manually, to make it easier to toggle on and off.
a.top {
z-index: 2000;
}
Modified event handling to target new containing tag:
$("a.img").click(function (e) {
e.preventDefault();
e.stopPropagation();
$(this).addClass("top");
$(this).find(".object-text").fadeIn("slow");
$("#filler").fadeIn("slow");
});
Modified how images z-index is reset:
$(document).click(function () {
$("#filler").fadeOut("slow", function() {
$("a.img").removeClass("top");
});
$(".object-text").fadeOut("slow");
});
The main problem I see here is that you have two objects with the same id. Change this, and your code should work. I would recommend switching what you have as ids (object) to classes, and what you have as classes (img02 and img01) to ids.
I looked over your code some more and it seems you are doing this a lot. Make sure that when you code you NEVER reuse ids...like ever. Both your a's and your divs have duplicate ids....
Not to be mean, but this does need a lot of work. Feel free to ask any questions if you need more help.

jQuery hover animation efficiency

I've got my hover working - but i'm interested in trying to make it more efficient as it does seems to 'lag' when it's finding the .overlay div. I also had the issue where I was animating all .overlay divs on a page, which I consider to be quite a noob mistake.
Anyway, let's learn how to make the below better!
jQuery:
// get aside feature
var aside_feature = $('aside .feature');
// on hover, fade it in
$( aside_feature ).hover(function() {
// get the overlay div
var feature_overlay = $(this).find('.overlay');
$(feature_overlay).stop().fadeIn();
// on hover out, fade it out
}, function() {
$(this).find('.overlay').stop().fadeOut();
});
Markup:
<aside>
<div class="feature">
<div class="overlay">
button
</div><!-- overlay -->
<div class="text">
<p>text</p>
</div><!-- .text-->
<div class="image">
<figure>
<img src="" alt="">
</figure>
</div><!-- .image -->
</div><!-- .feature -->
</aside><!-- aside -->
Fiddle: http://jsfiddle.net/9xRML/5/
Edit - Final Code
Thanks #Shomz, and #Afro.
Final code choices were to use tranisitons, and coupled with modernizr detection for transitions, I changed my hidden overlay div to opacity: 0; *display:none; and javascript as a fallback:
CSS
.overlay {
*display: none;
opacity: 0;
transition: 0.4s all linear;
}
.overlay:hover {
opacity: 1;
}
jQuery
$(function () {
/*=====================================
= Feature overlay =
=====================================*/
if (!Modernizr.csstransitions) {
// get aside feature
var aside_feature = $('aside .feature');
// on hover, fade it in
$( aside_feature ).hover(function() {
$(this).find('.overlay').stop(true, true).fadeIn();
// on hover out, fade it out
}, function() {
$(this).find('.overlay').stop(true, true).fadeOut();
});
}
});
With risking of having my answer out of scope here, if you want to really get performance, you should switch to CSS animations. It's totally possible with your example by setting the default opacity of the overlay to 0 (instead of display: none;) and making it show up on .feature:hover. The trick is to add the transition property like this:
// applies a 4ms transition to any possible property with no easing
transition: all .4s linear;
See the whole example here: http://jsfiddle.net/9xRML/6/
See a nice article about the performance difference (CSS vs. JS) here: http://css3.bradshawenterprises.com/blog/jquery-vs-css3-transitions/ (there are many more, of course)
I think I have solved your issue using the same HTML but changing the following:
JQuery
$('aside .feature').hover(function() {
$(this).find('.overlay').stop(true, true).fadeIn();
}, function() {
$(this).find('.overlay').stop(true, true).fadeOut();
});
CSS
.feature {
background: #ccc;
}
.overlay {
display: none;
}
This means the overlay will only display on hover.
Details on .stop() can be found here.
.stop(true, true)
We can create a nice fade effect without the common problem of multiple queued animations by adding .stop(true, true) to the chain.
DEMO

Jquery image and background fade onclick

I've been searching around and using bits and pieces I've found (mostly on this site) to help me get as far as I am, but am afraid I kind of painted myself into a corner here by taking a route I shouldn't have early on. Basically I'm trying to create like a light switch. On load, the page background is black with an image with black background around a frame(there is some light glare/glow which is why there is an image). When you click the switch it changes the background color to white and changes that image to something else with a white background. This is working fine but I want to add a fade so it isn't an instant change, kind of like a light fading on/off. Due to the way I got the earlier part working, I'm wondering if this will be more difficult than it should.
I've searched and read that there is no fade of background colors without containers and such. Just unsure of how I would do so with how I have things already. I'm open to suggestions completely, even if it means redoing some of the previous things in different ways. I left some commented things in just to show some things I tried previously. I'm pretty new to jQuery so I expect that some of this may look off completely.
Fiddle added. Images are just mock images but serve their purpose
http://jsfiddle.net/timtim123/7wh4B/
HTML:
<body id="bodyback">
<img id="out" src="rhino.png" width="527" height="376" border="0" />
<img id="frame" src="frame.png" width="589" height="377" border="0" />
<img id="paper" src="paper.png" width="142" height="214" border="0" usemap="#links" />
<img src="background.png" id="backimg"/>
<img src="background2.png" id="backimg" style='display:none;'/>
<div id="lightswitch">
<img src="switchdark.png" width="46" height="275" border="0" alt="Make it light" />
</div>
CSS:
#bodyback {
background-color:black;}
#backimg
{
position:absolute;
top: 0px;
left: 0px;
z-index: 2;
}
#backimg2
{
position:absolute;
top: 0px;
left: 0px;
z-index: 2;
}
#lightswitch
{
top: 0px;
left: 900px;
position:absolute;
z-index: 7;
}
JS:
$("#lightswitch").click(function() {
var src = $('#backimg').attr('src');
//change background image and color to white
if(src == 'background.png') {
// $("#backimg").fadeTo('slow', 0.3, function()
// $(this).attr("src","background2.png"),
$("#backimg").attr("src","background2.png"),
$("#bodyback").css("background-color","white");
//change background image and color back
} else if(src == "background2.png") {
$("#backimg").attr("src","background.png");
$("#bodyback").css("background-color","black");
}
});
Here's a very simple jQuery plug-in option, if you want to go that route
One option is jQuery UI color animation. It's a very simple plug-in with easy to use documentation. Just put the script in your head tag, and you're ready to go.
EXAMPLE (comes from the jQuery docs)
$(function() {
var state = true;
$( "#button" ).click(function() {
if ( state ) {
$( "#effect" ).animate({
backgroundColor: "#aa0000",
color: "#fff",
width: 500
}, 1000 );
} else {
$( "#effect" ).animate({
backgroundColor: "#fff",
color: "#000",
width: 240
}, 1000 );
}
state = !state;
});
});
You'll notice with this, you set a backgroundColor property, and it will animate to whatever background color that is.
From what I've looked at, going back and doing something from scratch, as opposed to using the plug-in, (despite being probably a fantastic exercise in learning to code cool stuff) is a little bit tricky. Depends on your purposes.

On mouseover, changing an image's opacity and overlaying text

I want to drop the opacity and overlay text on a thumbnail image when I mouse over it. I have several ideas about how to do it, but I'm fairly certain they're inefficient and clumsy.
Make a duplicate image in Photoshop with the text overlay and reduced opacity. Swap the original out for the duplicate on mouseover.
Use CSS to drop the opacity on mouseover. Use Javascript to toggle visibility of a div containing the overlay text.
The problem I see with 1 is it seems like an unnecessary use of space and bandwidth, and will cause slow load times. With 2, it seems like I'd have to hard-code in the location of each div, which would be a pain to maintain and update. I know this is a somewhat general question, but I'm at a loss about how to go about this. How can I do this relatively simple task in a way that will make it easy to add new thumbnails?
Wrap your image in a <div class="thumb">
Add position: relative to .thumb.
Add <div class="text> inside .thumb.
Add display: none; position: absolute; bottom: 0 to .text.
Use .thumb:hover .text { display: block } to make the text visible on hover.
Like this: http://jsfiddle.net/dYxYs/
You could enhance this with some JavaScript/jQuery: http://jsfiddle.net/dYxYs/1/
$('.text').hide().removeClass('text').addClass('text-js');
$('.thumb').hover(function(){
$(this).find('.text-js').fadeToggle();
});
This way, the basic effect still works without JavaScript, and users with JavaScript get the appealing fade effect.
Go with option 2. There are ways to do it to not have to write a jQuery function for each image. As seen in my jsfiddle.
http://jsfiddle.net/daybreaker/dfJHZ/
HTML
<img src="http://placekitten.com/300/300" />
<span class="text" style="display:none">THIS IS A KITTEN</span>
<br><br>
<img src="http://placekitten.com/200/200" />
<span class="text" style="display:none">THIS IS A KITTEN</span>
jQuery
$('img').mouseover(function(){
$(this).css('opacity','.2');
$(this).next('span.text').show();
}).mouseout(function(){
$(this).css('opacity','1');
$(this).next('span.text').hide();
});
You would need to modify the span.text css to overlay it on top of the image, but that shouldnt be too bad.
Wrap it in an element and do something like this:
var t;
$('div.imgwrap img').hover(function(){
t = $('<div />').text($(this).attr('title')).appendTo($(this).parent());
$(this).fadeTo('fast',0.5);
},function(){
$(this).fadeTo('fast',1);
$(t).remove();
});
with a markup similar to:
<div class="imgwrap">
<img src="http://www.gravatar.com/avatar/3d561d41394ff0d5d0715b2695c3dcf0?s=128&d=identicon&r=PG" title="text" />
</div>
example: http://jsfiddle.net/niklasvh/Wtr9W/
Here's an example. You can position the text however you want, but the basic principle below.
http://jsfiddle.net/Xrvha/
#container { position: relative; }
#container img, #container div {
position: absolute;
width: 128px;
height: 128px;
}
#container img { z-index -1; }
#container div {
z-index 1;
line-height: 128px;
opacity: 0;
text-align: center;
}
#container:hover img {
opacity: 0.35;
}
#container:hover div {
opacity: 1;
}
If you don't want to change your HTML wraping things etc, I suggest you this way. Here is the jQuery:
$(function() {
$(".thumb").mouseenter(function() {
var $t = $(this);
var $d = $("<div>");
$d.addClass("desc").text($t.attr("alt")).css({
width: $t.width(),
height: $t.height() - 20,
top: $t.position().top
});
$t.after($d).fadeTo("fast", 0.3);
$d.mouseleave(function() {
$(this).fadeOut("fast", 0, function() {
$(this).remove();
}).siblings("img.thumb").fadeTo("fast", 1.0);
});
});
});
2 is a good solution, have done about the same as this and it isn't as hard as you would've tought;
Drop de opacity with css indeed, than position a div relative to the img, and over it. It can be done with plain css. The z-index is the trick. That div can just be shown with $('#div').slideUp() ie.

Categories