jQuery .not() not working properly - javascript

I've looked around and researched why this isn't working, but it seems that I am in a sort of different situation.
I have a default action for a navigation item that handles the navigation animation on hover:
$('.logoCont').hover(function(){
someFunction()...
}, function (){
someFunctionReverse()...
});
Now, when it comes to being on the mobile screen, I hide the navigation and place a button there. The button then controls the animation of the menu sliding out from the side. I've added a line of code that adds a class to the navigation elements when this button is clicked.
$('.mobile-menuButton').click(function(){ //When you click the menu-show button
if($(this).hasClass('menuClosed')){ //Check to see if the menu is closed
$('.nav_hover').addClass('mobile_open'); //Add the mobile_open class to the navigation items
} else {
$('.nav_hover').removeClass('mobile_open'); //remove it
}
});
So then I changed the first hover function to say:
$('.nav_hover').not('.mobile_open').hover(function(){
someFunction()...
}, function (){
someFunctionReverse()...
});
I was hoping this would stop the someFunction() from happening when the mobile menu is out.
You can view what I'm doing HERE - When you reduce the screen to under 540px the media query will take effect and you can click on the menu button.
Documentation on .not() HERE. The second example at the end of the page is exactly what I was hoping for.

The class is added later and the event handler is attached to any and all elements that match the selector at pageload (or whenever it is executed) and doesn't really care about what you add later.
You have to check for the class inside the event handler
$('.nav_hover').hover(function(){
if ( !$(this).hasClass('mobile_open') ) {
someFunction()...
}
}, function (){
if ( !$(this).hasClass('mobile_open') ) {
someFunctionReverse()...
}
});
delegation could also work, but it wouldn't really work with not() or hover()
$(document).on({
mouseenter: function() {
someFunction()...
},
mouseleave: function() {
someFunctionReverse()...
}
}, '.nav_hover:not(.mobile_open)');

Related

Changing Bootstrap panel CSS class for "active" panel (clicked/focused)

I have a page with multiple Bootstrap panels, and I want to make it so that only the "active" panel has the panel-primary class (so, highlighted, in a sense). The definition of "active" in this case is that the user has clicked anywhere inside a panel or changed focus with keyboard or something.
So, I started with this:
function highlightActivePanel($activePanel) {
$('.panel-primary').toggleClass('panel-primary panel-default');
$activePanel.toggleClass('panel-default panel-primary');
}
$(document).on('click', '.panel-default', function () {
highlightActivePanel($(this));
});
The trouble is, I have a table with jquery DataTables plugin inside the panels. So, if I register the click event, it generally works, but not when you click on of the DataTables paging number buttons at the bottom of the panel for some reason. The click even doesn't fire. Probably due to DT's own click events, I'm guessing.
So, I then tried the focus event:
$(document).on('focus', '.panel-default', function () {
highlightActivePanel($(this));
});
... and that works better with clicking on DataTables buttons and fields, but doesn't work if the user simply clicks on the text (or in a table cell) inside a panel.
Finally, if I just simply leave both event listeners registered, it seems to work, but I'm wondering if this is smart, or if there is a better/cleaner way of doing this?
$(document).on('click', '.panel-default', function () {
highlightActivePanel($(this));
});
$(document).on('focus', '.panel-default', function () {
highlightActivePanel($(this));
});
Here's a JsFiddle that better illustrates what I'm talking about.
Edit: Just realized I can easily combine the two events like this:
$(document).on('click focus', '.panel-default', function () {
highlightActivePanel($(this));
});
But if there is still a better way to do this, let me know.
Clicking on the DataTables paging numbers triggers page.dt, so you could do click page.dt in place of click focus to avoid potentially losing focus to something else on the page (though you could also do that by using a more specific selector).

Bootstrap dropdown menu – stay open if search bar is focused

I am trying to create a customized bootstrap dropdown menu that opens and closes on hover (which I have working), but also stays open if the search bar is focused in the Events dropdown menu until it loses focus or the users clicks away from the dropdown.
Here is my js code:
$('ul.nav li.dropdown').hover(function() {
$(this).closest('.dropdown-menu').show(); $(this).addClass('open'); },
function() {
$("#search-query").focusin(function() {
$('.events').addClass('search-active');
});
if ($('.events').hasClass('search-active')) {
return;
} else {
$(this).closest('.dropdown-menu').hide(); $(this).removeClass('open');
}
});
Here is a codepen so you can see the rest of my code: http://codepen.io/webinsation/pen/bfDsB
I have tried several different ways to solve this using jquery’s is(':focus') selector with no results.
I appreciate any help or ideas you may have.
Thanks,
– Caleb
You can use :focus to find if the search box has focus in the second hover function, without any need to give things additional events. .size() will return 1 if it has focus and 0 otherwise, and then the ! casts those to true and false, respectively, before negating. Then in the first hover function, check to make sure there are no currently open menus before opening.
$('ul.nav li.dropdown').hover(function() {
if (!$(".dropdown-menu:visible").size()) {
$(this).closest('.dropdown-menu').show(); $(this).addClass('open');
}
},
function() {
if (!$(".navbar-search input:focus").size()) {
$(this).closest('.dropdown-menu').hide(); $(this).removeClass('open');
}
});
CodePen demo
I'll have my try.
I've used the hover() function and it's callback.
function () {
if (!$("#search-query").is(':focus')){
$(this).removeClass('open');
} else if ( !$( '.events' ).is( ':hover' ) ) {
$("#search-query").blur();
$('.dropdown-menu').hide();
}
});
on hover it's pretty much the same, You can set it back to closest as it was before.
On the callback (no hover) I check if not the .events gets hovered (so it'll show each of the other menu items drop down menus and also hiding the .events menu when hover removed. (you can set it to click if you want).
Here is a Fiddle, Hope it assists.

Hide and show menu with the same button using jquery

I have found a tutorial on some dropdown menu using jquery. It works fine but I want to adjust it just a little. Instead of hiding the menu using hovering, I want to have the same button that showed the menu, to hide it when it is being pressed again. So the same button has to both hide and show the dropdown menu.
The script that im using:
$(document).ready(function () {
$("ul.subnav").parent().append("<span></span>"); //Only shows drop down trigger when js is enabled - Adds empty span tag after ul.subnav
$("ul.topnav li span").click(function () { //When trigger is clicked...
//Following events are applied to the subnav itself (moving subnav up and down)
$(this).parent().find("ul.subnav").slideDown('fast').show(); //Drop down the subnav on click
$(this).parent().hover(function () {
}, function () {
$(this).parent().find("ul.subnav").slideUp('slow'); //When the mouse hovers out of the subnav, move it back up
});
//Following events are applied to the trigger (Hover events for the trigger)
}).hover(function () {
$(this).addClass("subhover"); //On hover over, add class "subhover"
}, function () { //On Hover Out
$(this).removeClass("subhover"); //On hover out, remove class "subhover"
});
});
Use jQuery's .toggle() http://api.jquery.com/toggle/
$("#yourbutton").click(function() {
$("#yourmenu").toggle();
});
You can save yourself from adding a CSS rule by using jQuery's .toggle method.
$('#yourMenu').toggle()
This will hide it if it's visible, and show it if it's hidden. You can add a number or 'fast', 'slow' as a parameter to make it animate.
jQuery.toggle() function will do this work for you:
$("#button").on('click', function() {
$("#menu").toggle();
});
Yes, toggleClass can be used. Or you can also define your own toggle function in javascript.
you can toggle between the classes or do any other function you want to.
function tog(elemen){
if(elemen.className == "show") {
hide drpdwn
elemen.className="hide";
} else {
make dropdwn visible
elemen.className="show";
}
}

How to prevent the parent div from registering the click when a child class is clicked; event.stopPropagation(); doing funny things

We've got the classic problem with a div's child getting clicked and the parent's click event gets triggered as well. I've got a button set within a container that expands and unexpands upon clicking.
The button, when clicked, should:
Unexpand the container
Hide the container's description
The two click functions are given below:
var $NotificationContainer = $("#NotificationContainer");
$NotificationContainer.append('<div class="Notification" title="'+title+'"></div>');
var $thisNotification = $NotificationContainer.children('.Notification[title='+uniqueTitle+']');
$thisNotification.append('<div class="NotificationDescription">'+uniqueDescription+'</div>');
$(".NotificationDescription").hide();
// Button used to close an expanded notification
$thisNotification.append("<div class='NotificationCloseButton'></div>");
$('.NotificationCloseButton').hide();
$thisNotification.click(function()
{
$(this).animate({height:250}, 1000);
$(this).find('.NotificationDescription').slideToggle('fast');
$(this).find('.NotificationCloseButton').slideToggle('fast');
});
$(".NotificationCloseButton").click(function()
{
$thisNotification.animate({height:50}, 1000);
$(this).find('.NotificationDescription').slideToggle('fast');
$(this).find('.NotificationCloseButton').slideToggle('fast');
});
What I find with this code is that when clicking the close button:
SlideToggles the description to be hidden
SlideToggles the close button to be hidden
The container unexpands, but then re-expands (contents still hidden)
The $thisNotification click is being called (I think).
Now, when I try to use event.stopPropagation(); or a simple return false; in the closeButton's click, I get very interesting results.
Clicking the close button with either of the above additions now:
Unexpands the container
The description and button remain present, and do not slideToggle at all.
Code snippets of the exact way I implemented stopPropogation and return false:
$(".NotificationCloseButton").click(function(event)
{
event.stopPropagation();
$thisNotification.animate({height:50}, 1000);
$(this).find('.NotificationDescription').slideToggle('fast');
$(this).find('.NotificationCloseButton').slideToggle('fast');
});
and
$(".NotificationCloseButton").click(function()
{
$thisNotification.animate({height:50}, 1000);
$(this).find('.NotificationDescription').slideToggle('fast');
$(this).find('.NotificationCloseButton').slideToggle('fast');
return false;
});
You have click bindings for a the parent object:
$thisNotification
and for a child object:
$(".NotificationCloseButton")
When you click the close button, the 'click' event is being fired for both handlers, all animations are queued, and you get the undesirable closes-then-opens action.
You have a few options to resolve this. #1 is to unbind the parent click handler and rebind it after the close button is clicked.
$thisNotification.click(function()
{
notificationClickHandler(); //animations are separated from bindings
$thisNotification.unbind('click');
});
Alternately, jQuery has a .clearQueue() method that removes all queued animations. This might have side-effects when users are quick with the mouse, or if your page is heavy on jQuery animations, so you'll have to experiment with the appropriate level of scope for your application.
$(".NotificationCloseButton").click(function()
{
$thisNotification.animate({height:50}, 1000);
$(this).find('.NotificationDescription').slideToggle('fast');
$(this).find('.NotificationCloseButton').slideToggle('fast');
$.clearQueue();
});

jQuery - Toggle a panel closed on click of outside element, only if panel is visible

I'm working on this site: http://dev.rjlacount.com/treinaAronson/index.php
My final to-do is to set the contact panel (which you can see if you click the top left "contact" button) to close if it's currently open and the user either clicks outside of the panel (in the "#content" area) or hits the esc key.
I figured the clicking in the #content area trigger would be the easier of the two, so I started with that. I've read a couple threads on triggering functions only if elements are visible, but what I've come up with so far isn't working at all:
$("#panel").is(":visible") {
$("#content").click(function(){
$("#panel").slideToggle("3000");
});
};
This breaks the functionality of the contact button, and I've tried several variations of this to no avail. Am I making any glaring errors here? Any advice would be greatly appreciated.
Thanks!
Bind Click and Keydown functions to the document and make sure the click function doesn't bubble up to the document when your panel or flip buttons are clicked. Like so:
$(document).bind({
keydown:function(e) {
if (e.keyCode == 27 ) {
$("#panel").slideUp("3000");
}
}, click: function(e) {
$("#panel").slideUp("3000");
}
});
$('#flip, #panel').bind('click', function(e){return false});
Why don't you add a class to the body of the page when the panel is opened and remove it when it's closed? That makes this much simpler:
$('.class #content').click(function(){
// Close the contact panel
});
Now, when the body has a class of 'class', any click on the #content div will automatically close contact.
Make sense? Great looking site, by the way.
$('#flip').bind('click', function(){
$(this).toggleClass('contactOpen');
$("#panel").slideToggle("3000");
});
$('#content').bind('click', function(){
if($('#flip').hasClass('contactOpen')){
$(this).toggleClass('contactOpen');
$("#panel").slideToggle("3000");
}
});

Categories

Resources