I have a drop down menu that has different heights based on a selection of classes - one-row, two-row, three-row.
The main content of the site also animates down depending on these classes.
I have also implemented a function that makes the menu reset if the user clicks outside of it.
Everything is working as required other than the fact the I cannot use 'toggleClass' to make the menu close if the link is clicked again.
Can any of you JQuery gurus help me out here?
// ============================================================
//
// DROP DOWN MENU
//
// ============================================================
$('.submenu-toggle').on('click', function (e) {
// Reset all other drop downs and icons
$('.submenu').removeClass('drop-down');
$('.submenu-toggle').find('.fa-angle-down').removeClass('rotate');
// Drop down this menu
$(this).find('.submenu').addClass('drop-down');
// Rotate the icon
$(this).find('.fa-angle-down').addClass('rotate');
// Drop the main content wrapper down depending on the
// number of rows in the drop-down menu
if ($(this).find('.submenu').hasClass('one-row')) {
$('.content-wrapper').addClass('one-row-drop-down');
$('.content-wrapper').removeClass('two-row-drop-down three-row-drop-down four-row-drop-down');
}
if ($(this).find('.submenu').hasClass('two-row')) {
$('.content-wrapper').addClass('two-row-drop-down');
$('.content-wrapper').removeClass('one-row-drop-down three-row-drop-down four-row-drop-down');
}
if ($(this).find('.submenu').hasClass('three-row')) {
$('.content-wrapper').addClass('three-row-drop-down');
$('.content-wrapper').removeClass('one-row-drop-down two-row-drop-down four-row-drop-down');
}
e.stopPropagation();
});
// Reset dropdowns and reset icon on click outside
$(document).on('click', function () {
$('.submenu').removeClass('drop-down');
$('.submenu-toggle').find('.fa-angle-down').removeClass('rotate');
$('.content-wrapper').removeClass('one-row-drop-down two-row-drop-down three-row-drop-down');
});
You need to use jquery toggle
http://api.jquery.com/toggle/
See here some examples http://api.jquery.com/toggle/#entry-examples
$( "#foo" ).toggle( display );
is equivalent to:
if ( display === true ) {
$( "#foo" ).show();
} else if ( display === false ) {
$( "#foo" ).hide();
}
Related
This is more of a tip than a question, but i hope others find this useful.
Basically i needed to make the lightbox slider called 'Swipebox' auto transition to the next slide, I looked online for help but found nothing.
to add this feature to the plugin i added this code:
setInterval(function(){
$this.getNext(); // Auto transitions each slide
}, 5000);
The file for this JS is called 'jquery.swipebox.js'. This is the code where you want to place the code previously mentioned:
/**
* Navigation events : go to next slide, go to prevous slide and close
*/
actions : function () {
var $this = this,
action = 'touchend click'; // Just detect for both event types to allow for multi-input
if ( elements.length < 2 ) {
$( '#swipebox-bottom-bar' ).hide();
if ( undefined === elements[ 1 ] ) {
$( '#swipebox-top-bar' ).hide();
}
} else {
$( '#swipebox-prev' ).bind( action, function( event ) {
event.preventDefault();
event.stopPropagation();
$this.getPrev();
$this.setTimeout();
} );
$( '#swipebox-next' ).bind( action, function( event ) {
event.preventDefault();
event.stopPropagation();
$this.getNext();
$this.setTimeout();
} );
}
$( '#swipebox-close' ).bind( action, function() {
$this.closeSlide();
} );
// THIS IS THE NEW CODE ADDED:
setInterval(function(){
$this.getNext(); // Auto transitions each slide
}, 5000);
},
This function is around about 550 lines down.
Also, to make the slideshow loop back around, you will need to change the option called 'loopAtEnd' from FALSE to TRUE. This is located at the top of the document.
loopAtEnd: true,
Hope this helped :)
I have a html page with over 1500 element !!!
and a menu .
when I click somewhere on document , the page locked for over 2 seconds (at least).
After some search I found this block of code in JQuery.UI :
// Clicks outside of a menu collapse any open menus
this._on( this.document, {
click: function( event ) {
if ( !$( event.target ).closest( ".ui-menu" ).length ) {
this.collapseAll( event );
}
// Reset the mouseHandled flag
this.mouseHandled = false;
}
});
the if statement fires over and over and it become problem .
How this could fix ?!
I was just wondering if there is a better way to do this:
// Show/hide filters on mobile //
$('#openMobileFilters').click(function(){
$('.navbar-inverse').addClass("hidden-xs");
$('#results-container').addClass("hidden-xs");
$('#filter-column').removeClass("hidden-xs");
});
$('.closeFilters').click(function(){
$('#results-container').removeClass("hidden-xs");
$('.navbar-inverse').removeClass("hidden-xs");
$('#filter-column').addClass("hidden-xs");
});
All it does is hide a load of stuff onclick and show a filters div. Then closes it when the user clicks the .closeFilters link.
How about using toggleClass method
// Show/hide filters on mobile //
$('#openMobileFilters').click(function(){
showOrHideFilter(true);
});
$('.closeFilters').click(function(){
showOrHideFilter(false);
});
function showOrHideFilter(show) {
$( "#results-container, .navbar-inverse" ).toggleClass( "hidden-xs", show );
$('#filter-column').toggleClass("hidden-xs", !show);
}
I am using the plugin Imagemapster to add highlighting and tooltip functions to an image map. It provides callbacks like so:
image.mapster(
{
mapKey: 'name',
listKey: 'name',
onClick: function (e) {
if(!$(this).hasClass('clicked')){
$(this).addClass('clicked');
}
$('#selections').html(xref[e.key]);
},
onMouseover: function (e) {
$('#selections').html(xref[e.key]);
},
onMouseout: function (e) {
if(!$(this).hasClass('clicked')){
$('#selections').html('');
}
},
});
Here is my example:
http://jsfiddle.net/5scbh/6/
If you click an item, I want that item's tooltip to remain displayed even if you mouseout. I'm sort of there, but the problem is: if you click an item, and then mouseover another area and then mouseout... it doesn't keep the clicked item's tooltip on mouseout.
I like that the tooltip changes on mouseover to whatever you rollover, but once you mouseout of that area or the imagemap, I want it to go back to showing the tooltip of whatever area has been clicked. If you unclick the clicked area so that nothing is clicked, then the tooltip should go away.
Can you help me do this? Thank you.
You can store your current tooltip in a data attribute, then write it back on mouse out.
...
onClick: function (e) {
if(!$(this).hasClass('clicked')){
$(this).addClass('clicked');
}
$('#selections').html(xref[e.key]);
$( '#selections' ).data( 'storage', xref[e.key] );
},
...
onMouseout: function (e) {
if(!$(this).hasClass('clicked')){
$('#selections').html('');
}
if( $( '#selections' ).data( 'storage' ) ) {
$( '#selections' ).html( $( '#selections' ).data( 'storage' ) );
};
},
....
updated your fiddle acordingly.
Here is the updated fiddle, using the correct edits provided by #robotroll, as well as the solution to the selecting/deselecting issue described in my comment above.
That part was solved by using this code:
onClick: function (e) {
if (e.selected) {
$(this).addClass('clicked');
$('#selections').html(xref[e.key]);
$('#selections').data( 'storage', xref[e.key] );
} else {
$(this).removeClass('clicked');
$('#selections').removeData();
$('#selections').html('');
}
},
http://jsfiddle.net/5scbh/10/
I am having a bit of trouble combining the HOVER and FOCUS events with jquery. This is what I had originally:
$("input,textarea").focus(function () {
$(this).parent().siblings('div.exp').removeClass('hide');
$(this).parent().siblings('div.exp').addClass('show');
});
$("input,textarea").blur(function (){
$(this).parent().siblings('div.exp').removeClass('show');
$(this).parent().siblings('div.exp').addClass('hide');
if ($(this).val().length <= 0) {
$(this).siblings('span.warning').removeClass('hide');
$(this).siblings('span.warning').addClass('show');}
else {
$(this).siblings('span.warning').removeClass('show');
$(this).siblings('span.warning').addClass('hide');
}
});
Basically, I have a user contact form with rows like the one below:
<div class="row">
<p><label>Your Name</label><input type="text" name="name" id="name" value=""/><span class="warning">Your name is missing</span></p>
<div class="exp">Who am I to address?</div>
</div>
The point of my Jquery code is to bring forth a hidden div (exp) when the user focuses any one input or textarea element as well as checking if the value of said input is not empty when unfocusing (blur) the element. (I haven't really gotten down to validation yet so checkin for the string length right now is just a temporary filler). Should the element have a string smaller or equal than 0, then span.warning is to be 'shown' to the user.
This is all working nicely.
Where I get stuck is the following:
I want to add in hover but without conflicting with focus. My desired final effect is this:
You hover any input or textarea and you get the div.exp to show up (exp is for explanation). You focus any input or area and the div.exp stays there, even if you go about hovering any other inputs or textareas. Should you hover an input that is already focused, nothing should happen.
So, in a nutshell, the focus and hover elements should work 'independently' so to speak. Not sure if I made myself clear but oh well, I tried =)
Cheers
G
Your code can be significantly shortened by using .hide() and .show() and chaining the events. I posted a demo here.
$(document).ready(function(e){
// hide all explanations and warnings
$('.exp, .warning').hide();
// add focus, blur and hover events to all inputs & textareas
$('input,textarea')
// if focused, show the explanation
.focus(function(){
// show explanation on focus (and add a class so the hover function knows not to hide it
$(this).addClass('focused').closest('.row')
.find('.exp').show()
.find('.warning').hide();
})
.blur(function(){
// hide explanation on blur
$(this).removeClass('focused').closest('.row').find('.exp').hide();
if ($(this).val().length < 1) {
// input is empty, show the warning
$(this).closest('.row').find('.warning').show();
} else {
// input is not empty, hide the warning... you might want to add the validation here
$(this).closest('.row').find('.warning').hide();
}
})
.hover(function(){
// show explanation when hovered
$(this).closest('.row').find('.exp').show();
},function(){
// hide explanation if the input is not focused
if ($(this).is(':not(.focused)')) $(this).closest('.row').find('.exp').hide();
})
});
You can set a flag to the input or textarea while it is focused to avoid conflict with your hover event. If the flag is set to true when the over or out event is fired, its code is not executed. The following code show the idea (I have not test it).
$("input,textarea").focus( function()
{
$(this).parent().siblings( 'div.exp' ).removeClass( 'hide' ).addClass( 'show' );
$(this).data( "hasFocus", true );
} );
$("input,textarea").blur(function()
{
$(this).parent().siblings( 'div.exp' ).removeClass( 'show' ).addClass( 'hide' );
if( $(this).val().length <= 0 )
$(this).siblings( 'span.warning' ).removeClass( 'hide' ).addClass( 'show' );
else
$(this).siblings( 'span.warning' ).removeClass( 'show' ).addClass( 'hide' );
$(this).data( "hasFocus", false );
});
$("input,textarea").hover( function()
{
// Over event
if( typeof $(this).data( "hasFocus" ) != undefined && !$(this).data( "hasFocus" ) )
$(this).parent().siblings( 'div.exp' ).removeClass( 'hide' ).addClass( 'show' );
},
function()
{
// Out event
if( typeof $(this).data( "hasFocus" ) != undefined && !$(this).data( "hasFocus" ) )
$(this).parent().siblings( 'div.exp' ).removeClass( 'show' ).addClass( 'hide' );
} );