jQuery - hover to show sidebar, but an option to lock it - javascript

I have a side bar which when you mouseover it slides over the content, when you mouseout it slides back. All working great.
I then have a button which when you click it, it locks the sidebar in place, pushing the content behind over. Locking the sidebar in place. Also works great..
My problem is that I wish for when the sidebar to be locked, to disable the hover, and keep it in the expanded state, then when you unlock it, to go back and re-enable hovering.
Fiddle
Thanks
$('.sec-sidebar-toggle').click(function (e) {
e.preventDefault();
if ($(this).closest('.sec-sidebar').hasClass('sidebar-locked')) {
//unlocked
$(this).closest('.sec-sidebar').removeClass('sidebar-locked');
$(this).closest('.sec-sidebar').stop().animate({
width: '38px'
}, 300).css({
'overflow': 'visible'
});
} else {
//locked
$(this).closest('.sec-sidebar').addClass('sidebar-locked');
$(this).closest('.sec-sidebar').stop().animate({
width: '253px'
}, 300).css({
'overflow': 'visible'
});
}
});
//Hover
$('.sec-sidebar').mouseover(function () {
$(this).find('.sec-nav').stop().animate({
marginLeft: '0px'
}, 300);
}).mouseout(function () {
$(this).find('.sec-nav').stop().animate({
marginLeft: '-215px'
}, 300);
});

You can unbind the mouseover and mouseout events.
http://jsfiddle.net/3n1gm4/VEUe9/
$('.sec-sidebar-toggle').click(function(e){
e.preventDefault();
if( $(this).closest('.sec-sidebar').hasClass('sidebar-locked') ){
//unlocked
$(this).closest('.sec-sidebar').removeClass('sidebar-locked');
$(this).closest('.sec-sidebar').stop().animate({width: '38px'}, 300).css({'overflow': 'visible'});
// ADD EVENT HANDLERS
setupHover();
} else{
//locked
$(this).closest('.sec-sidebar').addClass('sidebar-locked');
$(this).closest('.sec-sidebar').stop().animate({width: '253px'}, 300).css({'overflow': 'visible'});
// REMOVE EVENT HANDLERS
$('.sec-sidebar').unbind('mouseover');
$('.sec-sidebar').unbind('mouseout');
}
});
function setupHover() {
//Hover
$('.sec-sidebar').mouseover(function(){
$(this).find('.sec-nav').stop().animate({marginLeft: '0px'}, 300);
}).mouseout(function(){
$(this).find('.sec-nav').stop().animate({marginLeft: '-215px'}, 300);
});
}
setupHover();

I have wrapped the mouseout function in an IF statement to check whether the sidebar has the sidebar-locked class. If it does the following animation will not be executed.
if(!$('.sec-sidebar').hasClass('sidebar-locked')){
$(this).find('.sec-nav').stop().animate({marginLeft: '-215px'}, 300);
}
Is this what you were hoping to achieve?
Here is the JsFiddle.
Note: The ! at the start of the IF statement is to say IF NOT. So, If not this class in the above example.

There are two easy solutions in my head.
1: You could check the classes of the sidebar if 'sidebar-locked' is present with .hasClass() in the mouseevents.
2: You could remove the mouse events completely by unbinding them when you lock it and rebinding them when you unlock it.
See jQuery API: unbind.
Sidenote:
Consider using the hover event instead of the two seperate mouse events.

You should to clear mouseover event handler, and reassign it back when it needs.
Remove an event handler.

Related

jQuery :visible working but :hidden does not

I'm working on this website.
Here is the code for the menu trigger on the left sidebar:
jQuery(document).ready( function(){
jQuery('.nav-animate nav').hide('slide', 500);
jQuery('.nav-animate').hide();
jQuery(".x-btn-navbar").click(function(){
jQuery('#dimmer').fadeToggle(500);
jQuery('.nav-animate').fadeToggle(500);
jQuery('.nav-animate nav').toggle('slide', {direction: "left"}, 750);
// I am trying to show only the middle line when the navigation is closed
// and change the `.menu-p` text by checking whether the navigation has
// display:none or display:block, like this:
if(jQuery(".nav-animate").is(":visible")) {
jQuery("span.line.top").css('background-color', '#fff');
jQuery('span.line.bottom').css('background-color', '#fff');
jQuery('.menu-p').html('CLOSE')
}
// The above part works perfectly, however the part below doesn't:
if(!jQuery(".nav-animate").is(':visible')) {
alert('hidden');
jQuery('span.line.top').css('background-color', '#262628');
jQuery('span.line.bottom').css('background-color', '#262628');
jQuery('.menu-p').html('MENU');
}
});
});
I tried using if(jQuery(".nav-animate").is(":hidden")) {//...}, and if(jQuery(".nav-animate").css('display') == 'none') {//...} but both doesn't work.
My guess, when you click to "CLOSE" it does the :visible or :hidden check, but the menu is still open at the time you click so it still doesn't have the display:none until the click event performs that. In that case, what can I do?
Thanks in advance for your time and suggestions.
animation related methods will affect the visibility check, so check the state before call to toggle
jQuery(document).ready(function () {
jQuery('.nav-animate nav').hide('slide', 500);
jQuery('.nav-animate').hide();
jQuery(".x-btn-navbar").click(function () {
jQuery('#dimmer').fadeToggle(500);
//negate since fadetoggle will toggle the state
var visible = !jQuery('.nav-animate').stop().is(':visible');
jQuery('.nav-animate').fadeToggle(500);
jQuery('.nav-animate nav').toggle('slide', {
direction: "left"
}, 750);
// I am trying to show only the middle line when the navigation is closed
// and change the `.menu-p` text by checking whether the navigation has
// display:none or display:block, like this:
if (visible) {
jQuery("span.line.top").css('background-color', '#fff');
jQuery('span.line.bottom').css('background-color', '#fff');
jQuery('.menu-p').html('CLOSE')
} else {
// The above part works perfectly, however the part below doesn't:
alert('hidden');
jQuery('span.line.top').css('background-color', '#262628');
jQuery('span.line.bottom').css('background-color', '#262628');
jQuery('.menu-p').html('MENU');
}
});
});
Just add condition else on one your block condition right.. It's mean will be run if first condition block not true.
if(!jQuery('.nav-animate').stop().is(':visible')) {
jQuery("span.line.top").css('background-color', '#fff');
jQuery('span.line.bottom').css('background-color', '#fff');
jQuery('.menu-p').html('CLOSE')
}
else{
// to do
}

why is the click function not working?

here is my fiddle
the '.item' click function that shows the '.pull_down_content' doesn't always work why is this?
i've found that if you click the first 'tile' this will work fine and whilst that is open click the next tile still works fine but if you then go back to the original tile the click function stops working and only the hover works?
why is this?
here is part of my code..
$(this).children('.item').on('mouseenter mouseleave click', function(e) { e.stopPropagation();
if ($('.timelineTile').hasClass("clicked")) {
if (!$(this).data('clicked')) {
var Height = e.type==='mouseenter' ? '60px' : e.type==='click' ? '300px' : '0px';
$(this).siblings('.pull_down_content').stop().animate({'height': Height}, 300);
$(this).siblings('.pull_down_content').children('.inner').css({'display': 'block'}, 300);
if (e.type==='click') $(this).data('clicked', true);
}else{
if (e.type==='click') {
$(this).data('clicked', false);
$(this).siblings('.pull_down_content').stop().animate({'height': '0px'}, 300);
$(this).siblings('.pull_down_content').children('.inner').css({'display': 'none'}, 300);
}
} }
});
It looks like you are adding additional click events on the children every time you click on '.timelineTile'. You should move the above code outside of the '.timelineTile' click event. At the very least remove the existing events before re-adding them.

Slide Effects for Tabs Part 2

Ok so my original question got answered and now my slide effect only happens when I click in anywhere in my div region..here is the code:
$(document).ready(function(){
$('#tabs').tabs();
$("#tabs").click(function() {
$(this).effect( "slide", "medium" );
});
});
Now I'm wondering what if somebody wants to copy text from one of my tab regions? Every single time they try to highlight, the tab will slide away. How do I make it so that the tab region only slides when the actualy tab ul is clicked?
Use combination of mousedown and mouseup:
Demo Fiddle
var down=0;
$(document).ready(function(){
$("#tabs").mousedown(function(event){
down=event.clientX+"||"+event.clientY;
});
$("#tabs").mouseup(function(event){
var up=event.clientX+"||"+event.clientY;
if(up==down)
$(this).slideUp("medium" );
});
});
Updated code which prevent slidedown on right-click copy text:
Demo Fiddle 2
var down="||";
$(document).ready(function(){
$("#tabs").mousedown(function(event){
switch(event.which){
case 1:/*Left mouse button pressed*/
down=event.clientX+"||"+event.clientY;
break;
default:/*middle or right mouse button pressed*/
down="||";
}
});
$("#tabs").mouseup(function(event){
var up=event.clientX+"||"+event.clientY;
if(up==down)
$(this).slideUp("medium" );
});
});
You can use the event capturing option on click method. By using that, you can get the element on which the mouse is clicked. And then you can use the target object as below,
$('#tabs').click(function(e){
if(e.target.nodeName == 'P') {
e.stopPropagation();
return;
}
$(this).effect( "slide", "medium" );
});
Hope it will help.

How to prevent mouseenter event action with jQuery

I have this simple mouseenter : mouseleave action:
call = $('.js-call');
call.on({
mouseenter: function(e){
// animation
e.stopPropagation();
},
mouseleave: function(e){
// animation
}
});
In this action i have two CSS animations, which have a duration of 300ms. How can I prevent mouseover event for animation end, and fire it again if i'm properly on call element. When i moving fast on my call element action call many times. How to prevent it? Thx for help.
I would go with placing timeouts on both events, and activate the animation only if at the end of that timeout you still meet a condition. Something like that:
var timeoutIn, timeoutOut, delay = 300;
$element.hover(
function() {
if (timeoutOut){
clearTimeout(timeoutOut);
}
timeoutIn = setTimeout(function() {
// ##################
// 'MOUSEENTER' STUFF GOES HERE
// ##################
}, delay);
},
function() {
if (timeoutIn){
clearTimeout(timeoutIn);
}
timeoutOut = setTimeout(function() {
// ##################
// 'MOUSELEAVE' STUFF GOES HERE
// ##################
}, delay);
}
);
Update: I've just created a jQuery plugin called jQuery.hoverDelay.js, you can check it out here: jQuery hoverDelay.js
what you could do is use .bind( eventType [, eventData ], handler(eventObject) ).
bind the event mouseleave after you're done with the animation and vice versa. this should fix it.
Using jQuery .stop() is the correct approach.
Heres a working fiddle starting and stoping an animation with mouseenter and mousleave, without starting new animation if theres already running one.
http://jsfiddle.net/CZtLe/
function animateMe(element, color) {
element.stop(true).animate({
backgroundColor: color,
duration: 300
});
}
$(function () {
call = $('.js-call');
call.on({
mouseenter: function (e) {
animateMe($(this), '#FF0000');
e.stopPropagation();
},
mouseout: function (e) {
animateMe($(this), '#000000');
}
});
});

Switch between Fade in and Fade out on click

I want to use jQuery to fade in a div when an image is clicked, when the image is clicked again, I want it to hide and so on.
How would I do this?
I basically need a toggle switch.
$('#my_img_selector').click(function(){$('#my_div_selector').fadeToggle()});
Try it out here.
Try also slideToggle() and toggle() in place of fadeToggle().
You have to change the selectors $('#fadeMe') and $('#bindImage') according to your markup. The magic is here
$(document).ready(function(){
$('#bindImage').on('click', function(){
$('#fadeMe').fadeToggle();
//return false; // only useful if you trigger an
});
});
$('#yourimage').on('click', function(event){
if ($("#something").is(':visible')) {
$(".something").hide("drop", {
direction: "up"
}, 2000);
}else{
$(".something").show("drop", {
direction: "up"
}, 2000);
}
});

Categories