How to implement a "pop down" like in gmail - javascript

I'm trying to implement a pop down panel like on the top bar of Gmail. If you click on the Setting icon, your name, or the Share link, a panel drops down...is there a jquery plugin or something that will allow me to quickly implement something to give a similar effect?

If you want a non jQuery cross browser solution I made this for someone on here yesterday:
http://jsfiddle.net/Paulpro/H4CLU/
It drops down when you click button and hides when you click it again, or anywhere in the document that isn't part of the drop down.
Only thing you'd need to change is probably some CSS stuff to style it nicely.

Here's a jsFiddle that show how you can implement something like this.
Basically, you're capturing clicks on the body element, if they clicked on settings, you show the "panel" div. If they clicked something else, you hide it.
JS:
$(function() {
$('body').click(function(e) {
if ($(e.target).attr('id') == 'settings') {
$('#panel').show();
} else {
$('#panel').hide();
}
});
});
HTML:
<span id="settings">Settings</span>
<div id="panel">
<ul>
<li>Option 1</li>
<li>Option 2</li>
<li>Option 3</li>
</ul>
</div>
CSS:
#panel { display: none; border: 1px solid #000;}

Yes, I suggest to use jQuery (everytime you use JS). It is really easy to create a layer like this:
<div id="layer">content</div>
<a id="button" href="#">show</a>
<script type="text/javascript">
$(document)ready(function(){
$('#layer').hide();
$('#button').click(function(e){
e.preventDefault();
$('#layer').show();
});
});
</script>

Related

Closing a div moves the page up

I'm making a page where you can open and close descriptions.
The page works perfectly on firefox, but on other browser like Chrome, the page seems to go up as you open and close the other divs.
EDIT : the page goes up when I close a menu under another one. But not the other way.
here is a link so you can see what is happening with chrome :
https://imgur.com/a/4zgrzc0
I suppose the problem is $(this).parent('.sub-menu').siblings().find('ul').slideUp('fast');
How can I avoid that?
Thanks a lot.
$(document).ready(function(){
$(".exposition").on('click',function(){
var hello = $(this).attr('data-id');
$('.photos-evenements').hide();
$('[id='+ hello + ']').show();
});
});
$( document ).ready(function(open) {
$('.sub-menu ul').hide();
$('.sub-menu a').click(function () {
$(this).parent('.sub-menu').siblings().find('ul').slideUp('fast'); // to hide all ul expect this one
$(this).parent('.sub-menu').children('ul').slideToggle(200);
});
$('.sub-menu a').click(function(open) {
open.preventDefault();
});
});
.photos-evenements{
display:none;
max-width: 100%;
max-height: 90vh;
}
.exemple {
height:100vh;
background-color:lavender;
}
<div class="exemple">hi</div>
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<ul class="menu">
<li class='sub-menu'> 1
<ul>
<li> When opened, i'm a description, I'm not supposed to move the page when opened or closed.
</li>
</ul>
</li>
<li class='sub-menu'> 2
<ul>
<li> I'm supposed to close 1 and don't move the page up
</li>
</ul>
</li>
</ul>
<div class="exposition">
<div class="photos-ind"><img id="divId1" class="photos-evenements" src="http://follebeton.com/img/Performances%20OK.jpg" data-id="divId1"/></div>
<div class="photos-ind"><img id="divId1" class="photos-evenements" src="http://follebeton.com/img/333_3.png" data-id="divId1"/></div>
<div class="photos-ind"><img id="divId1" class="photos-evenements" src="http://follebeton.com/img/333_1.png" data-id="divId1"/></div>
</div>
<div class="exposition">
<div class="photos-ind"><img id="divId2" class="photos-evenements" src="http://follebeton.com/img/Performances%20OK.jpg" data-id="divId2"/></div>
<div class="photos-ind"><img id="divId2" class="photos-evenements" src="http://follebeton.com/img/333_3.png" data-id="divId1"/></div>
<div class="photos-ind"><img id="divId2" class="photos-evenements" src="http://follebeton.com/img/333_1.png" data-id="divId1"/></div>
</div>
</div>
I believe that what you are witnessing is aggressive scroll anchoring from Chrome. For some reason Chrome is anchoring the scroll on the link you clicked, while Firefox is anchoring it on some other element, possibly the container or preceding div.
It's not clear, to me at least, why there's a difference in behaviour or which is 'correct'. In any case you should be able to resolve your issue by simply disabling scroll anchoring within the menu container. To do this we can use the overflow-anchor property on the element where we want to disable scroll anchoring.
In the example you have given we would simply add the following code to the CSS
.sub-menu{
overflow-anchor:none
}
This should fix the issue.
I have edited your example in the snippet below to include this (I also tidied the code up slightly to make it clearer). I have tested this in both Firefox and Chrome and the jumping of the page seems to be gone.
Obviously you will have to change what you set the overflow-anchor:none property on for different scripts with different class names. One approach would be to just disable scroll anchoring for the entire document by setting it on the body.
body{
overflow-anchor:none
}
Be warned however, that scroll anchoring was introduced to counteract the very disruptive experience of what the user is currently looking at being moved unexpectedly by changes elsewhere on the document. It would be best to only disable it in select areas if possible.
$(document).ready(function(){
$(".exposition").on('click',function(){
var hello = $(this).attr('data-id');
$('.photos-evenements').hide();
$('[id='+ hello + ']').show();
});
});
$( document ).ready(function(open) {
$('.sub-menu ul').hide();
$('.sub-menu a').click(function () {
$(this).parent('.sub-menu').siblings().find('ul').slideUp('fast'); // to hide all ul expect this one
$(this).parent('.sub-menu').children('ul').slideToggle(200);
});
$('.sub-menu a').click(function(open) {
open.preventDefault();
});
});
.example {
height:100vh;
background-color:lavender;
}
.sub-menu {
overflow-anchor:none;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div class="example">Space above</div>
<ul class="menu">
<li class='sub-menu'> 1
<ul>
<li> When opened, i'm a description, I'm not supposed to move the page when opened or closed.
</li>
</ul>
</li>
<li class='sub-menu'> 2
<ul>
<li> I'm supposed to close 1 and don't move the page up
</li>
</ul>
</li>
</ul>
<div class="example">Space below</div>
Revised answer
I think this might be a simple minimum height issue for that page. By reserving the space for the hidden content, you can avoid the jump
I made a codesandbox to demonstrate the issue and the height on the list can be tweaked - remove the border when you are happy.
https://codesandbox.io/s/sleepy-currying-6vtsy?file=/index.html:467-489
Not exactly sure what you're trying to do, but you might try the following:
$(document).on('click', '.sub-menu a', function (e) {
e.preventDefault()
e.stopPropagation()
$(this).parents('.sub-menu').siblings().find('ul').slideUp('fast');
$(this).parents('.sub-menu').children('ul').slideToggle(200);
});
It's good practice to bind events to the document instead of a specific element in case you might end up loading data through AJAX in the future.
Anyhow, I usually achieve the thing you're looking for by defining the CSS for the element, in your case .sub-menu ul, to:
.sub-menu ul{
max-height:0vh; // To hide sub-menu <ul> contents
overflow:hidden;
transition:500ms ease; // For fancy smooth opening and closing [1/2]
transition:max-height 500ms ease; // Alternative, more specific [2/2]
}
.sub-menu.active ul{
max-height:100vh; // or any height you expect it to never exceed.
}
Then - with jQuery - you can do the following:
$(document).on('click', '.sub-menu a', function(e){
e.preventDefault();
$(this).parents('.sub-menu').addClass('active')
$(this).parents('.sub-menu').siblings().removeClass('active')
})

JS hide div if it has a class added via JS

I am working on a code where an active class is added to a div via JS.
What I would like to do is, when that div has active class, hide another div. But, due to the active class was added via JS, this code doesn't work:
if($("#section3").hasClass("active")) {
$(".menu").fadeOut("fast");
}
I think I would need to use the on function: .on()
Something like this, but it's not working... Any ideas?
$("#section3").on( function() {
$(this).hasClass('active') {
$(".menu").fadeOut("fast");
}
});
EDITED:
I'm afraid I cannot paste the code because I am using a plugin. This is the one that I am using, so you can see the functionality there.
I've added this bullet menu to it:
<ul id="menu">
<li data-menuanchor="slide1"><span></span></li>
<li data-menuanchor="slide2"><span></span></li>
<li data-menuanchor="slide3"><span></span></li>
<li data-menuanchor="slide4"><span></span></li>
</ul>
Each slide has a active class when it's on viewport, so what I would like to achieve is when the last slider is active, hide the menu
$(document).ready(function(){
$('section').click(function(){
$(this).addClass('active');
if($('section').hasClass('active')){
$('ul#menu').hide();
}
});
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<section>check</section>
<ul id="menu">
<li data-menuanchor="slide1"><span></span></li>
<li data-menuanchor="slide2"><span></span></li>
<li data-menuanchor="slide3"><span></span></li>
<li data-menuanchor="slide4"><span></span></li>
</ul>
oth the section and the li have active classes so you could use something like this or use the afterSlideLoad event if it is depeding of the slideshow
$(window).on("scroll",function() {
if ($('#menu li:last-child').hasClass("active")) {
("#menu").fadeOut("fast")
}
})
or you can use slideIndex to check if you are on the last slide. see here > afterSlideLoad

show() function doesn't seem to work as expected

I am trying to create a webpage with a menu on the left side and a content area on the right side. Mockup image below to give you an idea:
I am using jQuery UI to try to accomplish this. The goal is to have the content area on the right side to be set based on the menu item selected on the left. The area will always be a tabbed layout, but the content and amount of tabs will be different for each of the item selected from the left menu. Eventually, I want to integrate this into an ASP.NET MVC 5 app to include user authorization and roles affecting what menu items and tabs will be visible based on the logged in user. But for now, I am simply trying to get the tab menu to show up based on what I click on the left menu, and to show it specifically upon clicking one specific item. For the others, it will hide it again (I have not tried to implement the re-hiding yet, and that is not part of this question; I just want to get the initial show() to work).
So right now my approach is to hide the tabs on page ready, then use a function to display it when clicked, using the jQuery show() function. However, this doesn't work (tried in firefox and IE).
My attempt is at: https://jsfiddle.net/3mo28z1t/5/
In the fiddle, in the javascript section, if you change the "hide" to "show"
$("#tabsuseradmin").hide();
you will see the tabs menu, in case you want to get an idea of the layout before trying to fix the issue.
Specifically, I want the action of clicking on "Left menu item 3" to show the tabs.
Thank you.
I cleaned your fiddle up so that your scripts/css were in external resources. You must first define the target and then call the function with the target - you haven't targeted the individual tabs(i haven't done this for you either, i'm just pointing it out) Also you can't use show as a function name, as its reserved.
What i did do is create a toggle on the #leftmenu>li - see fiddle
$(function() {
$("#tabsuseradmin").tabs();
$("#leftmenu").menu();
});
$('#leftmenu>li').on('click', function(){
$("#tabsuseradmin").toggle();
});
$(function showTab(target) {
document.getElementById(target).show();
});
$(function hideTab(target) {
document.getElementById(target).hide();
});
#leftmenu {
display: inline-block;
}
#tabsuseradmin {
display: inline-block;
margin-right: 10px;
}
<link href="https://code.jquery.com/ui/1.11.4/themes/smoothness/jquery-ui.css" rel="stylesheet"/>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>
<script src="https://code.jquery.com/ui/1.11.4/jquery-ui.js"></script>
<body>
<ul id="leftmenu">
<li>Left menu item 1</li>
<li>Left menu item 2</li>
<li>Left menu item 3</li>
<li>Left menu item 4</li>
</ul>
<div id="tabsuseradmin">
<ul>
<li>Tab first</li>
<li>Tab second</li>
<li>Tab third</li>
</ul>
<div id="tabs-1">
<p>Tab 1</p>
</div>
<div id="tabs-2">
<p>Tab 2</p>
</div>
<div id="tabs-3">
<p>Tab 3</p>
</div>
</div>
</body>
<li id="clicker" onclick="show('tabsuseradmin')">Left menu item 3</li>
$(document).ready(
function(){
$("#clicker").click(function () {
$("#tabsuseradmin").show();
});
});
Updated Fiddle
There is an error in your code. If you check console, it specifically says - show is not defined. Show & hide are methods provided by jQuery. They are not the same in javascript.
In your example you are using document.getElementById(target).show();, but .show is a jQuery method
you should use something like :
$(document.getElementById(target)).show();
$('#'+target).show();
You can also declare your event handler differently to avoid the problem seen in jsfiddle (that show is not defined), see my updated jsfiddle for that

Creating navigational pages with jquery

I actually didn't really know how to phrase the question title, but here is the description. Suppose I'm using jQuery to show/hide uls that are stacked on top of each other (absolutely positioned). For example:
<ul id="one">
<li>blah</li>
<li>blah2</li>
</ul>
<ul id="two">
<li>blah</li>
<li>blah2</li>
</ul>
I have a controller button, that when pressed, simply changes the z-index of these uls. The controller button is literally just:
My button
With jQuery code that does: (I'm using the jQuery cycle plugin)
$('#mybutton').click(function() {
// check which ul is currently shown
// change z-index, so that the next ul is to be shown
});
THE QUESTION:
In my site, I have several pages that I would like to point to the second ul, so that when clicked, it'll bring them to the page with all of the uls, but only the second one will be shown. It would be the same if the person went to the page, had the default first ul shown, and then clicked "next" to proceed to the next ul. I am simply wondering if it's possible to avoid pressing "next", and just bring the user directly to the page and have the second ul shown.
I think you can use the hash-tag from the URL. You can then write an if statement like this:
if(location.hash === "#2"){
$("#one").hide();
}else{
$("#two").hide();
}
Or directly as a copy and paste example:
<html>
<script src="http:////ajax.googleapis.com/ajax/libs/jquery/1.8.1/jquery.min.js"></script>
<script>
$(function(){
if(location.hash === "#2"){
$("#one").hide();
}else{
$("#two").hide();
}
$('#mybutton').click(function(e) {
$("ul").toggle(); //quick n dirty! only works with 2 lists :)
e.preventDefault();
});
});
</script>
<body>
My button
<ul id="one">
<li>First Item!</li>
<li>blah</li>
<li>blah2</li>
</ul>
<ul id="two">
<li>Second Item!</li>
<li>blah</li>
<li>blah2</li>
</ul>
To second page (you might have to refresh, notice the #2 at the end of the url!)
​</body>
</html>
Also notice I've inserted a e.preventDefault(); at #mybutton's click listener to prevent the URL changing back on clicking.
If I am understanding you correctly, perhaps you can accomplish this via a page wrap with a unique id per page? You can swap the id out with JS or server side logic, depending on what you're trying to do.
<div id="page-one">
<ul id="one">
<li>blah</li>
<li>blah2</li>
</ul>
<ul id="two">
<li>blah</li>
<li>blah2</li>
</ul>
</div>
then your css will be #page-one #one { display:block }; #page-two #one { display : none }; etc.

if mouse on hover of div then display menu

I have the following menu which cascades on hover but i need to add some conditional checks like if the mouse is on hover on the div then keep the menu sliding down.
Also if the mouse is hovered on the LI then check them menu down.
As you can see it just slides down and back up once you leave the "div".
Im stuck... and have tried for hours searching for if statements etc, i just cant get the syntax correct.
my example
Here is a working example
HTML
<div id="leftWrap">
<div id='accordion'>
<ul>
<li><div>Absorption</div>
<ul style="display: none;">
<li>Accessories</a>
<ul style="display: none;">
<li>AA500AFG</li>
<li>AA500F</li>
<li>AA500G</li>
<li>AA990F</li>
</ul>
</li>
<li>Consumables</li>
<li>Products</li>
</ul>
</li>
<li><div>Fluorescence</div>
<ul style="display: none;">
<li>Accessories</li>
<li>Consumables</li>
<li>Products</li>
</ul>
</li>
</ul>
</div>
</div>
Javascript/JQuery
jQuery(document).ready(function() {
$('#accordion ul > li').hover(function() {
$(this).children("ul").slideToggle('slow');
});
});
If you ask me, it gets really messy when you use mousehover/mouseenter for such things. I'd prefer using a click event after the first hover or something, this way the user won't get annoyed by all that movement.
jQuery(document).ready(function() {
$('#accordion ul:first-child > li').hover(function() {
$(this).children("ul").slideToggle('slow');
});
$('#accordion ul:not(:first-child) > li').click(function(){
$(this).children("ul").slideToggle('slow');
});
});
Make it a child of the <div>, then it won't cancel the event when you leave it.
Also I should note that it's more semantic to make a navigation out of nested lists (such as
Category ItemItem
<ul>
<li>Category
<ul>
<li>Item</li>
<li>Item</li>
</ul>
</li>
</ul>
I tried to fiddle in your fiddle, but the markup and css are a lot confusing.
As Rikudo said, you should make the div, its child its much easier to do it that way. I have created a simplest accordion skeleton. You can see it here.
It does everything you want. However for the customizations and others things, I will leave it up to you.
http://jsfiddle.net/dttdB/13/
You had attached hover to the heading div when the mouse leaves that, the hover effect is lost.

Categories

Resources