Closing Menu on Outside Click on page with iFrames - javascript

I'm trying to use the trick outlined on this answer to close a navigation menu on a page I've designed. However, the majority of the space on the page is taken up by an iframe that loads articles stored on the same server as the page containing the iframe.
If I click on any of the elements on the parent page, the menu closes as it should. However, clicking on any of the space within the iframe does not close the menu.
I'm assuming this is because the parent page does not capture events happening inside of the iframe. Like I've said, both pages are stored on the same server, so how can I capture the click to close my menu when the user clicks within the iframe?
HTML:
<div id="menucontainer">
<nav id="mobilemenu">
<ul>
<li><span class="menutrigger">☰ Menu</span></li>
</ul>
</nav>
<nav id="fullmenu">
<ul>
<li>Menu Item 1</li>
<li>Menu Item 2</li>
<li>Menu Item 3</li>
<li>Menu Item 4</li>
</ul>
</nav>
</div>
<div id="frame">
<iframe name="content" id="content" src="intro.html"></iframe>
</div>
JQuery:
$(document).ready(function() {
$("a[target='content']").click(function() {
if ($("#mobilemenu").css("display") == "block" ){
$('#fullmenu').hide();
}
});
$('html').click(function() {
$('#fullmenu').hide();
});
$('#menucontainer').click(function(event){
event.stopPropagation();
});
$('.menutrigger').click(function() {
$('#fullmenu').toggle();
});
});
CSS: (Added because it occurred to me it might be affecting things)
html, body { height: 100%; width: 100%; }
nav, #frame { position: absolute; right: 0; left: 0; padding: 0; margin: 0; width: 100%; }
#content { height: 100%; width: 100%; }
#frame { top: 38px; bottom: 14px; }
nav { width: 100%; z-index: 100; }
#fullmenu { display: none; position: absolute; top: 38px; width: 100%; }
#mobilemenu { display: block; height: 38px; top: 0; background: #333; }
.menutrigger { font-size: 20px; font-weight: bold; padding: 1px 8px; color: #FFF; cursor: pointer; }
#frame { top: 38px; bottom: 14px; }
nav ul { position: relative; width: 100%; background: #333; list-style: none; display: inline-block; padding: 0; }
nav ul:after { clear: both; }
nav ul li { height: 29px; float: none; min-width: 110px; font-size: 14px; padding: 4px 4px; font-family: 'Roboto Condensed', sans-serif; }
nav ul li a { display: block; padding: 5px; color: #FFF; text-decoration: none; }
nav ul li:hover { background: #666; display: inline-block; height: 29px; }
nav ul li:hover a { color: #FFF; }

The contents().click() does not work when the iframe is on a different domain. You'll get a cross-domain access error attempting to make the contents() call.

Working Demo
Instead of
$('html').click(function() {
$('#fullmenu').hide();
});
use
$('html').click(function() {
$('#fullmenu').hide();
});
//get iframe contents and bind click on them.
$('#content').contents().click(function(){
$('#fullmenu').hide();
});

For iframes with different domains, my solution is to send an event from the iframe with Post Message API and listen to it on the parent. This way the parent can perform any action when the iframe is clicked.
In parent page:
window.addEventListener("message", (event) => {
// DO SOMETHING
}, false);
In iframe:
window.addEventListener("click", (event) => {
parent.postMessage("click", "*");
}, false);

Related

hide sidebar when click anywhere in page

I have an animate sidebar which appears when user clicks on a hamburger button.
Here is the structure :
$('#nav-toggle').click(function() {
if($('#nav-toggle').hasClass('active')){
$('.menu').animate({
right: "0px"
}, 200);
}else{
$('.menu').animate({
right: "-285px"
}, 200);
}
});
.menu{
right:-285px;
height:100%;
position: fixed;
width: 285px;
z-index: 1;
background-color: #111111;
}
.menu ul {
border-top: 1px solid #636366;
list-style: none;
margin: 0;
padding: 0;
}
.menu li {
border-bottom: 1px solid #636366;
font-family: 'Open Sans', sans-serif;
line-height: 45px;
padding-bottom: 3px;
padding-left: 20px;
padding-top: 3px;
}
.menu li a{
color:white;
}
<div class="menu">
<!-- Menu -->
<ul>
<li>About</li>
<li>Blog</li>
<li>Help</li>
<li>Contact</li>
</ul>
</div>
Actually we can open menu by clicking on #nav-toggle element and close it by clicking on this element too. I'd like to allow user to close this menu by clicking anywhere in the page.
How can I do do that? I tried with e.preventDefault(); in my if statement but it doesn't work.
Thanks!
I suggest to use toggleClass method and animate it by adding transition: .2s to your .menu,
working example:
$('#nav-toggle').click(function(e) {
e.stopPropagation();
$(".menu").toggleClass('bar')
});
$('body').click(function(e) {
if ($('.menu').hasClass('bar')) {
$(".menu").toggleClass('bar')
}
})
.menu {
right: -285px;
height: 100%;
position: fixed;
width: 285px;
z-index: 1;
background-color: #111111;
transition: .2s
}
.menu ul {
border-top: 1px solid #636366;
list-style: none;
margin: 0;
padding: 0;
}
.menu li {
border-bottom: 1px solid #636366;
font-family: 'Open Sans', sans-serif;
line-height: 45px;
padding-bottom: 3px;
padding-left: 20px;
padding-top: 3px;
}
.menu li a {
color: white;
}
.bar {
right: 0px;
}
body,
html {
height: 100%;
width: 100%;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<button id="nav-toggle">Click me</button>
<div class="menu">
<!-- Menu -->
<ul>
<li>About</li>
<li>Blog</li>
<li>Help</li>
<li>Contact</li>
</ul>
</div>
Try this, it will always hide of user clicks on body
$(document).on('click',function(){
if($("#nav-toggle").hasClass("active")){
$('.menu').animate({ right: "-100%" }, 200);
}
});
You can add a parent section to your page and attach a click event same as you have done with #nav-toggle, something like this
$('.parent-section').click(function() {
if($('#nav-toggle').hasClass('active')){
$('.menu').animate({
right: "0px"
}, 200);
} else {
$('.menu').animate({
right: "-285px"
}, 200);
}
});
Or you can add this to body tag directly, If you are going to use this i suggest go with section not body, hope this will help you :)
i've slightly edited your code :
here it is :
$('#nav-toggle').click(function(e) {
e.stopPropagation();
$('.menu').animate({right: "0px"}, 200);});
$(document).click(function(e){$('.menu').animate({right: "-285px"}, 200);});
https://jsfiddle.net/ndxqdqwc/
Complementing the Gintoki's answer
$('#nav-toggle').on('click', function(e) {
e.stopPropagation();
$(".menu").toggleClass('bar');
$('body').one('click', function(e) {
if ($('.menu').hasClass('bar')) {
$(".menu").toggleClass('bar')
}
});
});
This will just remove the listener from body, so well, it's not executing every time.
I'm actually not sure what is better for performance, but I don't like the fact that every click on the website is going through that "if(hasClass)"
$('#nav-toggle').click(function(e) {
e.stopPropagation();
$(".menu").toggleClass('bar')
});
$('body').click(function(e) {
if ($('.menu').hasClass('bar')) {
$(".menu").toggleClass('bar')
}
})
.menu {
right: -285px;
height: 100%;
position: fixed;
width: 285px;
z-index: 1;
background-color: #111111;
transition: .2s
}
.menu ul {
border-top: 1px solid #636366;
list-style: none;
margin: 0;
padding: 0;
}
.menu li {
border-bottom: 1px solid #636366;
font-family: 'Open Sans', sans-serif;
line-height: 45px;
padding-bottom: 3px;
padding-left: 20px;
padding-top: 3px;
}
.menu li a {
color: white;
}
.bar {
right: 0px;
}
body,
html {
height: 100%;
width: 100%;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<button id="nav-toggle">Click me</button>
<div class="menu">
<!-- Menu -->
<ul>
<li>About</li>
<li>Blog</li>
<li>Help</li>
<li>Contact</li>
</ul>
</div>

Clickable dropdown Menu in Navigation Bar not working

I'm trying to implement a dropdown menu inside the navigation bar which should show up on user click and disappear on clicking anywhere outside(like Facebook's dropdown menu having logout,etc.). But the dropdown isn't working the way it should. I have searched everywhere on StackOverflow and the internet but unable to find a solution. I want to implement it using CSS and JavaScript only, since I don't understand jQuery and other languages.
Here is my fiddle: https://jsfiddle.net/8ahy32yn/9/
The codes I have implemented are as follows:
HTML
<div id="navbar">
<ul>
<li>
Home
</li>
<li>
FAQs
</li>
<li class="user" style="float:right;">
Dropdown
<ul id="UserContent" class="user-content">
<li>
Profile
</li>
<li>
My Gifts</li>
<li>
Logout
</li>
</ul>
</li>
</ul>
CSS
ul
{
list-style-type: none;
margin: 0;
padding: 0;
overflow: hidden;
background-color: black;
position: fixed;
top: 0;
left: 0;
width: 100%;
height: 55px;
}
li
{
float: left;
}
li a
{
text-decoration: none;
display: block;
padding: 20px 25px;
color: white;
text-align: center;
}
li a:hover
{
background-color: #333333;
}
.user
{
position: relative;
display: inline;
}
.dropbtn
{
cursor: pointer;
}
.user-content
{
display: none;
position: absolute;
background-color: #f9f9f9;
min-width: 100px;
overflow: auto;
box-shadow: 0px 8px 16px 0px rgba(0,0,0,0.2);
}
.user-content a
{
color: black;
padding: 12px 16px;
text-decoration: none;
display: block;
}
.user-content a:hover
{
background-color: #F1F1F1;
}
.show
{
display:block;
}
JavaScript
function UserDropdown() {
document.getElementById("UserContent").classList.toggle("show");
}
window.onclick = function(event)
{
if (!event.target.matches('.dropbtn'))
{
var dropdowns = document.getElementsByClassName("user-content");
var i;
for (i = 0; i < dropdowns.length; i++)
{
var openDropdown = dropdowns[i];
if (openDropdown.classList.contains('show'))
{
openDropdown.classList.remove('show');
}
}
}
}
P.S. The Fiddle doesn't even show the dropdown on clicking whereas it shows up on my localhost like this:
Any help would be much appreciated. Thanks. :)
You want something like this ? The behavior you want is currently working, I just apply some CSS to style it better I think.
.show
{
display:block;
width: 245px;
right: 0;
left: auto;
line-height: 30px;
overflow: hidden
}
With height: auto on the ul and removing overflow: hidden on the ul parent you can do it the way you want : See it here
A closing brace is missing in the javascript section, the reason not working in fiddle
This link might help
http://www.w3schools.com/howto/howto_js_dropdown.asp

CSS horizontal submenu

I'm working on the navigation bar for a website and currently the main menu is complete. However, the "Services" and "Products" buttons need to each have their own sub-menu. The sub-menu should normally be hidden from view and appears when the user mouse-overs on the respective button.
Here is a fiddle with the desired result. Obviously, I'd rather not use any javascript if possible.
The idea I had initially was to have sub-menu have position: absolute with a z-index value lower than that of the main-menu, so that it can slide underneath the main-menu. However, doing so messes up with the width if I give it width: 100% and since my site is responsive, I avoid static widths.
I also tried doing with relative positioning, but that doesn't work either.
Another thing I don't like with that approach is that the markup for the main menu and sub-menu get split. Is it possible to get the above result, but with this markup?
<nav>
<ul class="nav">
<li role="presentation" class="active">Home</li>
<li role="presentation">Services
<ul>
<li role="presentation">Link 1
<li role="presentation">Link 2
</ul>
</li>
<li role="presentation">Products
<ul>
<li role="presentation">Link 3
<li role="presentation">Link 4
</ul>
</li>
<li role="presentation">About</li>
<li role="presentation">Contact</li>
</ul>
</nav>
Here is my code:
CSS
body {
font-size: 0;
}
.bodyframe {
display: inline-block;
box-shadow: 0 6px 15px rgba(0, 0, 0, 0.6);
}
.div_container {
max-width: 1460px;
width: 100%;
display: inline-block;
margin: 0 auto;
}
header {
width: 100%;
height: 49px;
}
.nav {
display: block;
position: relative;
list-style: none;
background: #304770;
z-index: 10;
}
.nav li {
display: inline-block;
background-color: #304770;
margin: 0 5px;
}
.nav li a {
padding: 12px 15px;
font-size: 18px;
color: #EFEFEF;
display: block;
}
.nav li.active a {
color: orange;
}
.nav li.active a:before {
width: 100%;
}
.nav li a:hover {
background-color: #304770;
color: orange;
transition: color 0.25s;
}
.nav li a:before {
content: "";
display: block;
position: absolute;
left: 0;
bottom: 0;
height: 3px;
width: 0;
background-color: orange;
-webkit-transition: width 0.2s;
transition: width 0.2s;
}
.nav li:nth-last-of-type(1) a:after {
display: none;
}
.nav li a:hover:before {
width: 100%;
}
.nav li a:after {
content: "";
display: block;
position: absolute;
right: -8px;
top: 21px;
height: 6px;
width: 6px;
background: #ffffff;
opacity: .5;
}
.subnav {
list-style-type: none;
display: block;
position: relative;
top: -49px;
margin: 0;
z-index: 1;
background-color: #ccc;
-webkit-transition: top 0.2s;
}
.subnav li {
display: inline-block;
background-color: #ccc;
margin: 0 5px;
}
.subnav li a {
padding: 8px 10px;
font-size: 14px;
color: #EFEFEF;
display: block;
}
HTML
<div class="bodyframe div_container">
<header>
<nav>
<ul class="nav">
<li role="presentation" class="active">Home</li>
<li role="presentation">Services</li>
<li role="presentation">Products</li>
<li role="presentation">About</li>
<li role="presentation">Contact</li>
</ul>
</nav>
<ul class="subnav">
<li>Test</li>
<li>1243</li>
</ul>
</header>
</div>
If you only need the submenu to mimic the one in the example, without using jQuery, using the second chunk of HTML with the CSS you supplied you could do:
nav:hover~ul {
top: 0px;
}
This shows the next ul element, in this case the subnav, whenever the nav is hovered over ("~" selector means select the ul element preceded by nav:hover).
However, if you want to do something more dynamic... id suggest just using JS/jQuery as well

Jquery slideUp, slideDown height bug on fixed div

When I slideUp() or slideDown() fixed div, it jumps.
I have read that it is height problem, but could not solve it. Maybe there is something I can do with padding?
Need some help :)
http://jsfiddle.net/sirjay/08ypLtp2/
#tab-menu {
text-align: center;
padding-right: 40px;
position: fixed;
bottom: 0;
width: 100%;
margin-bottom: 0;
}
li {
padding: 15px;
display: inline-block;
margin: 0 10px;
width: 110px;
background-color: lightblue;
}
.t-hidden {
display: none;
padding: 10px;
}
$(function() {
$('#tab-menu li > a').click(function(e) {
e.preventDefault();
var x = $(this).closest('li').find('.t-hidden');
if (x.is(':visible')) {
x.slideUp();
} else {
x.slideDown();
}
});
});
<ul id="tab-menu">
<li>
First
<div class="t-hidden">
Hidden 1
</div>
</li>
<li>
Second
<div class="t-hidden">
Hidden 2
</div>
</li>
<li>
Third
<div class="t-hidden">
Hidden 3
</div>
</li>
</ul>
Just add a height and a width to animate smoothly each element you apply slideUp() or slideDown() to.
li {
padding: 15px;
display: inline-block;
margin: 0 10px;
width: 110px;
height:90px;
background-color: lightblue;
}
DEMO http://jsfiddle.net/a_incarnati/08ypLtp2/3/

jQuery menu with sliding highlighter

I would like to do something like this: http://dreamapp.de/sites/portfolio/
At the moment this is done with an additional list item which has position: absolute. So I simply move the list item to the same place as the active list item. But this solution will only work if the content is not dynamically centered. So beside it's an ugly but working, solution, there must be a better one, right?
I thought that I've seen similar things on other website, but I couldn't find anything like this. So how could I do this better?
HTML:
<nav id="menu2" class="menu">
<ul>
<li class="marker"></li>
<li class="nav1">Home</li>
<li class="nav2">HTML/CSS</li>
<li class="nav3">JavaScript</li>
<li class="nav4">Resources</li>
<li class="nav5">Tutorials</li>
<li class="nav6">About</li>
</ul>
</nav>
jQuery:
$(".nav1 a").click(function() {
$(".marker").stop().animate({left:'8px'},200, function() {
$(".marker").stop().animate({display:'show'}, 200);
});
});
$(".nav2 a").click(function() {
$(".marker").stop().animate({'left':'118px'},200, function() {
$(".marker").stop().animate({display:'show'}, 200);
});
});
.
.
.
CSS:
.menu ul li.marker {
width: 110px;
height: 45px;
background-color: #42ff2e;
display:none;
position: absolute;
}
.menu {
width: 660px;
height: 45px;
display: block;
}
.menu ul {
list-style: none;
padding: 0;
margin: 0;
}
.menu ul li {
float: left;
overflow: hidden;
position: relative;
text-align: center;
line-height: 45px;
}
.menu ul li a {
position: relative;
display: block;
width: 110px;
height: 45px;
font-family: Arial;
font-size: 11px;
font-weight: bold;
letter-spacing: 1px;
text-transform: uppercase;
text-decoration: none;
cursor: pointer;
}
Think you could use this for fixed navigation item width http://jsfiddle.net/UqUBr/
(for variable navigation item width - http://jsfiddle.net/bdmjC/)
JS:
var navigation = $('nav'),
items = navigation.find('.item'),
itemWidth = 110
$(".item a").click(function() {
var item = $(this).parent()
$(".marker").stop().animate({left:items.index(item)*itemWidth},200, function() {
$(".marker").stop().animate({display:'show'}, 200);
});
});
HTML:
<nav id="menu2" class="menu">
<ul>
<li class="marker"></li>
<li class="item">Home</li>
<li class="item">HTML/CSS</li>
<li class="item">JavaScript</li>
<li class="item">Resources</li>
<li class="item">Tutorials</li>
<li class="item">About</li>
</ul>
</nav>
CSS:
nav#menu2 {
display: block;
margin: auto;
width: 660px;
position: relative;
}

Categories

Resources