I'm a beginner in javascript. I want to add hide and show button using toggle methods. Here is my html.
<body>
<header>
<li>Mécanique
<ul class="sub-menu">
<li>Mécanique du point</li>
<li>Mécanique du solide</li>
</ul>
</li>
</header>
</body>
Learn how things work before you ask a question here at StackOverflow. We all still learning, but, we have to try things ourselves.
Besides that, here's how to use jQuery to hide/show .sub-menu by clicking the a tag that contains 'Mécanique' word, and I'll give it an ID so we can reference it later by JavaScript.
// we put everything in the document.ready handler to ensure that the document has finished loading.
$(document).ready(function() {
// reference the 'a' tag that I gave it an id of 'trigger', and also referencing the .sub-menu ul.
var trigger = $('#trigger'),
menu = $('.sub-menu');
// adding the event listener to the #trigger to hide/show the .sub-menu ul.
trigger.on('click', function(e) {
// cancel the default behaviour when clicking a link.
e.preventDefault();
// hide/show the menu.
menu.toggle();
});
});
ul.sub-menu {
// by default, let's make the .sub-menu ul hidden.
display: none;
}
<body>
<header>
<li>Mécanique
<ul class="sub-menu">
<li>Mécanique du point</li>
<li>Mécanique du solide</li>
</ul>
</li>
</header>
<script
src="https://code.jquery.com/jquery-3.3.1.min.js"
integrity="sha256-FgpCb/KJQlLNfOu91ta32o/NMZxltwRo8QtmkMRdAu8="
crossorigin="anonymous"></script>
</body>
Hope I pushed you further.
Related
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')
})
I'm really new at trying to use jQuery, so please forgive me for asking what is likely a simple question. Perhaps it isn't even related to jQuery, but anyway, here's the scenario. I'm trying to put in a hidden div which I only want to show up when the user hovers their mouse over the Learner's anchor tag on the page. I've started with only one anchor tag, to get it working first before implementing the rest of them. I've downloaded a jQuery library and included a reference to it, so here's some of what I've got in my page's head section:
<script src="js/jquery-1.11.1.js" type="text/javascript" ></script>
<style type="text/css">
#navcontainer ul { list-style-type: none; }
#navcontainer ul li { display: inline; }
#navcontainer ul li a
{
text-decoration:none;
padding: .2em 1em;
}
</style>
Next I've defined an unordered list, using the styling above to make it horizontal, and I've got a hidden div after it, which I want to show when the user moves their mouse over the first anchor in the unordered list. Here's the relevant HTML from within the body tag:
<body>
<div id="navcontainer">
<ul>
<li>Home</li>
<li>Learners</li>
<li>Teachers</li>
<li>Businesses</li>
<li>Contact Us</li>
</ul>
<div id="dropdown1" style="visibility:hidden;">
<ul>
<li>Description A</li>
<li>Description B</li>
<li>Description C</li>
</ul>
</div>
<!-- other HTML code -->
</body>
However, when I run this from within the browser (IE11) nothing happens. Using the F12 web developers tools built into IE11 I learn that it giving an error of "showHide is undefined". Why is it doing that? The showHide() function is most certainly in the jquery-1-11.1.js file, which most certainly is in my js folder. What have I done wrong, or failed to take into account?
jQuery works kinda different than that. You have to make it look like this:
$("#dropdown1").toggle()
You better make a javascript file and separate the JS from the HTML:
HTML:
<body>
<div id="navcontainer">
<ul>
<li>Home</li>
<li>Learners</li>
<li>Teachers</li>
<li>Businesses</li>
<li>Contact Us</li>
</ul>
<div id="dropdown1" style="visibility:hidden;">
<ul>
<li>Description A</li>
<li>Description B</li>
<li>Description C</li>
</ul>
</div>
<!-- other HTML code -->
</body>
The JS
$(function(){
$("#navcontainer li a").click(function(){
if( this.href.indexOf("#") != -1 ) {
$( $(this).attr("href") ).toggle(); // $( "#container1" )
}
});
});
What this does is on the navcontainer li click, we make a handler, which does something if it contains a #. Then we select that element #container1 which is in the href, also is the selector for the element which we want to show. And we toggle that element.
There is no such function as showHide you could use toggle() or show() or hide()
in you current scenario uou would couple them with $(this). or your chosen selector.
As an example of targetting a particular element with jQuery we have added the class hover-learners and target it with the selector below.
HTML:
<div id="navcontainer">
<ul>
<li>Home
</li>
<li>Learners
</li>
<li>Teachers
</li>
<li>Businesses
</li>
<li>Contact Us
</li>
</ul>
<div id="dropdown1">
<ul>
<li>Description A
</li>
<li>Description B
</li>
<li>Description C
</li>
</ul>
</div>
Add the below javascript as a file or within <script type="text/javascript"> code here</script> after including your jQuery library file.
Javascript:
// wrap everything in jQuery's ready function to make sure the page has fully loaded before executing the javascript
$(document).ready(function () {
//select learners and apply mouseover event
$('.hover-learners').on('mouseover', function () {
$('#dropdown1').show();
});
//select learners and apply mouseout event
$('.hover-learners').on('mouseout', function () {
$('#dropdown1').hide();
});
});
Also since the show and hide methods manipulate the display CSS property I have added
CSS:
#dropdown1 {
display:none;
}
and remove the inline style="visibility:hidden" from the #dropdown1
Working demo here: http://jsfiddle.net/robschmuecker/J6U7d/
I experience an issue where .slideToggle() or .slideUp()/.slideDown() stop functioning when the container div data get updated by Ajax. Consider this initial structure:
<ul class="main-container">
<li>
<div class="data-container"><!--display:none; through CSS-->
<p>empty</p>
</div>
</li>
</ul>
And the slideToggle script:
$('.main-container li').click(function(){
$(this).find('div.data-container').slideToggle();
});
Then there is an Ajax update like this:
$('.main-container').replaceWith(data)
The updated structure becomes:
<ul class="main-container">
<li>
<div class="data-container"><!--display:none; through CSS-->
<ol>
<li>data1</li>
<li>data2</li>
</ol>
</div>
</li>
</ul>
Then the slideToggle stops functioning until I reload the page. Is there any work around rather than using .slideToggle() or .slideUp()/.slideDown() ?
Simply use:
$(document).on('click', '.main-container li', function(){
$(this).find('div.data-container').slideToggle();
});
The issue is that when you replace .main-container the original event handler is no longer in effect. To get around this you set the event listener on document and ask it to run the function when a click event is triggered on an li inside the .main-container div.
Here it is working: http://jsfiddle.net/wXdbL/3/
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.
I have the following jquery code for my drop down menu:
var active = 0;
$(document).ready(function(){
jQuery("#dropmenu ul").css({display:"none"});
// For 1 Level
jQuery("#dropmenu li:has(ul) a").append('');
jQuery("#dropmenu li ul a span").text('');
// For 2 Level
jQuery("#dropmenu li ul li:has(ul) a").append('');
jQuery("#dropmenu li ul li ul a span").text('');
jQuery("#dropmenu li").hover(function(){
if(active != 1){
jQuery($('.active').parent()).find("ul:first").css('display', 'none');
jQuery(this).find("ul:first").fadeIn('fast');
active = 1;
}
},
function(){
jQuery(this).find("ul:first").fadeOut('fast');
jQuery($('.active').parent()).find("ul:first").fadeIn('fast');
active = 0;
}); });
//ACTIVATE
$(document).ready(function(){
jQuery($('.active').parent()).find("ul:first").css('display', 'block');
});
What the code is suppose to do is check and see which element has an active class and show it when the page loads.
The HTML looks something like this:
<ul id="dropmenu">
<li><a class="active" href="index.php">home</a>
<ul>
<li>Euro 2012</li>
<li>FIA Cup</li>
<li>Previous Events</li>
<li>Event 2012-2013</li>
<li class="last">Pre Season</li>
</ul>
</li>
<li><a href="#" >home</a></li>
<li>blabl</li>
<li>dropdown
<ul>
<li>Euro 2012</li>
<li>FIA Cup</li>
<li>Previous Events</li>
<li>Event 2012-2013</li>
<li class="last">Pre Season</li>
</ul>
</li>
<!-- ... -->
</ul>
right now when the page loads the default drop down is shown however once you hover over other menu items if they dont have a drop down menu it shows the default one and hides, and if you quickly go over the the menu item it will keep repeating the animation. How can I avoid the repetition of the animation and how can I avoid showing the default menu when the menu is empty?
I say scrap this and look for scripts that do that, there are plenty if you just take the time to google, here is a useful link :
http://vandelaydesign.com/blog/web-development/jquery-drop-down-menus
I personally use this plugin to make dropdown menus:
http://filamentgroup.com/lab/jquery_ipod_style_and_flyout_menus/
You can do a lot with this plugin with a little help of html and css to make a row of dropdown menus... The plugin uses jQuery and jQuery UI for the design, you can custom it however you want, here is the link to the jQueryUI website if you haven't been there: http://www.jqueryui.com/themeroller