Slidetoggle with multiple divs - javascript

I'm struggling to make a replica of the effect seen here: https://tu-dresden.de/if you click on Language, Search, Internal and the navigation in the blue header.
I have managed to create this: https://jsfiddle.net/06tfufo6/2/
I would like to keep the slideToggle effect upon clicking and somehow slideToggle each element inside.
Upon clicking the same/active button it should all close. I can't seem to wrap my head around how this can be done.
Thank you
jQuery('.container-box, .slideout-container').hide();
jQuery('.btn-group a').on('click', function() {
var target = "#" + jQuery(this).data("target");
jQuery('.slideout-container').slideToggle();
jQuery('.container-box').not(target).hide().attr('aria-expanded', 'false');
jQuery(target).show().attr('aria-expanded', 'true');
});
.btn-group {
background-color: #002557;
}
a {
color: #fff;
padding: 10px 20px;
}
.slideout-container {
padding: 25px 0;
background: #ccc;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="btn-group">
Show language
Show search
Search navigation
</div>
<div class="slideout-container">
<section id="top_search" class="container-box" aria-expanded="false">
Section search
</section>
<section id="language" class="container-box" aria-expanded="false">
Section language
</section>
<section id="navigation" class="main-navigation container-box" role="navigation" aria-expanded="false">
Navigation
</section>
</div>

Store the current content in a variable and compare each time is clicked to slide down and up the content, would be something like this:
jQuery('.container-box, .slideout-container').hide();
var current_page,
target = '';
jQuery('.btn-group a').on('click', function () {
var target = "#" + jQuery(this).data("target");
if(current_page === target){
jQuery('.slideout-container').slideUp();
current_page = '';
}else{
jQuery('.slideout-container').slideDown();
current_page = target;
}
jQuery('.container-box').not(target).hide().attr('aria-expanded', 'false');
jQuery(target).show().attr('aria-expanded', 'true');
});
here is working: https://jsfiddle.net/06tfufo6/8/

For the functionality you described, you need to be able to keep track of the initiating element, and then only call your toggle code when the instigating element is clicked (assuming I understood what you were going for). The code below does just that.
You're going to need to tweak the aria-expanded true/false portion of your code, but this should get you going.
jQuery('.container-box, .slideout-container').hide();
jQuery('.btn-group a').on('click', function() {
var target = "#" + jQuery(this).data("target");
let $target = jQuery(this);
// If no other elements have instigator class, add to target
if (!jQuery(".btn-group a.instigator").length) {
$target.addClass("instigator");
}
if ($target.hasClass("instigator")) {
jQuery('.slideout-container').slideToggle();
jQuery(target).show().attr('aria-expanded', 'true');
} else {
jQuery('.container-box').not(target).hide().attr('aria-expanded', 'false');
jQuery(target).show().attr('aria-expanded', 'true');
}
});
Here's a working fiddle.

Related

Hide and show an item based on a toggled is-active class

I used the following code to toggle a button class in order to make a full-screen mobile menu.
HTML
button class="hamburger hamburger--slider" type="button">
<a href='#'><div class="hamburger-box">
<div class="hamburger-inner"></div>
</div>
</a>
document.addEventListener('DOMContentLoaded', function() {
jQuery(function($){
$('.hamburger').click(function(){
$('.hamburger--slider').toggleClass('is-active');
});
});
});
Now I would like to hide another item in my header when the toggled class .is-active is present.
The following code works to hide the item, but once the toggled class is gone, the item does not reappear but stays hidden until the page is reloaded.
jQuery(function($) {
if ($('.hamburger--slider.is-active').length) {
$('.rey-headerCart-wrapper').hide();
}
});
Appreciate any help :) !
you have to show the element again after the burger menu closes:
document.addEventListener('DOMContentLoaded', function() {
jQuery(function($){
$('.hamburger').click(function(){
$('.hamburger--slider').toggleClass('is-active');
// hide / show other element
if ($('.hamburger--slider.is-active').length) {
$('.rey-headerCart-wrapper').hide();
} else {
$('.rey-headerCart-wrapper').show();
}
});
});
});
Or in vanilla javascript:
window.addEventListener("load", () => {
document.querySelector(".hamburger").addEventListener("click", () => {
document.querySelector(".hamburger--slider").classList.toggle("is-active");
// hide / show other element
const cart = document.querySelector(".rey-headerCart-wrapper");
if (document.querySelector(".hamburger--slider.is-active")) {
cart.style.display = "none";
} else {
cart.style.display = "block";
// apply original display style
// cart.style.display = "inline-block";
// cart.style.display = "flex";
};
});
})
In order to make toggle functions like this more understandable, maintainable and extendable you need to think about your HTML structure.
In your current structure, you have a button that toggles a class on itself. Therefore any element beyond that button that has to change appearance or beaviour has to check which class that button has, or you have to extend the click-event handler in order to add these elements (that's what you did here).
This can get quite messy really fast.
A better approach could be to not toggle a class on the button but on an element that is a common parent to all elements that you want to change the behavior of.
That way anything you ever add to that wrapper already can be manipulated via CSS, without the need of changing your JS.
$('.nav-toggler').on('click', function() {
$('#nav-wrapper').toggleClass('active');
});
.menu, .cart {
padding: 1em;
margin: 2px;
}
.cart {
background: #FFF000;
}
.menu{
background: #F1F1F1;
display: none;
}
#nav-wrapper.active > .menu {
display: block;
}
#nav-wrapper.active > .cart {
display: none;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div id="nav-wrapper">
<button class="nav-toggler">Toggle</button>
<div class="menu">My Menu</div>
<div class="cart">My Cart</div>
</div>

Change url doesn't change tab selected

I was implementing that if i refresh the page, it should make active to previously selected tab(preserve selected tab) . So I Create a simple html page and add some jQuery.
But if i change URL manually like file:///home/2.html#news to file:///home/2.html#home
it changes only content of page but doesn't change tab ,that was selected. .
Here is my code.
<body>
<ul>
<li id="first">Home</li>
<li id="second">News</li>
<li id="third">Contact</li>
<li id="forth">About</li>
</ul>
<p id="home">
home section
</p>
<p id="news">
news section
</p>
<p id="contact">
contact section
</p>
<p id="about">
about section
</p>
</body>
<style>
p{
display: none;
}
:target {
display:block;
border: 2px solid #D4D4D4;
background-color: #e5eecc;
}
</style>
<script type="text/javascript">
$(document).ready(function(){
if(localStorage.getItem("active_state") == null ){
activeStateId = "first";
}
else{
activeStateId = localStorage.getItem("active_state")
}
$('#'+activeStateId).addClass('active');
$('li').click(function(){
$('.active').removeClass('active');
$(this).addClass('active');
localStorage.setItem("active_state", $(this).attr('id'));
});
});
</script>
When you got link hashes, you dont actually reload the page, but the browser just triggers those links. You rely on CSS :target change rule which evaluates every time the #hash changes on the url.
p {
display: none;
}
:target {
display:block;
border: 2px solid #D4D4D4;
background-color: #e5eecc;
}
Thus, you have all the sections updated properly even without refreshing the page. In order to have such functionality, you don't need to store any data to the local or remote machine since you are using hashes on the url. Just use the hashes and handle the hashchange event to add the .activate class to the links like this:
$(document).ready(function() {
var hash = window.location.hash;
if(hash.length > 0) {
hash = hash.substring(1);
$('li a[href$='+hash+']').parent().addClass('active');
}
$(window).on('hashchange', function() {
$('.active').removeClass('active');
var hash = window.location.hash
if(hash.length > 0) {
hash = hash.substring(1);
$('li a[href$='+hash+']').parent().addClass('active');
}
});
});
Check my working example here: http://zikro.gr/dbg/html/urlhash.html#about

Making a div to display as none

I have this code which makes a div to display as none when anywhere outside the div is clicked. But my problem is I also want the link which makes the div to display block to also close the div if the div is displayed as block so I ran this code:
function show_div(x){
var box = document.getElementById(x);
if(box.style.display=='block'){
box.style.display='none';
} else {
box.style.display='block';
window.addEventListener('mouseup', function(event){
if(event.target != box && event.target.parentNode != box){
box.style.display='none';
}
});
}
}
But the link does not close the div. if I run it like this:
function show_div(x){
var box = document.getElementById(x);
if(box.style.display=='block'){
box.style.display='none';
} else {
box.style.display='block';
}
}
The link opens and closes the div, But I also want a click anywhere outside the div to close the div also. Please do anyone have a better Idea on how I can achieve this? Here is my HTML:
<a onclick="show_div('divd')" href="javascript:;">click</a>
<div id="divd">this is the div</div>
As Portal_Zii said, you'll probably need a wrapper/container for your div to hide it, but this example should give you a basic idea.
$(document).ready(function() {
var $div = $("#divd");
$("a").on("click", function() {
$div.toggle(); // this is to toggle div visibilty
});
$div.on("click", function(e) {
// prevent div from closing when clicking inside
e.preventDefault();
return false;
});
$div.parent().on("click", function() {
// hide div when user clicks inside div's parent element
$div.hide();
});
});
.container {
background: red;
height: 100px;
padding: 20px;
}
#divd {
background: blue;
width: 50%;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.0/jquery.min.js"></script>
click
<div class="container">
<div id="divd">this is the div</div>
</div>

Adding a class to a link inside a <li> element on scrolling

Is it possible to add a class to a link inside a li element when a certain part of the page is active?
I have a one page website and would like to change the color of the link when that specific part of the page is reached via scroll.
Here's my HTML:
<header id="header">
<section class="container">
<nav>
<a class="logo" href="index.html">Logo</a>
<div id="menu">
<ul id="links">
<li>Services</li>
<li>About</li>
<li>Clients</li>
<li class="last">Contact</li>
</ul>
</div>
</nav>
</section>
</header>
And here's the CSS:
#menu li a {
color:#7a7a7a;
text-decoration: none;
font-size: 12px;
margin-right:20px;
}
#menu li.last a {
color:#7a7a7a;
text-decoration: none;
font-size: 12px;
margin-right:0px;
}
#menu li.current a {
color: #0086be;
}
What I would like to do is to add the class .current to the link inside the li element whenever that specific part of the page is reached.
I believe this is only possible with Javascript, can anyone point me the right path to achieve this?
Thanks in advance
I think you want something like scrollspy in bootstrap,
you can use it or you can find https://gist.github.com/pascaldevink/2380129 bypascaldevink
or here is the fiddle http://jsfiddle.net/ia_archiver/Kb7xq/
You will require jquery for this,
$.fn.scrollspy = function ( option ) {
return this.each(function () {
var $this = $(this)
, data = $this.data('scrollspy')
, options = typeof option == 'object' && option
if (!data) $this.data('scrollspy', (data = new ScrollSpy(this, options)))
if (typeof option == 'string') data[option]()
})
}
$.fn.scrollspy.Constructor = ScrollSpy
$.fn.scrollspy.defaults = {
offset: 10
}
$(function () {
$('[data-spy="scroll"]').each(function () {
var $spy = $(this)
$spy.scrollspy($spy.data())
})
})
}(window.jQuery);
Using hover function you can achieve this.i.e. on hover of specific part of the page you add the class to the link present inside the li. e.g.
$('#specificPartOfPageId').hover(function(){
$('#links').children().children('a').addClass('current');
});
This would add .current class to every link present inside that UL element.
Hope this helps.
If I have understood correctly, I guess this is what you require: jsFiddle. The CSS and the HTML code remains the same and this is the jQuery code which I've used:
$(window).scroll(function() {
var scroll = $(window).scrollTop();
if (scroll > 500) {
$("#links li:first-child").addClass("current");
}
if (scroll > 750) {
$("#links li:first-child").removeClass("current");
$("#links li:nth-child(2)").addClass("current");
}
var scrollBottom = $(window).scrollTop() + $(window).height();
if (scroll < 500) {
$("#links li:first-child").removeClass("current");
}
if (scroll < 750) {
$("#links li:nth-child(2)").removeClass("current");
}
});
Basically what happens is that when you scroll down to 500px, the li:first-child is automatically assigned the current class. You can modify the jQuery to suit your needs by adding more if queries as per your needs. You can target different <li>'s in your list using different child-selectors like li:first-child, li:nth-child(2) etc.

Issue Unhiding div Using Javascript

Have successfully setup a menu which cycles between multiple tabs using Javascript. The issue is I'm using SiteLevel as a search for this site. I want the search box to be a part of the hide/unhide menu but the script (I've also tried the html code for the search box, but still no fix)
I've paired it down to the simplest form of this concept to ensure that it's not some other css or script that's conflicting, but it still opens to a blank box here's the code.
I've pumped it into http://jsfiddle.net/Split98/A3DVa/
Software
Hardware
Supplies
Contact
Search
<div id="nav">
<div id="software">Hello!</div>
<div id="hardware">Yes!</div>
<div id="supplies">Yeee Haw!</div>
<div id="contact">Bingo!</div>
<div id="search"><script type="text/javascript" src="http://www.sitelevel.com/javabox?crid=ze32uipb"></script></div>
</div>
CSS:
#nav div {
display: none;
background-color: red;
height: 200px;
}
jQuery:
$(function(){
var divs = $('#nav div'),
links = $('a');
links.click(function () {
$(this.hash).toggle().siblings().hide();
return false;
});
})
Thanks in advance guys!
LIVE DEMO
Simply use #nav > div in your CSS
Will target only the immediate childrens.Otherwise all DIV elements will be hidden (your search tool)
#nav > div {
display: none;
background-color: red;
height: 200px;
}
edited jQuery
$(function () {
var divs = $('#nav div'),
links = $('a');
divs.eq(0).show(); // if you need it.....
links.click(function ( e ) { // e = event
e.preventDefault(); // instead of return false;
$(this.hash).toggle().siblings().hide();
});
});

Categories

Resources