Why Doesn't Modal FadeOut Slowly? - javascript

I inherited this modal/overlay/content close/empty method that works, but abruptly:
method.close = function () {
$modal.hide();
$overlay.hide();
$content.empty();
$(window).unbind('resize.modal');
};
To fade out gradually, I modified the method like below, but elements are left behind and subsequent clicks don't open new modals loaded with content, only the overlay:
method.close = function () {
$modal.fadeOut('slow', function() {
$(this).hide();
});
$overlay.fadeOut('slow', function() {
$(this).hide();
});
$content.fadeOut('slow', function() {
$(this).empty();
});
$(window).unbind('resize.modal');
};
What am I missing?
UPDATE: The solution is a single nested callback, based on garryp's answer, like this:
method.close = function() {
$overlay.fadeOut('slow', function() {
$overlay.hide();
$content.empty();
});
$modal.hide();
$(window).unbind('resize.modal');
};

Hide is asynchronous; the calls you have in your original code do not block while the transition occurs, execution moves immediately to the next. You need to use callbacks, like this:
var me = $(this); //Added to ensure correct this context
$modal.fadeOut('slow', function () {
me.hide(function () {
$overlay.fadeOut('slow', function () {
me.hide(function () {
$content.fadeOut('slow', function () {
me.empty();
});
});
});
});
});
Assuming the rest of your code is correct this should ensure the transitions fire one after the next.

Firstly, you do not need $(this).hide(). JQuery fadeOut automatically set display: none at the end of fading animation (read more: http://api.jquery.com/fadeout/).
That mean, in your case $content element will also have display: none after fadeOut animation. I expect you forgot to add $content.show() in modal open method.

Related

Jquery slideDown not working right away

This is click function that search area will be slide down right under header. I made this with jQuery slideDown. But I can see that slideDown function is not working right away, It seem like waiting 1 second then slide down.
It is not a big problem, but this is bother me.
Is there any solution?
or this is just how slideDown function work?
Below is my code for reference:
/*header function*/
function showHeaderSearch_PC() {
$('.search_area').slideDown(260);
$('#search_btn_pc').fadeOut(150, function(){
$('#search_close_btn_pc').fadeIn(150);
});
}
function hideHeaderSearch_PC() {
$('.search_area').slideUp(260);
$('#search_close_btn_pc').fadeOut(150, function(){
$('#search_btn_pc').fadeIn(150);
});
}
function showHeaderAllMenu() {
$('.all_menu_area').slideDown(400);
$('#all_menu_btn').fadeOut(150, function(){
$('#all_menu_close_btn').fadeIn(150);
});
}
function hideHeaderAllMenu() {
$('.all_menu_area').slideUp(400);
$('#all_menu_close_btn').fadeOut(150, function(){
$('#all_menu_btn').fadeIn(150);
});
}
$(function(){//PC header search function
$('#search_btn_pc').click(function(){
hideHeaderAllMenu();
setTimeout(function(){ showHeaderSearch_PC();}, 400);
});
$('#search_close_btn_pc').click(function(){
hideHeaderSearch_PC();
});
});
$(function(){//PC header all menu function
$('#all_menu_btn').click(function(){
hideHeaderSearch_PC();
setTimeout(function(){ showHeaderAllMenu();}, 270);
});
$('#all_menu_close_btn').click(function(){
hideHeaderAllMenu();
});
});
I believe, you are using "slideDown" function with some value such as slideDown(500);
If you don't pass any value like slideDown(), it would slide down immediately

What's wrong with my jquery syntax and formating?

What's wrong with this code? Probably a lot cus I'm new to jquery. I'm trying to fadeIn the page then fade the background to a different one the fade up and in the nav and set it up so the links will fade the page out and bring in the new page. The code I have now isn't quite working and I think some syntax and formatting is the problem.
$(document).ready(function() {
$('body').fadeIn(1500);
});
$('#background').addClass('background');
setTimeout(function() {
$('#background').addClass('background-blured');
}, 1500);
$("h1").delay(2000).animate({
top: -50,
opacity: 1,
}, 700, function() {
// Animation complete.
});
$('.link').click(function() {
event.preventDefault();
newLocation = this.href;
$('body').fadeOut(500, newpage);
});
function newpage() {
window.location = newLocation;
}
});
Thanks!
$(document).ready triggers as soon as the DOM is fully loaded. Any javascript outside of the $(document).ready block is run while the browser is still loading the page. so if your $('#background') element is not yet loaded to the DOM jQuery cannot add the 'background' class to it. And more than likely only some of your $('.link') elements will have the click event listener added since they weren't yet loaded when the javascript ran. That's why you should embed such things inside the $(document).ready function.
$(document).ready(function() {
$('body').fadeIn(1500);
$('#background').addClass('background');
setTimeout(function() {
$('#background').addClass('background-blured');
}, 1500);
$("h1").delay(2000).animate({
top: -50,
opacity: 1,
}, 700, function() {
// Animation complete.
});
$('.link').click(function() {
event.preventDefault();
newLocation = this.href;
$('body').fadeOut(500, newpage);
});
});
function newpage() {
window.location = newLocation;
}
Notice with proper indentation you can easily see what is inside the $(document).ready function. Also notice you don't put standard functions like your newpage() function inside the $(document).ready.

Creating my custom tooltip using jquery plugin

Using jquery plugin with mouse hide and show I am trying to create tool tip.I am facing two problem
Whether my code is correct for mouseout and mouseleave
When I am creating lot of tooltip it was not positioning correctly it was coming down actually it has to come to right side.
I have found so many from stack Overflow but nothing is working out.
Here is the jquery code
$(document).ready(function() {
$(".tooltip").hide();
$("#help").on({
mouseenter: function () {
$("#showtooltip").show();
},
mouseleave: function () {
$("#showtooltip").hide();
}
});
$("#help1").on({
mouseenter: function () {
$("#showtooltip1").show();
},
mouseleave: function () {
$("#showtooltip1").hide();
}
});
$("#help2").on({
mouseenter: function () {
$("#showtooltip2").show();
},
mouseleave: function () {
$("#showtooltip2").hide();
}
});
});
Third mouse over was not working. I am trying to creating I think missed something.
Here is the jsbin Link
Kindly help me
Thanks & Regards
Mahadevan
Just add this css rules to your .tooltip class:
position: absolute;
top: 40px; /* define how much space from tooltip to the top
and this javascript:
$(document).ready(function() {
$(".tooltip").hide();
$("#help").on({
mouseenter: function (e) {
$("#showtooltip").show();
$("#showtooltip").css('left', e.pageX); // added
},
mouseleave: function () {
$("#showtooltip").hide();
}
});
$("#help1").on({
mouseenter: function (e) {
$("#showtooltip1").show();
$("#showtooltip1").css('left', e.pageX); // added
},
mouseleave: function () {
$("#showtooltip1").hide();
}
});
$("#help2").on({
mouseenter: function (e) {
$("#showtooltip2").show();
$("#showtooltip2").css('left', e.pageX); // added
},
mouseleave: function () {
$("#showtooltip2").hide();
}
});
});
I added only this line in javascript mouseenter function:
$("#showtooltip").css('left', e.pageX);
It sets the tooltip left coordinate, in case you have many items, the tooltip will show exactly beneath the hovered item.
Customization
If you want the tooltip right of the hovered item, you will need to add this css:
var rightMargin = 20; // or whatever fits your needs
$("#showtooltip").css('left', e.pageX + rightMargin);
and change your css top property above.
Update
Since this code of yours is very coupled and you asked for a better solution, here it is jQuery code:
$(document).ready(function() {
$(".tooltip").hide();
$(".help").on({
mouseenter: function (e) {
var tooltip = $(this).next(); tooltip.show();
tooltip.css('left', e.pageX + 20);
},
mouseleave: function () {
$(this).next().hide();
}
});
});
to work this, you gonna have to remove your coupled ids and instead add to every anchor tag class help.
the code simply checks if the user is hovering a link, and if so, then just show the next element after it, which happens to be the tooltip.
Here is a FIDDLE
Cheers

preventDefault() on a timer

Does anyone know if there's a way to preventDefault(), but on a timer, so default actions are restored after a certain time?
Here's what I have so far:
function setResetInterval(bool){
var el = $('article');
if(bool){
timer = setInterval(function(){
setTimeout(function(){
console.log('default prevented');
e.preventDefault();
}, 500);
},1000);
}else{
clearInterval(timer);
}
}
if(object.touch.touch){
object.header.menu_button.attr('href',null);
object.touch.articles = $('article');
object.content_blocks.on('click','article',{},function(e){
object.touch.articles.removeClass('on');
$(this).addClass('on');
e.stopPropagation();
setResetInterval(true);
setTimeout(
function() { setResetInterval(false); }, 500);
});
}
Problem is, the function is called after the clickthrough and the action is not prevented. The alternative is the prevent the default action on click, which stop scrolling on mobile devices.
Thinking about it more clearly, the real problem is the click tag in question is basically the entire screen width on mobile.
To build on what Cayce said, one way to approach this is to tie the functionality to a class you later remove.
Demo Fiddle:
In the example, the default will be prevented as long as the div has the .red class, the setTimeout will remove the class after 3 seconds.
JS:
$('body').on('click', '.red', function (e) {
e.preventDefault();
console.log('I only show up while default is prevented');
});
$('body').on('click', 'div', function () {
console.log('I will always show up');
});
setTimeout(function () {
$('div').removeClass('red');
},3000);

Load() seems to lose scope after it's been evoked

I have a button that fades in some html file, and then a back button that returns the user to initial view. However this only works once. They are unable to click the button again for a more detailed view.
$('.support').click(function () {
$('.main-view').fadeOut('slow', function () {
// Animation complete.
$('.main-view-wrapper').load('includes/modules/support.html');
});
});
$('.back').click(function () {
$('.return-main').fadeOut('slow', function () {
// Animation complete.
$('.main-view-wrapper').load('includes/modules/main-view.html');
});
});
If .back element is generated dynamically, you should delegate the event:
$('.main-view-wrapper').on('click', '.back', function(){
$('.return-main').fadeOut('slow', function () {
// Animation complete.
$('.main-view-wrapper').load('includes/modules/main-view.html');
});
})
$(document).on('click', '.support', function () {
$('.main-view').fadeOut('slow', function () {
// Animation complete.
$('.main-view-wrapper').load('includes/modules/support.html');
});
});
$(document).on('click', '.back', function(){
$('.return-main').fadeOut('slow', function () {
// Animation complete.
$('.main-view-wrapper').load('includes/modules/main-view.html');
});
})
After you've clicked both buttons, you've faded out both .main-view and .return-main, but you never fade them back in. So nothing will happen on the next click. Do you need to fade them in on click of the opposite button?

Categories