In the following code, on .hover() the #wrap element's height in animated via jQuery animate().
On handlerIn the element gains 250px of height and on handlerOut it loses 250px of height.
The issue is that I've also included a "button" that gives the user the ability to remove that 250px of height that is added on .hover(handlerIn). When the user clicks this "button", then moves the mouse outside of the hover element (handlerOut); the hover element loses 250px twice.
I'd like to only trigger the .hover(handlerOut) function if the user has not clicked the "button".
Fiddle
$(document).ready(function() {
$("#wrap").hover(
function() {
$(this).animate({height: '+=250'}, 'slow');
$('#button').css('display', 'block');
expanded = true;
console.log("expanded is " + expanded);
},
function () {
$(this).animate({height: '-=250px'}, 'slow');
$("#button").hide();
expanded = false;
console.log("expanded is " + expanded);
}
);
$('#wrap').on('click', function(){
window.open('http://google.com', 'click', 'window settings');
return false;
console.log('click');
});
if(expanded = true){
$("#button").on('click', function(){
$('#wrap').animate({height: '-=250px'}, 'slow');
$("#button").hide();
return false;
});
};
});
(Though I don't necessarily think you're going about this the right way) You need to make sure you're setting expanded to false after you click the X, i.e., telling the code that the box is no longer expanded and that it shouldn't reduce the size of the box further:
$(document).ready(function() {
$("#wrap").hover(
function() {
$(this).animate({height: '+=250'}, 'slow');
$('#button').css('display', 'block');
expanded = true;
console.log("expanded is " + expanded);
},
function () {
$(this).animate({height: '-=250px'}, 'slow');
$("#button").hide();
expanded = false;
console.log("expanded is " + expanded);
}
);
$('#wrap').on('click', function(){
window.open('http://google.com', 'click', 'window settings');
return false;
console.log('click');
});
if(expanded = true){
$("#button").on('click', function(){
$('#wrap').animate({height: '-=250px'}, 'slow');
$("#button").hide();
return expanded = false; //This is all I changed
});
};
});
That works. Fiddle
EDIT
A word of warning - you should really think twice before using the jQuery.animate() function. Compared to say, something like CSS animations or a far better js animation platform like GSAP, the jQuery.animate() function is around 10x slower ::reference.
Personally I'd use GSAP, but either way you shouldn't spend much more time learning this workflow - it will only hinder you in the future!
Related
I'm trying to make the Scroll To Top button appear once the user started scrolling down, instead of it always being present, even when being at the top. Quick note, I barely have experience with JS, so I have no idea what I'm doing.
Anyway here is the page I'm having an error on: http://www.m.evans-carpentry.com/gallery/projects/
<script>
$(function() {
var $elem = $('#content');
$('#nav_up').fadeIn('slow');
$('#nav_down').fadeIn('slow');
$(window).bind('scrollstart', function(){
$('#nav_up,#nav_down').stop().animate({'opacity':'0.2'});
});
$(window).bind('scrollstop', function(){
$('#nav_up,#nav_down').stop().animate({'opacity':'1'});
});
$('#nav_down').click(
function (e) {
$('html, body').animate({scrollTop: $elem.height()}, 800);
}
);
$('#nav_up').click(
function (e) {
$('html, body').animate({scrollTop: '0px'}, 800);
}
);
});
</script>
Thanks!
you call jquery earlier announcements of jquery on line 30
<script>$('#nav Li: has (ul)').doubleTapToGo ();</script>
insert this line after the call jquery
Your code is too complex, try this:
$(document).ready(function(){
//Check to see if the window is top if not then display button
$(window).scroll(function(){
if ($(this).scrollTop() > 100) {
$('.scrollToTop').fadeIn();
} else {
$('.scrollToTop').fadeOut();
}
});
//Click event to scroll to top
$('.scrollToTop').click(function(){
$('html, body').animate({scrollTop : 0},800);
return false;
});
});
".scrollToTop" is the thing to be clicked that scrolls back to the top of the page.
function dropdownHover() {
jQuery('ul.nav li.dropdown').hover(function() {
jQuery(this).find('.dropdown-menu').stop(true, true).delay(200).fadeIn();
}, function() {
jQuery(this).find('.dropdown-menu').stop(true, true).delay(200).fadeOut();
});
}
$(window).on('resize', function(event){
var windowSize = $(window).width();
if(windowSize > 992){
dropdownHover();
}
});
I need this function dropdownHover() to fire only when window is greater than 992px, both on load and on resize, else if window is < 992px, both on load or on resize i dont want to fire this function on hover i want regular bootstrap dropdown on click. I tried to do this with css but i cant add animation on dropdown because its just display: none/block. I also tried to add class on resize to fire this function if element has that class else dont but it doesnt work either.
Edit: Final working version
$('.dropdown').on('mouseenter', function(){
if(!$(this).is('.open') && $(window).data('wide'))
$('.dropdown-menu', this).dropdown('toggle').hide()
.stop(true, true)
.delay(200)
.fadeIn(function(){
this.style.display = '';
}).find('a').on('touchstart click', function (e) {
e.stopPropagation();
});
}).on('mouseleave', function(){
if($(this).is('.open') && $(window).data('wide'))
$('.dropdown-menu', this).dropdown('toggle');
});
$('.dropdown').on('click', function(e){
if( $(window).data('wide')) {
$('.dropdown-menu', this).dropdown('toggle');
} else {
$('.dropdown-menu', this)
.stop(true, true).slideToggle()
.closest('.dropdown').removeClass('open');
}
});
// not entirely necessary. Not sure which is faster: this or just checking the width in all three places.
$(window).on('resize', function(){
$(window).data('wide', $(window).width() > 992);
// reset the open menues
$('.dropdown').removeClass('open');
$('.dropdown-menu').css({
display: '',
left: '',
position: '',
});
// because we are checking the width of the window, this should probably go here although this really should be a media query style
$('.dropdown-menu.pull-center').each(function() {
var menuW = $(this).outerWidth();
if ($(window).width() > 1000) {
$(this).css({
left: - menuW / 2 + 60 + 'px',
position: 'absolute'
});
} else {
$(this).css({
left: '',
position: ''
});
}
});
}).trigger('resize');
Initial Solution
Your question is twofold. First, you need it to not show the menu at smaller sizes. For that, you check on resize what the window width is. The problem is that it only works once. It triggers the event listeners for hover and it doesn't kill those event listeners if the screen is then larger at some point. For that, you can set a flag. There are a lot of ways to do this, but for my answer, I've chosen to use jQuery .data() method.
$(window).on('resize', function(event){
var windowSizeWide = $(window).width() > 600; // reduced for testing purposes
jQuery('ul.nav li.dropdown').data('dropdown-enabled', windowSizeWide);
}).trigger('resize');
Then when we listen for the hover events (which are mouseenter and mouseleave events), we simply return out of the function if the screen is too small.
jQuery('ul.nav li.dropdown').on('mouseenter', function() {
if(!jQuery(this).data('dropdown-enabled')) return;
jQuery(this).find('.dropdown-menu').stop(true, true).delay(200).fadeIn();
}).on('mouseleave', function() {
if(!jQuery(this).data('dropdown-enabled')) return;
jQuery(this).find('.dropdown-menu').stop(true, true).delay(200).fadeOut();
}).find('.dropdown-menu').hide();
Finally, you also want the event to trigger on load. You can do that by simply adding .trigger('resize') as seen in the first snippet. You can see a functioning demo here: http://jsfiddle.net/jmarikle/xw9Ljshu/
Possible Alternative Solution
Alternatively, you can also use CSS to handle this with media queries. The simplest way to do this is to force display: none on smaller screens. I don't recommend completely hiding the element because it becomes inaccessible at that point, but this is the general idea:
#media(max-width: 600px) {
ul.dropdown-menu {
display:none !important;
}
}
Note that !important is used because jQuery adds inline styles when you fadeIn or fadeOut.
Second demo: http://jsfiddle.net/jmarikle/xw9Ljshu/1
window.screen.availWidth to get the window size. i am yet not tested your code.But i think this will ok.
function dropdownHover() {
jQuery('ul.nav li.dropdown').hover(function() {
jQuery(this).find('.dropdown-menu').stop(true, true).delay(200).fadeIn();
}, function() {
jQuery(this).find('.dropdown-menu').stop(true, true).delay(200).fadeOut();
});
}
$(document).ready(function(){
$(window).on('resize', function(event){
var windowSize = window.screen.availWidth;
if(windowSize > 992){
dropdownHover();
}
});
})
JQuery Accordion
(function(jQuery){
jQuery.fn.extend({
accordion: function() {
return this.each(function() {
var $ul = $(this);
if($ul.data('accordiated'))
return false;
$.each($ul.find('ul'), function(){
$(this).data('accordiated', true);
$(this).hide();
});
$.each($ul.find('a'), function(){
$(this).click(function(e){
//if(!$(this).hasClass('Active')) {
activate(this);
return void(0);
//}
});
});
var active = $('.Active');
if(active){
activate(active, 'toggle');
$(active).parents().show();
}
function activate(el,effect){
if (!effect) {
$(el)
.toggleClass('Active')
.parent('li')
.siblings()
.find('a')
.removeClass('Active')
.parent('li')
.children('ul')
.slideUp('fast');
}
$(el)
.siblings('ul')[(effect || 'slideToggle')]((!effect)?'fast':null);
}
});
}
});
})(jQuery);
Calling Accordion
$('.Menu.Open').accordion();
The Problem
.Menu.Open is inside of .SideNav of which I want to get the new height after my accordion has collapsed/expanded content to set the height of .Main
I've been looking into timers and timed events however I just cannot get this to work after my accordion has expanded and feel my attempts are completely wrong, I'd hate to flood this page with them all!
Looking at your code, you are relying on Jquery.slideUp/slideDown to expand/collapse your accordion. If I understood you correctly you are trying to measure height after the animation is complete. I believe this is what you are looking for
$('element').slideUp('fast', function(){ perform_measurement_here();});
Also, for your reference
http://api.jquery.com/slideup/
So, i have some animation actions, this is for my login panel box:
$('.top_menu_login_button').live('click', function(){
$('#login_box').animate({"margin-top": "+=320px"}, "slow");
});
$('.login_pin').live('click', function(){
$('#login_box').animate({"margin-top": "-=320px"}, "slow");
});
now i need to add some hiding action after click on body so i do this:
var mouse_is_inside = false;
$('#login_box').hover(function () {
mouse_is_inside = true;
}, function () {
mouse_is_inside = false;
});
for stop hiding this element on body click, and this for body click outside by login-box
$("body").mouseup(function () {
if (!mouse_is_inside) {
var login_box = $('#login_box');
if (login_box.css('margin-top','0')){
login_box.stop().animate({"margin-top": "-=320px"}, "slow");
}
}
});
Everything is fine but this panel animates after each body click, how to stop this and execute only one time? Depend on this panel is visible or not?
You'd normally do this sort of thing by checking if the click occured inside the element or not, not by using mousemove events to set globals :
$(document).on('click', function(e) {
if ( !$(e.target).closest('#login_box').length ) { //not inside
var login_box = $('#login_box');
if ( parseInt(login_box.css('margin-top'),10) === 0){
login_box.stop(true, true).animate({"margin-top": "-=320px"}, "slow");
}
}
});
And live() is deprecated, you should be using on().
The idea is to move a div downwards slightly when hovered and when clicked to move further down to reveal content. The problem is that when you have clicked the div and it moves down you are no longer hovering on it so it performs the 'close when not hovered function.
$(function () {
$('.more').hover(function () { //Open on hover
$('#pull_down_content').animate({
'top': '-360px'
}, 1000);
}, function () { //Close when not hovered
$('#pull_down_content').animate({
'top': '-380px'
}, 1000);
});
});
$('.more').click(function () { //Move down when clicked
$('#pull_down_content').animate({
'top': '0px'
}, 1000);
});
Put a class on the element to signify that it has been clicked, and do not close it if it has that class:
$(function() {
$('.more').hover(function(){ //Open on hover
$('#pull_down_content').animate({'top':'-360px'},1000);
},
function(){ //Close when not hovered
if (!$('#pull_down_content').hasClass("expanded"))
$('#pull_down_content').animate({'top':'-380px'},1000);
});
});
$('.more').click(function(){ //Move down when clicked
$('#pull_down_content').addClass("expanded").animate({'top':'0px'},1000);
});
Of course you now need another trigger to determine when exactly to undo the hover animation after the item has been clicked; how to do that exactly depends on the effect you want to achieve.
The problem is that when you have clicked the div and it moves down
you are no longer hovering on it so it performs the 'close when not
hovered function.
I'm not sure I get it? You do know that the element with the bound events is not the same as the one that you are animating ?
Anyway, something like this maybe:
$(function() {
$('.more').on('mouseenter mouseleave click', function(e) {
if (!$(this).data('clicked')) {
var Top = e.type==='mouseenter' ? '-360px' : e.type==='click' ? '0px' : '-380px';
$('#pull_down_content').stop().animate({'top': Top}, 1000);
if (e.type==='click') $(this).data('clicked', true);
}else{
if (e.type==='click') {
$(this).data('clicked', false);
$('#pull_down_content').stop().animate({'top': '-380px'}, 1000);
}
}
});
});
FIDDLE