Hide menu, when clicking anywhere else than the menu - javascript

I have a menu that appears when I click an icon. Currently I can close it by clicking the 'close' icon, but I would like to be able to close it by clicking anywhere outside of the menu, when the menu is visible.
Here is a jsFiddle: http://jsfiddle.net/budapesti/3v5ym2bp/3/
For example the following doesn't work:
$(document).click(function() {
if($('.menu').is(":visible")) {
$('.menu').hide()
}
});
I found similar questions, such as jQuery: Hide element on click anywhere else apart of the element and How do I detect a click outside an element?, but couldn't get the solutions to work for me.
EDIT: I wonder if is(":visible") works with jQuery "animate"?

call close function on anywhere click on window. And use event bubbling.
i had update it its jsfiddle link is
> http://jsfiddle.net/rahulrchaurasia/3v5ym2bp/19/

Try this : http://jsfiddle.net/3v5ym2bp/13/
html
<div class="inv"></div><!-- Added an invisible block -->
<div class="menu"> <span class="glyphicon glyphicon-remove closed pull-right"></span>
<ul>
<li>Link</li>
<li>Link</li>
<li>Link</li>
</ul>
</div>
<div class="icon-menu"> <span class="glyphicon glyphicon-menu-hamburger"></span>MENU</div>
css
.menu {
position: fixed;
width: 285px;
height: 100%;
left: -285px;
background: #202024;
z-index: 1;
}
.glyphicon-remove, ul {
color: #fff;
padding: 10px;
}
/* Added an invisible block */
.inv {
display:none;
width:100%;
height:100%;
position:fixed;
margin:0;
}
jQuery
"use strict";
var main = function () {
$('.icon-menu').click(function () {
$('.icon-menu').hide();
$('.inv').show(); //added
$('.menu').animate({
left: "0px"
}, 200);
});
//Added
$('.inv').click(function () {
$('.inv').hide();
$('.menu').animate({
left: "-285px"
}, 200);
$('.icon-menu').show();
});
$('.closed').click(function () {
$('.inv').hide();//added
$('.menu').animate({
left: "-285px"
}, 200);
$('.icon-menu').show();
});
};
$(document).ready(main);
Another simple example : http://jsfiddle.net/3v5ym2bp/17/

I suggest you bind an event on document click after menu has been shown, the event that will ensure that every click anywhere outside menu will close it.
$(document).on("click.menu",function(event) {
var target = $(event.target);
if (!target.closest(".menu").length || target.closest(".closed").length) {
closeMenu(function() {
$(document).off("click.menu");
});
}
});
here you'll have to evaluate event object, and what trigger it - which element if it's inside menu (apart from the close button) then don't do nuffing, if outside - then close the menu. All the closing stuff is put to the separate function. also don't forget to unbind this handler from document after closing
http://jsfiddle.net/3v5ym2bp/15/
working demo

Use css attribute left to detect if the menu is visible instead of :visibe because it's bot work with chrome, see jquery .is(“:visible”) not working in Chrome.
You have just to detect if the menu is visible (use the css attribute left) because if the menu css left=0px that mean it's visible, and after that if the click is outside of menu or not and so if outside close it.
Take a look at Your updating fiddle work fine just by adding the following handle that detect outside click :
JS :
$(document).click(function(e) {
//if the menu is visible
if($(".menu").css('left') =="0px"){
//if the click is outside of menu
if($(e.target).closest('.menu').length == 0){
$('.closed').click();
}
}
});

var main = function() {
$('.icon-menu').click(function() {
$('.icon-menu').hide();
$('.menu').animate({
left: "0px"}, 200);
});
$('.closed').click(function() {
$('.menu').animate({
left: "-285px"}, 200);
$('.icon-menu').show();
});
};
$(document).ready(main);
var rahul=0;
$(window).click(function(e) {
$('.menu').animate({
left: "-285px"}, 200);
$('.icon-menu').show();
});
.menu {
position: fixed;
width: 285px;
height: 100%;
left: -285px;
background: #808080;
z-index: 1;
}
.glyphicon-remove, ul {
color: #fff;
padding: 10px;
}
<div class="menu" onclick="event.cancelBubble=true;">
<span class="glyphicon glyphicon-remove closed pull-right"></span>
<ul>
<li>menu1</li>
<li>menu2</li>
<li>menu3</li>
</ul>
</div>
<div class="icon-menu" onclick="event.cancelBubble=true;">
<span class="glyphicon glyphicon-menu-hamburger"></span>*MENUS*
</div>
<script type="text/javascript" src="http://code.jquery.com/jquery-1.4.2.min.js"></script>

Related

Smooth scroll to id except when user is already at that location

I'm running the following script when a user clicks on a button, to scroll to a specific div on the page, along with a few other unrelated functions.
The problem is that the button itself is supposed to always remains in view, and thus can be spam-clicked to cause the page to 'lag' while it's busy moving over and over to the same location. I would like to counter this behavior by only executing the scroll when the page is not already at that specific location.
Unfortunately I have no real experience working with JavaScript/jQuery and have not been able to find an example of something like this being used.
Here's my sample code:
HTML
<div id="navButton">Button</div>
<div id="listContent">Content that must be visible after button click goes here</div>
Script
window.onload=function(){
document.getElementById("navButton").onclick = function(){
$("html, body").animate({scrollTop: $("#listContent").offset().top -165}, 400);
}
}
Maybe this Example could help you... Change the hash first then listen to the hashchange Event. When you reload the page it will scroll down to your anchor.
$(document).ready(function() {
// check for hash when page has loaded
if (getHash() != null) {
checkForScrolling();
}
});
// check for hash when hash has changed
window.onhashchange = function() {
checkForScrolling();
};
// return hash if so or null if hash is empty
function getHash() {
var hash = window.location.hash.replace('#', '');
if (hash != '') {
return hash;
} else {
return null;
}
}
// this function handles your scrolling
function checkForScrolling() {
// first get your element by attribute selector
var elem = $('[data-anchor="' + getHash() + '"]');
// cheeck if element exists
if (elem.length > 0) {
$('html, body').stop().animate({
scrollTop: elem.offset().top
}, 300);
}
}
body {
font-family: Helvetica
}
section {
position: relative;
margin-bottom: 10px;
padding: 20px;
height: 300px;
background-color: #eee;
}
section a {
display: block;
position: absolute;
bottom: 10px;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div>
<h1 data-anchor="start">Smooth Scrolling</h1>
<ul>
<li>Scroll to Anchor 1
</li>
<li>Scroll to Anchor 2
</li>
<li>Scroll to Anchor 3
</li>
</ul>
<section>
<h2 data-anchor="1">First Anchor</h2>
Back to top
</section>
<section>
<h2 data-anchor="2">Second Anchor</h2>
Back to top
</section>
<section>
<h2 data-anchor="3">Third Anchor</h2>
Back to top
</section>
</div>
Try this if worked
<div id="navButton" onclick="moveElement('listContent');">Button</div>
<div id="listContent">Content that must be visible after button click goes here</div>
You will need jquery included for this script code
function moveElement(divId) {
$('html, body').animate({
scrollTop: $("#"+divId).offset().top
}, 2000);
}
And if you see it not working then try by adding below css. It will make gap between button and your div.
#navButton {
height: 300px;
border:1px solid green;
}
#listContent {
height: 900px;
border: 1px solid red;
}

Not able to click in any content in box coming after using "Show a popup when hovering over a link or button"

i am not able to click in content of popup which comes after using "Show a popup when hovering over a link or button".
i am link to code that i am using: http://jsfiddle.net/8UkHn/
please help me either by suggesting an edit in same code or a new code.
thanks.
$("a").hover(function(e) {
$($(this).data("tooltip")).css({
left: e.pageX + 1,
top: e.pageY + 1
}).stop().show(100);
}, function() {
$($(this).data("tooltip")).hide();
});
div {
position: absolute;
display: none;
background: #ccc;
border: 1px solid;
}
foo
<br><br>
bar
<div id="foo">
foo means foo
<a href="">Anyhing can go here!
</a>
</div>
<div id="bar">bar means bar</div>
When your mouse moves out of the <a> tag, the tooltip associated with it is immediately hidden. Because of this, you won't be able to click on anything inside the tooltip.
The solution is to keep the tooltip open as long as the mouse is inside your <a> or its associated tooltip.
Check demo: http://jsfiddle.net/8UkHn/2108/
Code:
$("a").hover(function(e) {
$($(this).data("tooltip")).css({
left: e.pageX + 1,
top: e.pageY + 1
}).stop().show(100);
// clear any timer started for hiding the tooltip
if($(this).data("hidetimer")) {
clearTimeout($(this).data("hidetimer"));
$(this).data("hidetimer", 0);
}
}, function() {
// start a timer for hiding the tooltip
// after 500ms so as to give the user time to move his
// mouse over to the tooltip
var tooltip = $($(this).data("tooltip"));
$(this).data("hidetimer", setTimeout(function() {
tooltip.hide();
}, 500));
});
$('[data-tooltip]').each(function() {
var self = $(this), tooltip = $(self.data("tooltip"));
// similar show/hide logic for when the mouse enters/leaves the tooltip
tooltip.hover(function() {
if(self.data("hidetimer")) {
clearTimeout(self.data("hidetimer"));
self.data("hidetimer", 0);
}
}, function() {
self.data("hidetimer", setTimeout(function() {
tooltip.hide();
}, 500));
});
});
As your tooltips are outside of your a tag that you hover, when you try to hover the tooltip, it disapear, you should keep your tooltip inside your hover target to avoid this behaviour.
Please,try this:
(Fiddle)
$(".container").hover(function(e) {
$(this).children(".tooltip").css({
left: e.pageX + 1,
top: e.pageY + 1
}).stop().show(100);
}, function() {
$(this).children(".tooltip").hide();
});
.tooltip {
position: absolute;
display: none;
background: #ccc;
border: 1px solid;
}
.container{
overflow:visible;
}
<span class="container" data-tooltip="#foo">
<a href="http://foo.com" >foo</a>
<div id="foo" class="tooltip" >foo means foo</div>
</span>
<span class="container" data-tooltip="#bar">
<a href="http://bar.com" >bar</a>
<div id="bar" class="tooltip" >bar means bar</div>
</span>

jQuery slide from left + dim background

I'm trying to dim the background while slide-opening the left menu to right.
Here is the link and jsfiddle.
At first run, when the dimmer code is commented out, it hides sliding to left and after the 2nd click its working okay. When the dimmer code is included, it doesn't remove the class='dimmer' and I can't click again.
Here is the jQuery:
jQuery(document).ready( function(){
jQuery(".x-btn-navbar").click(function(){
//if (jQuery('#dimmer').hasClass('dimmer')){
//jQuery('#dimmer').removeClass('dimmer');
//} else {
//jQuery('#dimmer').addClass('dimmer');
//}
jQuery('.nav-animate').fadeIn(500);
jQuery('.nav-animate nav').toggle('slide', {direction:'left'}, 500);
});
});
Any help is appreciated, thanks for your time.
Done, I guess...
Changes in HTML
<div class="x-navbar-wrap" style="z-index:999;">
<div class="x-navbar x-navbar-fixed-left">
<div class="x-navbar-inner">
<div class="x-container max width">
<a data-target=".x-nav-wrap.mobile" class="x-btn-navbar" href="#">
<span style="margin:-17px;font-size:20px;">MENU</span>
</a>
<!------- You didn't had these closing tags ---->
</div>
</div>
</div>
CSS changes
#dimmer {
background: none repeat scroll 0 0 rgba(0, 0, 0, 0.5);
display: none;
height: 100%;
left: 0;
position: fixed;
top: 0;
width: 100%;
z-index: 1000;
}
JavaScript
jQuery(document).ready( function(){
jQuery('.nav-animate nav').hide('slide', {direction:'left'}, 500);
jQuery(".x-btn-navbar").click(function(){
jQuery('#dimmer').fadeIn(250, function(){
jQuery('#dimmer').fadeOut(250);
})
jQuery('.nav-animate').fadeIn(500);
jQuery('.nav-animate nav').toggle('slide', {direction:'left'}, 500);
});
});
Working Fiddle
Maybe this will help you:
jQuery('.nav-animate nav').css({
opacity: 0,
left: -$('.nav-animate nav').outerWidth()
});
jQuery(".x-btn-navbar").click(function () {
if (jQuery('#dimmer').hasClass('dimmer')) {
jQuery('#dimmer').removeClass('dimmer');
jQuery('.nav-animate nav').animate({
opacity: 0,
left: -$('.nav-animate nav').outerWidth()
}, 500);
} else {
jQuery('#dimmer').addClass('dimmer');
jQuery('.nav-animate nav').animate({
opacity: 1,
left: $('.x-btn-navbar').outerWidth()
}, 500);
}
});
JSFiddle Demo: http://jsfiddle.net/kq5vo508/2/
i hope i got your question right, but from the link you attached it seems that you have a problem with the first click on the menu button and that later on confuse the dimmer status.
in your HTML you have the nav section
<section class="nav-animate">
<nav style="height:auto;" class="x-nav-wrap mobile cbp-spmenu cbp-spmenu-vertical cbp-spmenu-push">
And your css sets .nav-animate to not be displayed, try removing that setting and instead set the inner nav tag to display:none;

.replaceWith() to replace content in a div for different link elements

I am trying to load a div with different content based on the link I click...
While it seems to work for the first link when I click it, clicking the other links only replaces the content with the same content for 'encodeMe' , yet I have specified different content that I want to replace for 'htmlize-me'
The first run-through of this I did not use jQuery's .bind() function. I simply used .click() , and both had the same result. Looking through the jQuery API I thought using the .bind() function would bind each function within it to that particular page element, but it seems to apply it to all my links.
I've achieved the same effect using .hide and .show to toggle divs but I want to be more elegant about how I do that, and this was my attempted alternative...
here's the relevant html:
<label for="list-root">App Hardening</label>
<input type="checkbox" id="list-root" />
<ol>
<li id="encode-me"><a class="show-popup" href="#">encodeMe()</a></li>
<li id="htmlize-me"><a class="show-popup" href="#">htmlizeMe()</a></li>
</ol>
<div class="overlay-bg">
<div class="overlay-content">
<div class="the-content"></div>
<br><button class="close-button">Close</button>
</div>
</div>
here's the script I made to trigger the content change:
$('#encode-me').bind('click' , function() {
$('div.the-content').replaceWith('<h3 style="color: #008ccc;"> function encodeMe( string ) </h3>' +
'Found in <p>[web root]/redacted/redacted.asp</p>');
});
});
$('#htmlize-me').bind('click' , function() {
$('div.the-content').replaceWith('Hi, Im something different');
});
});
Try something like this:
Use html() instead of replaceWith()
$('#encode-me').bind('click' , function() {
$('div.the-content').html('<h3 style="color: #008ccc;"> function encodeMe( string ) </h3>' +
'Found in <p>[web root]/redacted/redacted.asp</p>');
});
});
$('#htmlize-me').bind('click' , function() {
$('div.the-content').html("Hi, I'm something different");
});
});
replaceWith does exactly what it sounds like, it replaces the div with the h3, so when you click the second link there is no div.
Try setting the innerHTML instead
$('#encode-me').on('click' , function() {
$('div.the-content').html('<h3 style="color: #008ccc;"> function encodeMe( string ) </h3>Found in <p>[web root]/redacted/redacted.asp</p>');
});
$('#htmlize-me').on('click' , function() {
$('div.the-content').html('Hi, I\'m something different');
});
So I figured out a more clever way to do this! Use the DOM to your advantage - set up a nested list structure and change the content using .find() on parent and child elements the list.
Markup
<span style="font-size:1.4em">Type
<ul class="row">
<li>Blah
<div class="overlay-content">
<p></p>
<p class="changeText">Blah</p>
</div>
</li>
<li>Blah2
<div class="overlay-content">
<p></p>
<p class="changeText">Blah2</p>
</div>
</li>
</ul>
</span><br>
<!-- OVERLAYS -->
<div class="overlay"></div>
CSS
.close {
border-radius: 10px;
background-image: url(../img/close-overlay.png);
position: absolute;
right:-10px;
top:-15px;
z-index:1002;
height: 35px;
width: 35px;
}
.overlay {
position:absolute;
top:0;
left:0;
z-index:10;
height:100%;
width:100%;
background:#000;
filter:alpha(opacity=60);
-moz-opacity:.60;
opacity:.60;
display:none;
}
.overlay-content {
position:fixed!important;
width: 60%;
height: 80%;
top: 50%;
left: 50%;
background-color: #f5f5f5;
display:none;
z-index:1002;
padding: 10px;
margin: 0 0 0 -20%;
cursor: default;
border-radius: 4px;
box-shadow: 0 0 5px rgba(0,0,0,0.9);
}
Script
$(document).ready(function(){
$('.show-popup').click(function() {
var ce = this;
$('.overlay').show('slow', function() {
$(ce).parent().find('.overlay-content').fadeIn('slow');
});
});
// show popup when you click on the link
$('.show-popup').click(function(event){
event.preventDefault(); // disable normal link function so that it doesn't refresh the page
var docHeight = $(document).height(); //grab the height of the page
var scrollTop = $(window).scrollTop(); //grab the px value from the top of the page to where you're scrolling
$('.overlay').show().css({'height' : docHeight}); //display your popup and set height to the page height
$('.overlay-content').css({'top': scrollTop+100+'px'}); //set the content 100px from the window top
});
/*
// hides the popup if user clicks anywhere outside the container
$('.overlay').click(function(){
$('.overlay').hide();
})
*/
// prevents the overlay from closing if user clicks inside the popup overlay
$('.overlay-content').click(function(){
return false;
});
$('.close').click(function() {
$('.overlay-content').hide('slow', function() {
$('.overlay').fadeOut();
});
});
});

Appending HTML with click function jQuery not working

http://jsfiddle.net/CCKUz/
So I have a box with a <span class="open"> that will increase the height of a collapsible div to view the content. It's collapsible simply by CSS height and the open click function sets height to auto. Easy and this works.
The problem happens when I go to append the open and close spans. When I include them in the actual html, they work fine. When I append them, they no longer function. I thought maybe this was due to not being available for the js to apply the .click function to them since they were created after the load but even creating them and applying the .click in the same function doesn't help this problem.
Is there anything you see there that might be affecting this? Thanks.
HTML:
<div class="box collapsible">
<h3>Title</h3>
<p>This is a sample paragraph that is here for placer purposes.</p>
</div>
CSS:
.box { height: 20px; border: 1px solid #000000; padding: 10px; margin: 20px; position: relative; overflow: hidden; }
h3 { margin: 0 0 20px 0; line-height: 20px; }
.open, .close { text-indent: -9999px; width: 20px; height: 20px; position: absolute; top: 10px; right: 10px; }
.open { background: #00ff00; }
.close { background: #0000ff; }
JS:
$(function(){
var box = $(".collapsible");
var close = $(".collapsible span.close");
var open = $(".collapsible span.open");
box.each(function(){
box.append('<span class="open">Open</span>');
open.each(function(i){
open.click(function(){
alert("You clicked open");
$(this).parent(box).css("height","auto").append('<span class="close">Close</span>');
$(this).hide();
$(this).parent().find(close).show();
});
});
close.each(function(i){
close.click(function(){
$(this).parent(box).css("height","15px");
$(this).hide();
$(this).parent().find(open).show();
});
});
});
});
No need for loops, jQuery does that internally, and you need delegated event handlers with dynamic elements, like so:
$(function () {
var box = $(".collapsible");
box.append( $('<span />', {'class':'open'}) )
.on('click', '.close', function () {
$(this).hide()
.closest('.collapsible')
.css("height", "auto")
.append( $('<span />', {'class':'close'}).show() );
})
.on('click', '.close', function () {
$(this).hide()
.closest('.collapsible')
.css("height", "15px")
.find('.open').show();
});
});
you select the open-elements before adding them:
var open = $(".collapsible span.open");
Try this:
$(function(){
var box = $(".collapsible");
var close = $(".collapsible span.close");
box.each(function(){
box.append('<span class="open">Open</span>');
var open = $(".collapsible span.open"); //do it here!!
open.each(function(i){
open.click(function(){
alert("You clicked open");
$(this).parent(box).css("height","auto").append('<span class="close">Close</span>');
$(this).hide();
$(this).parent().find(close).show();
});
});
close.each(function(i){
close.click(function(){
$(this).parent(box).css("height","15px");
$(this).hide();
$(this).parent().find(open).show();
});
});
});
});
There is no need for .each delegate the function
$(document).on('click','.collapsible span.open',function(){
demo here http://jsfiddle.net/CCKUz/2/
The problem is that you are adding your .close spans dynamically, so your initial search will not find anything, so it will not add any click handlers to them. You can use event delegation to fix this easily.
.on('click', 'span.close', function(evt){
You can also simplify your code a lot:
$(".collapsible")
.append('<span class="open">Open</span>')
.on('click', 'span.open', function(evt){
// Search within the parent '.collapsible'.
$(evt.delegateTarget)
.css("height", "auto")
.append('<span class="close">Close</span>');
// Hide the '.open' span.
$(this).hide();
})
.on('click', 'span.close', function(evt){
// Search within the parent '.collapsible'.
$(evt.delegateTarget)
.css("height","15px");
.find('.open').show();
// Remove the old '.close' button since the
// open handler will make a new one.
$(this).remove();
})

Categories