I'm working on a jQuery game. I have a 4 divs in a 2x2 design. The player needs to pick 1 option and verify with another button. The thing is, I have a hover effect adding a class which changes the background with a low opacity, and a click effect setting the background with a higher opacity. For divs 2, 3 and 4 it works fine - I hover and background changes color with opacity 0.3 and when I move the mouse out, it goes back to white. And when I click it, it changes the background to 0.4 and the hover doesn't affect them anymore. However, this is not working for the first div: the div changes background color on hover, but when I click it ,it keeps the hover color, and when I mouse out I see the click color, and every time I hover it changes the hover color again and so on.
Why is it happening only on div 1?
Code:
//hover effects
$(".respuesta1,.respuesta2,.respuesta3,.respuesta4").hover(
function () {
$(this).addClass("respuestahover");
},
function () {
$(this).removeClass("respuestahover");
});
//on click function for div1
$(".respuesta1").on("click", function () {
//if it hasnt been clicked, toogle class and change var to true
if (prendido1 == false) {
$(this).toggleClass("respuesta1b");
prendido1 = true;
//if any of the other divs are clicked by the time you are clicking unclicked 1, turn them off
if (prendido2 == true) {
$(".respuesta2").toggleClass("respuesta2b");
prendido2 = false;
}
if (prendido3 == true) {
$(".respuesta3").toggleClass("respuesta3b");
prendido3 = false;
}
if (prendido4 == true) {
$(".respuesta4").toggleClass("respuesta4b");
prendido4 = false;
}
//if is already clicked, turn off and change var to false
} else {
$(this).toggleClass("respuesta1b");
prendido1 = false;
}
});
The last part is repeated for every div "respuesta2", "respuesta3", etc..
Any idea?
EDIT
I was trying to clean up the code to make a jsFiddle and I think I got it to work:
http://jsfiddle.net/bqySN/2/
I'll just leave the code there if anyone is interested, be aware the code is unpolished and it need more generalisations.
EDIT 2
After some testing I actually found the problem:
if I alter the order of my css clases the app goes crazy:
This one is correct, with hover first
.respuestahover{
background-color:#f00;
opacity:0.2;
}
.respuestab{
background-color:#f00;
opacity:0.5;
}
This one is incorrect, hover second:
.respuestab{
background-color:#f00;
opacity:0.5;
}
.respuestahover{
background-color:#f00;
opacity:0.2;
}
I'm not really sure why it is behaving like that, but I'm glad I figure it out.
You are adding a class on hover... why would you do that via javascript if you can just use the :hover state from css? For example:
#foo .element p { color: red; }
#foo .element:hover p { color: blue; }
EDIT:
Sorry, I miss the original question.
If you want to remove the hover effect after clicking, you have lot of different ways to do this. You can remove the class defined with the hover via css, or if you want a jQuery solution you can use mouseenter/mouseleave with .on and then unbind with off.
See the following fiddle example.
You should simplify the bindings to just target them a little more generically, then remove the hover classes on all of them:
$(".respuesta").on("click", function (index) {
$(this).removeClass("hover");
// do other things
});
You can also use the index to find which number they are if they're in a list.
if you want the hover to not override the click, give the click an active class and tell the hovers to work on everything but them:
$('.respuesta:not(.active)').hover(function() {
// do something
}
Related
I have been trying to make a random image appear on click by adding a fadeOut effect and then removing the class. when I click it works fine, but I don't know how to remove the class after a few milliseconds and then being able to appear again on another click. so far I have just been able to make it fade out on click, I have tried a setInterval function so that the class gets removed after 1 millisecond but didn't work so I erased it, but even then, I don't know how to make the .on('click', function()) function fire on every click, instead of just working once. any help or tips would be really appreciated. Thanks!
<style>
body {
background-color: black;
}
img {
opacity: 0;
width: 40px;
z-index: 0;
position: relative;
top: 3em;
}
</style>
<img class="red"
src="http://www.clker.com/cliparts/0/f/1/f/130267960774173786paint-
splash(red)-md.png" alt="">
<img class="blue" src="http://www.clker.com/cliparts/Q/3/H/u/Z/K/dark-blue-
splash-ink-hi.png" alt="">
<img class="yellow" src="http://www.clker.com/cliparts/3/y/m/m/p/P/yellow-
splash-ink-md.png" alt="">
<script>
$(document).ready(function(){
var red = $(".red");
var blue = $(".blue");
var yellow = $(".yellow");
var images = [red, blue, yellow];
$(document).on('click', function(){
$(images[(Math.floor(Math.random()*3))]).addClass("animated fadeOut");
});
})
//i should be able to click anywhere on the screen and a random image should appear and then fadeout each time there is a click
</script>
Try something like this:
$(document).on("click", function() {
$("#element").show(0, function() {
$("#element").fadeOut();
});
});
$("#element").hide();
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<span id="element">Element</span>
It looks like you are using jQuery so you simply need to:
1) Create a function that hides the class. Example:
function hideStuff(){
$(".myimg").hide();
}
2) Add a class to your image files so they have a common selector (like "myimg" below). You may also want to add an "alt" attribute (was missing in your code). Example:
<img class="yellow myimg" src="http://www.clker.com/stuff" alt="image-three">
3) Add the timeout as part of your function with the amount of delay you want. While it is not required, you should include a variable name so you can call it in the future. Example:
var myTimeout = setTimeout( hideStuff, 5000);
Hopefully these will get you going in the right direction.
Both .fadeOut() and .hide() set display: none, which could effect your layout. I think you're looking to animate opacity to 0, and then in the callback function you can change the image source. I'd recommend using a div and setting the background-image property since divs are a bit more layout friendly. Also, you could either use classes and set the background-image property in the <style> section or you can make an array of the image urls and randomly pick from that (which is what I did here).
let images = [
'http://www.clker.com/cliparts/0/f/1/f/130267960774173786paint-splash(red)-md.png',
'http://www.clker.com/cliparts/Q/3/H/u/Z/K/dark-blue-splash-ink-hi.png',
'http://www.clker.com/cliparts/3/y/m/m/p/P/yellow-splash-ink-md.png'
];
$(document).on('click', function() {
let $img = $('.img'); //so you don't have to make a new object everytime it's used
if ($img.css('opacity') === '1') {
$img.animate({ opacity: 0 }, function() {
$img.css('background-image', `url(${images[Math.floor(Math.random()*3)]})`);
});
} else {
$img.animate({ opacity: 1 });
}
}).click().click(); //two clicks to initialize image
https://jsfiddle.net/yc4e4nxb/3/
NOTE: JSfiddle doesn't seem to like wherever these images are hosted, so it's working kind of erratically. Hopefully you get the gist of what this code is doing though.
http://api.jquery.com/animate/
If I understood the question correct, In This Fiddle the button element disappears when you click anywhere in the screen and then re appears immediately. Hope this will work.
$(document).ready(function(){
$(document).on('click',function(){
$("#myElement").fadeOut().delay(100).fadeIn();
});
});
I'm having an issue trying to get .fadeIn(), .fadeOut(), and .hide() to behave properly when an element is hovered over.
Let's say I have a container, .post-box.
.post-box contains two divs: .description and .quote. The .quote div is initially hidden so that when .post-box is hovered over, it fades in and takes the place of the .description div, which gets hidden with .hide().
When .post-box is hovered out of, .quote fades out and .description is faded in again.
$(document).ready(function() {
var description = $('.description');
var quote = $('.quote');
var postBox = $('.post-box');
postBox.hover(function() {
$(this).find(description).clearQueue().stop(true, true).hide(0, function() {
quote.fadeIn(300);
});
}, function() {
$(this).find(quote).clearQueue().stop(true, true).fadeOut(300, function() {
description.fadeIn(300);
});
});
});
It seems that I've got this concept working fairly well except for one issue. If you quickly hover over .post-box, quickly hover out, and then quickly hover over again, you're presented with both the .quote and .description divs showing at the same time (see example screenshot here).
I thought I was preventing them from firing at the same time based on how my functions are set up, but I must be missing something important for this to be happening.
Here is my fiddle so you can see it in action.
Could somebody please lead me in the right direction?
My guess would be to also clear the animation queue for the quote element on hover.
$(this).find(quote).clearQueue().stop(true, true).hide();
I've updated the fiddle accordingly .
Introduction
I'm using Semantic-UI's sidebar functionality, which gives you a button that triggers a sidebar that pushes the content from the left (in this case).
I want to unfold that same sidebar by hovering with the mouse on the left side. I realize there are several ways to do it (as these often do. Maybe just checking the X position of the mouse would work but that's beside the point); I chose to create a transparent div on the left side and make its :hover pseudo-class to trigger the sidebar:
// create sidebar and attach to menu open
$('.ui.sidebar').sidebar('attach events', '.toc.item');
// hover transparent div to trigger the sidebar too:
$('.sidebar-trigger').hover(function() {
$('.ui.sidebar').sidebar('show')
});
// hide() and show() the sidebar accordingly to use the sidebar:
$('.ui.sidebar').sidebar('setting', {
onShow: function() {
$('.sidebar-trigger').hide();
},
onHidden: function() {
$('.sidebar-trigger').show();
}
});
Problem
Now, it all works except for one occasion: when you don't stop moving the mouse as the sidebar opens. I've looked at $(document).on('transitionend', function(event) { ... } and that mouse effectively prevents the transition to finish.
Resources
I've put a blue background on my .sidebar-trigger and made a small video/gif so as to be clearer.
I moved the mouse like a crazy creature but with natural gestures the problem occurs as well.
I'm using Semantic-UI's guide on this thing: http://semantic-ui.com/modules/sidebar.html#/settings (I've also tried onVisible and onHide with no luck)
This is a OSX Yosemite 10.10.3 running Chrome 45.0.2454.101 (64-bit)
jsfiddle with the problem at hand
PS: It seems it might be an OSX Chrome bug?
I would try using one and mouseover:
$('.sidebar-trigger').one('mouseover', function() {
$('.ui.sidebar').sidebar('show')
});
Then, when it has finished animating, reattach the event:
$(document).on('transitionend', function(event) {
$('.sidebar-trigger').one('mouseover', function() {
$('.ui.sidebar').sidebar('show')
});
});
I think what is happening is that the hover event is getting called multiple times - every time the element is hovered, then goes over a child element, and then goes back over the hover element, and things are getting mixed up at some point. So you need to only call show if it's not already shown.
Here is a working example: Fiddle
I believe when the element was hovered, it was adding a classes 'uncover' and 'visible', and another called 'animating' which wouldn't fire until the mouse stopped moving. I changed the jQuery slightly to only add classes 'uncover' and 'visible', and it still animated okay. However, the body was pushing right too far by 175px, so I had to edit the class that was causing that (noted below) from 260px to 85px. This DOES get the menu acting properly though from my understanding.
$('.sidebar-trigger').mouseenter(function() {
$('.ui.sidebar').addClass('uncover, visible');
$('body').addClass('mleft175');
});
$('body').click(function() {
$('.ui.sidebar').removeClass('uncover, visible');
$('body').removeClass('mleft175');
});
and then add overriding class
.ui.visible.left.sidebar ~ .pusher
{
-webkit-transform: translate3d(85px, 0, 0);
transform: translate3d(85px, 0, 0);
}
Right now it is set to hide the menu when the body is clicked. Alternatively you can hide it when the mouse leaves the sidebar menu:
$('.ui.sidebar').mouseleave(function(){
$(this).removeClass('uncover, visible')
});
Ok, my first answer was (of course) way too much work for what it really needed. The onVisible seems to work perfectly. Was that not working for you? Demo HERE
Simply change 'onShow' to 'onVisible' in your sidebar setting:
$('.ui.sidebar').sidebar('setting', {
onVisible: function() {
$('.sidebar-trigger').hide();
},
onHidden: function() {
$('.sidebar-trigger').show();
}
});
As shown on the Semantic UI site, the onVisible fires when the animating starts. The onShow fires when the animating finishes. So what you were doing was hiding that blue / transparent bar when the animation was finally done (the .animating class noted in my previous answer), as opposed to when it starts. If you need further explanation please let me know.
I'm working with a 3D rotating button in which each face has a different phrase, but both are links to the same URL. I initially was rotating the cube button with a plain old css :hover, but I noticed that when you click the button it resets. It should only rotate back to its starting position if your mouse is no longer on the button.
I have created a pen that uses all of my markup and styling, and I've tried four methods of adding a class called 'flip' to style on hover, but each of these four methods have the same effect as the plain old css :hover method, they reset on a mouse click. I've commented #2, 3, and 4 out in the pen just because they are all yielding the same result, and the first is just a simple 'toggleClass' method. Here's the four JS snippets and a link to the pen.
// #1 Story Button Toggle Class On Hover To Rotate - Resets on Click
$('.story-button').hover(function () {
$(this).toggleClass('flip');
return false;
});
// #2 Story Button Add/Remove Class On Hover To Rotate - Resets on Click
$('.story-button').hover(
function () {
$(this).addClass('flip');
},
function () {
$(this).removeClass('flip');
}
);
// #3 Story Button Add/Remove Class on 'mouseover To Rotate - F's Up the markup/styles on mouseover
$('.story-button').mouseover(function(){
$(this).removeClass().addClass('flip');
}).mouseout(function(){
$(this).removeClass().addClass('flip');
});
// #4 Story Button Add/Remove Class on 'mouseenter' and 'mouseleave' To Rotate - Still Rotates back on click
$('.story-button')
.mouseenter(function() {
$(this).addClass('flip');
})
.mouseleave(function() {
$(this).removeClass('flip');
});
And the link to the pen: http://codepen.io/andandandandrew/pen/OPXOxP?editors=011
Thanks in advance for the help/advice!
PS, If anyone has any idea why this would work on codepen but not on my local mamp server (building a wordpress site, using codekit with no JSHint errors when compiled/minified) that would be super.
The problem is that the hover event is on the element that is being transformed if you add a div around the button and listen for the hover on the div then you shouldn't have a problem.
HTML:
<div class="btnContainter">
<button class="story-button">
<a class="front" href="javascript:(void)">FRONT</a>
<a class="back" href="javascript:(void)">BACK</a>
</button>
</div>
CSS:
.btnContainter {
display: block;
width: 15em;
height: 3em;
margin: 0 auto;
}
jQuery:
$('.btnContainter').hover(function () {
$(this).children('.story-button').toggleClass('flip');
return false;
);
codePen
I have a refresh "button" (actually a png image) which the user can hover their mouse over, turning it from gray to blue. When refresh is clicked, the image changes to a play "button" which exhibits similar color-changing behavior, except when you click on the play image it should switch back to the original refresh image.
The problem is that, after clicking on the refresh image, when I click on the play image without removing my mouse from the image, it doesn't change back to the refresh image.
I have already looked into event propagation stopping.
Here is my code:
$('#refresh').click(function (event) {
if (!tMinusZero) {
$('#refresh').html("<img src='play_small_hover.png'>");
tMinusZero = true;
event.stopImmediatePropagation();
} else {
$('#refresh').html("<img src='refresh_small_hover.png'>");
tMinusZero = false;(
event.stopImmediatePropagation();
}
});
$('#refresh').hover(function () {
if (!tMinusZero) {
$('#refresh').html("<img src='refresh_small_hover.png'>");
} else {
$('#refresh').html("<img src='play_small_hover.png'>");
}
}, function () {
if (!tMinusZero) {
$('#refresh').html("<img src='refresh_small.png'>");
} else {
$('#refresh').html("<img src='play_small.png'>");
}
});
Some interesting things I have noticed whilst trying to debug:
If I move my mouse through #refresh too fast the hover will 'stick' i.e. the implicit mouseleave won't fire.
Commenting out the hover code fixes the clicking problem.
Leaving the hover code in, if I click outside of the image but inside of the div, without removing my mouse from the div, fixes the clicking problem.
Removing my mouse from the div before trying to click again fixes the clicking problem.
After clicking on the image, the image it changes to will flicker between the hover and non-hover image if I move my mouse over it, but not if I first remove my mouse from the div.
When I experience the clicking problem, the offending image will flicker momentarily, as if switching to one of the non-hover images, and then quickly changing back to the offending image.
It seems to me that my two event handlers have conflicting interests, but stopping the event propagation doesn't seem to help.
Why don't you try to tackle your problem with CSS, i think it will be more elegant, make a small DIV, with a background corresponding to your image, define a hover state and an active state, plus a small script to change between 2 more additional states
Something like:
CSS:
#refresh[data-state=notclicked]
{
background-image:url('play_small.png');
cursor:pointer;
}
#refresh[data-state=notclicked]:hover
{
background-image:url('play_small_hover.png');
cursor:pointer;
}
#refresh[data-state=clicked]
{
background-image:url('refresh_small.png');
cursor:pointer;
}
#refresh[data-state=clicked]:hover
{
background-image:url('refresh_small_hover.png');
cursor:pointer;
}
Of course you will have to define the width and the height in the CSS, to a fixed width.height which matches your png size.
Than the js:
$("#refresh").click(function(){
if ($(this).attr('data-state')=='clicked') {$(this).attr('data-state','notclicked');}
else {$(this).attr('data-state','clicked');}
});
If I understand correctly how you want it to behave, your code seems to work just fine, even though there's a typo in the click event (round bracket).
tMinusZero = false;(
Also, just for improve the code you can replace
$('#refresh')
with
$(this)
inside the event as it'll refer to the dom element you attached the event to.