The script below does not fire the slideDown and fadeTo at the same time. It does not fade in until the slide down finishes.
<script>
$( document ).ready(function() {
var obj = $("#example");
obj.slideDown(450);
obj.fadeTo(450,1);
});
</script>
How can I simultaneously slide the object down while also fading it in?
Also, the object is just a normal div.
When you use slideDown and fadeTo, both of these calls are added to a queue(fx queue) and is executed one after another.
You can use .animate() to animate a set of css properties
$(document).ready(function () {
var obj = $("#example");
obj.animate({
opacity: 1,
height: 'show'
}, 450);
});
$(document).ready(function() {
var obj = $("#example");
obj.animate({
opacity: 1,
height: 'show'
}, 450);
});
#example {
display: none;
opacity: 0;
white-space: pre-line;
border: 1px solid red;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>
<div id="example">
$(document).ready(function () {
var obj = $("#example");
obj.slideDown(450);
obj.fadeTo(450, 1);
});
</div>
obj.slideDown({duration: 450, queue: false});
obj.stop().fadeTo(1000, 1);
Don't queue fadeTo(), fadeIn()/fadeOut()
Related
To simplify my problem, I made a jsfiddle
When I click on "Click me" it displays a box, but when i click on it twice
at the same time, it displays two boxes at the same time, and for my case it should not be possible. The second box should be able to be displayed only if the first box is completly displayed and the user click again on 'Click me'.
How can I achieve that ?
$('#clickme').click(function() {
$div = $('<div>', {
"class": "newDiv"
});
$('#container').append($div);
$div.show('clip', 3000);
});
#clickme {
cursor: pointer
}
.newDiv {
height: 40px;
width: 40px;
background-color: red;
margin: 5px;
display: none;
padding: 15px;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.2.1/jquery.min.js"></script>
<script src="https://ajax.googleapis.com/ajax/libs/jqueryui/1.12.1/jquery-ui.min.js"></script>
<a id="clickme">Click me</a>
<div id="container"></div>
A simple solution is to use a flag, to check the state whether action can be performed.
Here complete callback of .show() is used to reset the flag once effect is complete.
var disable = false;
$('#clickme').click(function() {
var elem = $(this);
if (disable == false) {
disable = !disable;
elem.toggleClass('none', disable);
$div = $('<div>', {
"class": "newDiv"
});
$('#container').append($div);
$div.show('clip', 3000, function() {
disable = !disable;
elem.toggleClass('none', disable);
});
}
});
#clickme {
cursor: pointer
}
#clickme.none {
cursor: none
}
.newDiv {
height: 40px;
width: 40px;
background-color: red;
margin: 5px;
display: none;
padding: 15px;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.2.1/jquery.min.js"></script>
<script src="https://ajax.googleapis.com/ajax/libs/jqueryui/1.12.1/jquery-ui.min.js"></script>
<a id="clickme">Click me</a>
<div id="container"></div>
I think the cleanest solution is to bind and unbind your click handler. No need to use a flag or a timeout.
function clickHandler() {
$div = $('<div>', {
"class": "newDiv"
});
$('#container').append($div);
// Unbind click handler until animation is completed
$("#clickme").off("click", clickHandler);
// Begin animation
$div.show('clip', 3000, function() {
// Animation completed. Bind click handler.
$("#clickme").on("click", clickHandler);
});
}
// Initial bind of click handler
$("#clickme").on("click", clickHandler);
Here's a working fiddle.
You can disable the button for the time when the box is being drawn. Like this:
$('#clickme').click(function() {
disabling the button for 3000 sec as the box takes 3000 sec to get rendered.
setTimeout(function(){
$(this).attr('disabled','disable');
},3000);
$(this).removeAttr('disabled');
$div = $('<div>', {
"class": "newDiv"
});
$('#container').append($div);
$div.show('clip', 3000);
});
So you need to stop execution if the box is still being animated.
I am using the complete argument of jQuery.show method.
var inAnimation = false;
$('#clickme').click(function() {
if(inAnimation)
return;
$div = $('<div>', {
"class": "newDiv"
});
$('#container').append($div);
inAnimation = true;
$div.show('clip', 3000, function() {inAnimation = false;});
});
i always use callback after end of animation:
let open = true;
$('#clickme').click(function(){
if ( open ) {
open = false;
$div = $('<div>',{"class" : "newDiv"});
$('#container').append($div);
$div.show('clip',3000, function(){
open = true;
});
}
});
fiddle
If you want a simple solution for your problem you can place an if statement before the assignment of the $div variable:
$('#clickme').click(function() {
if($('.newDiv').length == 0){
$div = $('<div>', {
"class": "newDiv"
});
$('#container').append($div);
$div.show('clip', 3000);
}
});
$('.newDiv').click(function() {
$('.newDiv').destroy();
}
I'm a javascript/jquery rookie, but I try to put in place a an interactive page containing multiple divs. These Divs enlight when we pass the mouse over and turn back to normal when mouse leaves the div. The div enlarges when clicked, and a "back" button" must turn back the div to "normal" state. My problem is the behavior of the div when click the back button, and it starts to get back to normal but enlarges again afterward. I know I could resolve the problem by moving the "button" out of the div, but is there any other solution ?
Also, how to "stop" the opacity change when enlarging the DIV ? Tried the stop() function in various scenarios but without success so far...
Thanks for the help.
Here is the HTML code :
<div id='container'>
<div id='back_button'>BACK</div>
</div>
And here is for the jQuery
$(document).ready(function () {
$('#container').hover(function () {
$(this).fadeTo('fast', 1);
}, function () {
$(this).fadeTo('fast', 0.8);
}).click(function () {
$(this).stop().animate({
width: "600px",
height: "600px",
opacity: 1
});
$('#back_button').fadeTo('fast', 1);
});
$('#back_button').click(function () {
$(this).stop( true, true ).parent().animate({
width: "200px",
height: "100px"
});
});
});
I also created an example on jsfiddle
Stop the click on the back button from propagating up to the parent, and you can use a class to disable the hover events when the element is enlarged.
$(document).ready(function () {
$('#container').hover(function () {
if ( ! $(this).hasClass('large') ) $(this).fadeTo('fast', 1);
}, function () {
if ( ! $(this).hasClass('large') ) $(this).fadeTo('fast', 0.8);
}).click(function () {
$(this).animate({
width: "600px",
height: "600px",
opacity: 1
}).addClass('large');
$('#back_button').fadeTo('fast', 1);
});
$('#back_button').click(function (e) {
e.stopPropagation();
$(this).parent().animate({
width: "200px",
height: "100px"
}).removeClass('large');
});
});
FIDDLE
please use this updated code
$(document).ready(function () {
$('#container').hover(function () {
$(this).stop().fadeTo('fast', 1);
}, function () {
$(this).stop().fadeTo('fast', 0.8);
}).click(function (e) {
if(e.target.id=="back_button" || $(this).width()>200){
return;
}
$(this).stop().animate({
width: "600px",
height: "600px",
opacity: 1
});
$('#back_button').fadeTo('fast', 1);
});
$('#back_button').click(function () {
$('#container').animate({
width: "200px",
height: "100px",
});
});
});
I have some DIVs for products, and I have:
// mouseenter
$(document).on('mouseenter', '.productWrapper', function(){
$(this).stop(true,true);
$(this).find('.productWrapperContentVisible').animate({
height: '100px',
opacity: '1',
}, function(){
$(this).find('.productWrapperPrice').fadeIn();
$(this).find('.productWrapperByCompany').fadeIn();
});
});
// mouseleave
$(document).on('mouseleave', '.productWrapper', function(){
$(this).stop(true,true);
$(this).find('.productWrapperPrice').fadeOut('fast');
$(this).find('.productWrapperByCompany').fadeOut('fast');
$(this).find('.productWrapperContentVisible').animate({
height: '40px',
opacity: '.8',
});
});
and there are about 20 of products in each page, while I'm using stop(true,true), after I move my mouse on many of them many times, this doesn't work right, they continue to change height, and sometimes productWrapperPrice is still there while I don't have my mouse over there, it should go hidden.. .
sample: http://jsfiddle.net/gwsPB/
What's wrong with my code?
Thanks
Try this:
// mouseenter
$(document).on('mouseenter', '.productWrapper', function () {
$(this).find('.productWrapperContentVisible').stop(true, false).animate({
height: '100px',
opacity: '1'
}, function () {
$(this).find('.productWrapperPrice, .productWrapperByCompany').stop(true, true).fadeIn();
});
}).on('mouseleave', '.productWrapper', function () {
var $this = $(this);
$this.find('.productWrapperPrice, .productWrapperByCompany').stop(true, true).fadeOut('fast');
$this.find('.productWrapperContentVisible').stop(true, false).animate({
height: '40px',
opacity: '.8'
});
});
DEMO
The problem is: when you mouseenter and mouseleave immediately fast enough, your animate function in the mouseenter event is not finished yet. When your call $this.find('.productWrapperContentVisible').stop(true, true), the animation is stopped but the callback function is called which display them again
function () {
$(this).find('.productWrapperPrice, .productWrapperByCompany')
.stop(true, true).fadeIn();
}
By using stop(true, false), the callbacks are not called.
You need to call stop() on elements where are being animated, calling it on an ancestor element has no effect.
// mouseenter
$(document).on('mouseenter', '.productWrapper', function () {
$(this).find('.productWrapperContentVisible').stop(true, true).animate({
height: '100px',
opacity: '1'
}, function () {
$(this).find('.productWrapperPrice, .productWrapperByCompany').stop(true, true).fadeIn();
});
}).on('mouseleave', '.productWrapper', function () {
var $this = $(this);
$this.find('.productWrapperPrice, .productWrapperByCompany').stop(true, true).fadeOut('fast');
$this.find('.productWrapperContentVisible').stop(true, true).animate({
height: '40px',
opacity: '.8'
});
});
I want a panel to slide from left edge of browser when clicking a button and hide the panel when clicking the same button (toggle).
Html
<div class="panel">
</div>
»
CSS
.panel {
width:300px;
float:left;
height:550px;
background:#d9dada;
position:relative;
left:-300px;
}
.slider-arrow {
padding:5px;
width:10px;
float:left;
background:#d9dada;
font:400 12px Arial, Helvetica, sans-serif;
color:#000;
text-decoration:none;
position:relative;
left:-300px;
}
jquery
$(function(){
$('.slider-arrow.show').click(function(){
$( ".slider-arrow, .panel" ).animate({
left: "+=300"
}, 700, function() {
// Animation complete.
});
$(this).html('«').removeClass('show').addClass('hide');
});
$('.slider-arrow.hide').click(function(){
$( ".slider-arrow, .panel" ).animate({
left: "-=300"
}, 700, function() {
// Animation complete.
});
$(this).html('»').removeClass('hide').addClass('show');
});
});
It is showing the panel but not hiding the panel. Any problem with the selectors used?
http://jsfiddle.net/Paramasivan/eHded/1/
As others have said with jQuery once the document is initialized its only looking for elements that initially existed. For that reason your .show function was being run every time.
Instead of looking for a click event on .slider-arrow.show you can just look at .slider-arrow and then check for the classes once it has been clicked like in this example.
$(function(){
$('.slider-arrow').click(function(){
if($(this).hasClass('show')){
$( ".slider-arrow, .panel" ).animate({
left: "+=300"
}, 700, function() {
// Animation complete.
});
$(this).html('«').removeClass('show').addClass('hide');
}
else {
$( ".slider-arrow, .panel" ).animate({
left: "-=300"
}, 700, function() {
// Animation complete.
});
$(this).html('»').removeClass('hide').addClass('show');
}
});
});
http://jsfiddle.net/eHded/4/
Since you are using jQuery to manipulate the "show" and "hide" after the DOM has loaded, jQuery doesn't know those elements exist.
Event handlers are bound only to the currently selected elements; they must exist on the page at the time your code makes the call...
I suggest using jQuery's on() in order to delegate events and select dynamically generated classes, like so:
$(document).on('click','.slider-arrow.show',function(){
....
});
$(document).on('click','.slider-arrow.hide',function(){
....
});
http://jsfiddle.net/eHded/2/
I think you can manage the action choosing from the active anchor class like this:
$(function(){
$('.slider-arrow').click(function(){
var anchor = this;
var removeClass = "show";
var addClass = "hide";
var diff = "+=300";
var arrows = "«";
if($(anchor).hasClass("hide")){
diff = "-=300";
removeClass = "hide";
addClass="show";
arrows = '»';
}
$( ".slider-arrow, .panel" ).animate({
left: diff
}, 700, function() {
// Animation complete.
$(anchor).html(arrows).removeClass(removeClass).addClass(addClass);
});
});
});
So you've got only one animation function.
Here is the updated fiddle: http://jsfiddle.net/eHded/5/
You should try using .slideToggle(), put inside a .click(function(){/*in here*/}).
When you write $('.slider-arrow.hide').click(func....., that binds the click event at the time that code is first ran (probably when the document is ready). If you change the DOM later on (ie. add the .hide class) you need to re-bind the click event.
You need to use jQuery's .on() method instead (http://api.jquery.com/on/).
$(document).on('click', '.slider-arrow.show', function() { /*.......*/ });
$(document).on('click', '.slider-arrow.hide', function() { /*.......*/ });
A better alternative altogether however would be to use CSS3 transitions and jQuery's .toggleClass()
.panel {
left: -300px;
transition: left 1s;
/* other styles... */
}
.panel.expand {
left: 0;
}
$('.slider-arrow').click(function() {
$('.panel').toggleClass('expand');
}
For this task I use SlideReveal jQuery plugin.
After you include the library the setup is as easy as:
<div id='slider'>Hello World!!</div>
<button id='trigger'>Trigger</button>
<script>
$('#slider').slideReveal({
trigger: $("#trigger")
});
</script>
Please refer to documentation for more details and live samples.
I have two div classes, say A and B. When the mouse is over div A, div B should appear, then if the mouse is over A or B, div B should stay opened. If the mouse is out of both, A and B divs, B should disappear. (As you probably guess this is a simple tooltip script)
This is the jquery code I wrote:
$(document).ready(function() {
function show() {
$("BBB").css({'display':'block'});
}
$("AAA").each(function() {
$(this).mouseover(function() {
show();
});
$(this).mouseleave(function() {
time = setTimeout("hide()", 200);
});
$("BBB").mouseleave(function() {
setTimeout("hide()", 200);
});
$("BBB").mouseenter(function() {
clearTimeout(time);
});
});
});
function hide() {
$("BBB").css({'display':'none'});
}
The problem is that when I move from B to A, B disappears! I want to it to disappear only if the mouse is neither over A, nor B. How can I fix this problem?
First, put B inside of A:
<div class="a">
AAA
<div class="b">
BBB
</div>
</div>
Then, abandon your javascript and make life easier with plain old css:
.b
{
display: none;
}
.a:hover .b
{
display: block;
}
Edit - Here's a live example using the CSS technique: http://jsfiddle.net/gilly3/sBwTa/1/
Edit - If you must use the JavaScript, just add clearTimeout(time) to show(). But, let's also simplify your code:
$(function()
{
var time = 0;
function show()
{
clearTimeout(time);
$("BBB").show(); // Existing jQuery that does $().css("display","block")
}
function hide()
{
time = setTimeout(function()
{
$("BBB").hide();
}, 200);
}
$("AAA,BBB").mouseenter(show).mouseleave(hide);
});
There are a few small problems with your code. The one which is biting your right now is that you aren't clearing BBB's timeout when you enter AAA. You can fix this by adding a clearTimeout to AAA's mouseover handler.
Secondly, it's safest to clear this kind of timeout before you set it each time, so that you don't have your timeout tracking overwritten if something unexpected happens. (It's always safe to clear a timeout, even if it's invalid or has already occurred.)
Lastly, though this is most likely only a problem in your example code, you're leaking time into the global object. ;-)
Try this instead:
$(document).ready(function() {
var time;
function show() {
$("BBB").css({'display':'block'});
}
$("AAA").each(function() {
$(this).mouseover(function() {
clearTimeout(time);
show();
});
$(this).mouseleave(function() {
clearTimeout(time);
time = setTimeout("hide()", 200);
});
$("BBB").mouseleave(function() {
clearTimeout(time);
time = setTimeout("hide()", 200);
});
$("BBB").mouseenter(function() {
clearTimeout(time);
});
});
});
function hide() {
$("BBB").css({'display':'none'});
}
Here's a script that works with meaningful function names that should make it easy to see what's going on. You have to cancel the hiding from mouseenter on both divs.
$(document).ready(function() {
var timerId, delay = 300;
var a = $("#A"),
b = $("#B");
function stopHide() {
clearTimeout(timerId);
}
function showTip() {
b.show();
}
function startHide() {
timerId = setTimeout(function() {
b.hide();
}, delay);
}
a.mouseenter(showTip).mouseenter(stopHide).mouseleave(startHide);
b.mouseenter(stopHide).mouseleave(startHide);
});
div {
border: 2px dashed firebrick;
float: left;
font-size: 50pt;
font-weight: bold;
padding: 5px;
margin: 5px;
}
#B {
display: none;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div id='A'> A </div>
<div id='B'> B</div>
Previously at http://jsfiddle.net/92jbK/1/
You code is wrong :)
Try this:
<!DOCTYPE HTML>
<html lang="ru-RU">
<head>
<meta charset="UTF-8">
<title></title>
<style type="text/css">
#AAA, #BBB {
width:100px;
height:100px;
border:1px solid #000;
}
</style>
</head>
<body>
<div id="BBB">
BBB
</div>
<div id="AAA">
AAA
</div>
<script src="http://www.google.com/jsapi"></script>
<script>
//VISIBLE
function hide() {
$("#BBB").css({'display':'none'});
}
function show() {
$("#BBB").css({'display':'block'});
}
// Load jQuery
google.load("jquery", "1");
google.setOnLoadCallback(function() {
// NOT VISIBLE
// function hide() {
// $("#BBB").css({'display':'none'});
// }
// function show() {
// $("#BBB").css({'display':'block'});
// }
$(document).ready(function() {
var time;
$("#AAA").each(function() {
$(this).mouseover(function() {
show();
});
$(this).mouseleave(function() {
time = setTimeout("hide()", 200);
});
$("#BBB").mouseleave(function() {
setTimeout("hide()", 200);
});
$("#BBB").mouseenter(function() {
clearTimeout(time);
});
});
});
});
</script>
</body>
</html>
one alternative is to use jquery's tooltip http://flowplayer.org/tools/tooltip/index.html
then you can just do for example:
$('#A').live(function() {
$(this).tooltip({
relative: true,
position: 'top center',
delay: 200,
effect: !$.browser.msie ? 'fade' : 'toggle',
fadeInSpeed: 100,
fadeOutSpeed: 50,
predelay: 500
});
});
and you just make div b of class tooltip
Is time declared outside all of this?
It is not in the same scope in the two functions you have it in above, so is not the same variable so the clearTimeout() call has no effect.
Declare it outside both with var time;, so that they refer to the same variable.