Closing a div moves the page up - javascript

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')
})

Related

How to create hover effects for all links EXCEPT the one you hover on using javascript/jquery/css?

I recently saw a very interesting effect I would like to create in a navbar for a website. The effect was a hover effect, used for links in a menu list. Instead of the typical "change the link when you hover over it" , it changes every OTHER link BESIDES the one you are hovering. In the example I saw when you hover over one link in the list, it applied an opacity fade to all the other links, leaving the link you are hovering over at full opacity.
now i've tried some css things that ive looked up, something like this:
.menu-link:a + .menu-link {opacity: 0.7;}
...but that only achieved the effect for the link next to it , not all links with the same class. I'm assuming this can be achieved with javascript but im such a noob I cannot figure it out.
So could anyone help me figure out how to code up a quick function like this in either jquery or javascript? something that looks for a hover on an object with a specific class and then having an effect (such as lowering opacity) performed on all other objects with that class? Thanks for any help!
EDIT: okay i was asked to provide some code. this is the "menu of links" i have been working on, the are just a series of unordered lists that show up in a header div at the top of the page:
<div class="col-lg-2 col-md-2 menu-border">
<div class="menu-list">
<h4 class="list-title">Blog</h4>
<ul>
<li><a class="menu-link" href="#">Archive</a></li>
<li><a class="menu-link" href="#">Search</a></li>
<li><a class="menu-link" href="#">Tag Cloud</a></li>
</ul>
</div>
</div>
<div class="col-lg-2 col-md-2 menu-border">
<div class="menu-list">
<h4 class="list-title">Profile</h4>
<ul>
<li><a class="menu-link" href="#">Artist Profiles</a></li>
<li><a class="menu-link" href="#">Submit A Profile</a></li>
</ul>
</div>
</div>
<div class="col-lg-2 col-md-2 menu-border">
<div class="menu-list">
<h4 class="list-title">Connect</h4>
<ul>
<li><a class="menu-link" href="#">SoundCloud</a></li>
<li><a class="menu-link" href="#">linkedIN</a></li>
</ul>
</div>
</div>
they are just a few sub menus; however i have given all the links in all the sub menus a class ("menu-link") and I'm trying to figure out how to make a function that when hovering over one link with the "menu-link" class, all other links with that class do something (in my particular case i want them to fade to a > 1 opacity )
Using jQuery, you could do something like this:
jQuery
$('a.menu-link').hover(function(){
$('a.menu-link').not(this).toggleClass('toggle');
})
CSS
.toggle {
opacity: 0.7;
}
Here is a fiddle of it in action: http://jsfiddle.net/HMq67/
Using toggleClass() and not() you can change the style of every element that is not the one you are hovering over.
Give this jsFiddle a try. If nothing else, it should get you going.
In essence, you will need javascript to listen for the mousover and mouseout events. Then select all elements except the one you are currently hovering over.
$('nav li a').mouseover(function () {
$('nav li a').not($(this)).addClass('hover');
});
$('nav li a').mouseout(function () {
$('nav li a').not($(this)).removeClass('hover');
});
4 years later...lol.
You can achieve this with simple CSS!
For the code you provided above it would look like this:
.menu-list ul:hover .menu-link {
opacity: 0.7;
}
.menu-list ul:hover .menu-link:hover {
opacity: 1;
}
.menu-list ul li a {
display: block;
}
Fiddle: https://jsfiddle.net/fz6bumxx/6/
Note - I'm setting the a tags within each list items to block so that you can't trigger the link fades without hovering over one of the links.
Hope this helps!

JS Toggle hides ALL toggled divs -- makes page non-functioning

Sorry if this is a silly question, I'm very new to JS/JQuery and don't know if there's a simple answer to my problem.
I have two toggling divs set up more or less like the following (this is the stripped-down version):
<div id="top-story-panel">
<div id="story-toggle">
<ul>
<li id="top-stories">
Top Stories
</li>
<li id="toc">
All Stories
</li>
</ul>
</div>
</div>
<div id="toc-panel">
<div id="story-toggle">
<ul>
<li id="top-stories">
Top Stories
</li>
<li id="toc">
All Stories
</li>
</ul>
</div>
</div>
With this function, the two divs toggle back and forth without a hitch, but if you click on one of the toggles ("top stories"/"all stories", respectively) and then click it AGAIN it hides the div it just showed and... can't find anything else to replace it with. Both divs are hidden now and there's no way for the user to interact with either div.
jQuery(function($) {
var $contentPanel= $('#top-stories-panel, #toc-panel')
$toggle= $("#top-stories, #toc");
$toggle.on('click', function(e) {
var $id;
e.preventDefault();
$icons.removeClass('hidden');
$id=$('#'+this.id+'-panel'); //get menu id
$contentPanel.fadeOut(10);
if(! $id.is(':visible')) {
$id.fadeIn(450)
preloadImages: 'all';
$(this).addClass('hidden');
}
});
});
I'm assuming that if I place the toggles outside of their respective divs, I won't have this problem -- but is there a code workaround for the toggle to stay within the div?
Thanks so much for all of your help ;_;

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.

How to implement a "pop down" like in gmail

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>

Categories

Resources