How can I fix this expanding issue? - javascript

So I'm trying to create an accordion style menu where if you click a panel it opens the section. If you click it again, it closes. On top of that, it should also close any other panel that was previously opened.
I've almost got that functionality but the problem is that I have to click it twice.
To see what I mean, check out this Fiddle
You'll notice that if you open link one then try to open link 2, you'll have to press link 2 twice.
How can I make it so that you only have to press it once to close link 1 but also open link 2 ?
let dropdown = document.querySelectorAll('.dropdown-toggle');
const handleClick = (e) => {
const active = document.querySelector('.open');
if(active){
active.classList.remove('open');
} else {
e.currentTarget.nextElementSibling.classList.add('open')
}
}
dropdown.forEach(element => {
element.addEventListener('click', handleClick);
});
body {
background: #ccc;
}
.menu {
background: #fff;
margin: 0 auto;
max-width: 400px;
}
.menu ul {
padding: 0;
text-align: center;
width: 100%;
}
.menu ul li {
list-style: none;
padding: 20px 0;
border-bottom: 1px solid #ccc;
}
.menu ul li a {
text-decoration: none;
}
.menu ul li .dropdown {
display: none;
padding: 20px;
background: grey;
}
.menu ul li .dropdown.open {
display: block;
}
<div class="menu">
<ul>
<li>
link 1
<div class="dropdown">Some text</div>
</li>
<li>
link 2
<div class="dropdown">Some text</div>
</li>
<li>
link 3
<div class="dropdown">Some text</div>
</li>
<li>
link 4
<div class="dropdown">Some text</div>
</li>
<li>
link 5
<div class="dropdown">Some text</div>
</li>
</ul>
</div>

Can use js like the following.
let dropdown = document.querySelectorAll('.dropdown-toggle');
const handleClick = (e) => {
const isLastOpenTargetClicked = e.currentTarget.nextElementSibling.classList.contains('open');
if(isLastOpenTargetClicked) {
e.currentTarget.nextElementSibling.classList.remove('open');
return;
}
const active = document.querySelector('.open');
if(active){
active.classList.remove('open');
}
e.currentTarget.nextElementSibling.classList.add('open')
}
dropdown.forEach(element => {
element.addEventListener('click', handleClick);
});
body {
background: #ccc;
}
.menu {
background: #fff;
margin: 0 auto;
max-width: 400px;
}
.menu ul {
padding: 0;
text-align: center;
width: 100%;
}
.menu ul li {
list-style: none;
padding: 20px 0;
border-bottom: 1px solid #ccc;
}
.menu ul li a {
text-decoration: none;
}
.menu ul li .dropdown {
display: none;
padding: 20px;
background: grey;
}
.menu ul li .dropdown.open {
display: block;
}
<div class="menu">
<ul>
<li>
link 1
<div class="dropdown">Some text</div>
</li>
<li>
link 2
<div class="dropdown">Some text</div>
</li>
<li>
link 3
<div class="dropdown">Some text</div>
</li>
<li>
link 4
<div class="dropdown">Some text</div>
</li>
<li>
link 5
<div class="dropdown">Some text</div>
</li>
</ul>
</div>

There's no need to check whether the current element is active; On the click handler you simply want to check whether the .nextElementSibling's .classList contains the class open. If it does, remove it. If it doesn't, apply it.
This can be seen in the following:
let dropdown = document.querySelectorAll('.dropdown-toggle');
const handleClick = (e) => {
if (e.currentTarget.nextElementSibling.classList.contains('open')) {
e.currentTarget.nextElementSibling.classList.remove('open');
} else {
e.currentTarget.nextElementSibling.classList.add('open')
}
}
dropdown.forEach(element => {
element.addEventListener('click', handleClick);
});
body {
background: #ccc;
}
.menu {
background: #fff;
margin: 0 auto;
max-width: 400px;
}
.menu ul {
padding: 0;
text-align: center;
width: 100%;
}
.menu ul li {
list-style: none;
padding: 20px 0;
border-bottom: 1px solid #ccc;
}
.menu ul li a {
text-decoration: none;
}
.menu ul li .dropdown {
display: none;
padding: 20px;
background: grey;
}
.menu ul li .dropdown.open {
display: block;
}
<div class="menu">
<ul>
<li>
link 1
<div class="dropdown">Some text</div>
</li>
<li>
link 2
<div class="dropdown">Some text</div>
</li>
<li>
link 3
<div class="dropdown">Some text</div>
</li>
<li>
link 4
<div class="dropdown">Some text</div>
</li>
<li>
link 5
<div class="dropdown">Some text</div>
</li>
</ul>
</div>

Inside your click handler, loop the document.querySelectorAll('.dropdown-toggle'), remove all the open from classlist, then add open to the current target

Related

Mobile navigation issues with jQuery

I created a simple navigation, but it doesn't work on mobile. When you click on the plus symbol or "Book 1 name" the list of links are suppose to appear, but for some reason it doesn't work, and when you click the plus symbol the ex symbol is suppose to appear. The book title should link should work on desktop, but not on mobile. Thanks!
$(document).ready(function () {
$(window).resize(function() {
if($(window).width() <= 550) {
$('.bookName').click(function(e){
e.preventDefault();
$('.bookNavigation ul li ul').toggleClass('toggleNav')
$(this).toggleClass('changeIcon');
});
} else {
$('.bookName').click(function(e){
return true;
});
}
});
});
.bookNavigation ul li ul{
display: flex;
}
.toggleNav{
display: block;
}
#media only screen and (max-width: 550px) {
.bookNavigation ul li ul{
display: none;
}
.bookName::before{
content: '+';
padding-right: 10px;
}
.bookName .changeIcon::before{
content: '-';
padding-right: 10px;
}
}
a{
text-decoration: none;
}
li{
list-style: none;
}
.bookNavigation{
margin-bottom: 100px;
}
.bookName{
text-transform: uppercase;
font-size: 30px;
}
li{
margin-right: 30px;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<nav class="bookNavigation">
<ul>
<li>
Book 1 Name
<ul>
<li>Book 1 Chapter 1</li>
<li>Book 1 Chapter 2</li>
<li>Book 1 Chapter 3</li>
</ul>
</li>
</ul>
</nav>
<p>you are in Book 1 Name cover page</p>
You can do this check $(window).width() <= 550 inside the click event rather than attaching the event based on screen-size. Please find the corrected code.
$('.bookName').click(function(e) {
if ($(window).width() <= 550) {
e.preventDefault();
$('.bookNavigation ul li ul').toggleClass('toggleNav')
$(this).toggleClass('changeIcon');
}
});
.bookNavigation ul li ul {
display: flex;
}
.bookNavigation ul li ul.toggleNav {
display: block;
}
#media only screen and (max-width: 550px) {
.bookNavigation ul li ul {
display: none;
}
.bookName::before {
content: '+';
padding-right: 10px;
}
.bookName .changeIcon::before {
content: '-';
padding-right: 10px;
}
}
a {
text-decoration: none;
}
li {
list-style: none;
}
.bookNavigation {
margin-bottom: 100px;
}
.bookName {
text-transform: uppercase;
font-size: 30px;
}
li {
margin-right: 30px;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<nav class="bookNavigation">
<ul>
<li>
Book 1 Name
<ul>
<li>Book 1 Chapter 1</li>
<li>Book 1 Chapter 2</li>
<li>Book 1 Chapter 3</li>
</ul>
</li>
</ul>
</nav>
<p>you are in Book 1 Name cover page</p>
Instead of checking on resize, check the window with inside buttonClickHandler like below
$(button).on('click', function(){
if($(window).width() <= 550){
// Code to toggle list
}
});
Another problem was the specificity of toggleNav css class.
.bookNavigation ul li ul {
display: none;
}
Above code is more specific than
.toggleNav {
display: block;
}
So the toggling toggleNav won't work because the 1st one will override this one. For fixing it create a class like the one below and toggle it on click. So that it will be hidden initially and will be removed on click.
.navHidden {
display: none
}
Check this pin for working example: https://codesandbox.io/s/bold-currying-39w11

When click on second dropdown black box should remain visible

In this dropdown nav I'm building if a dropdown is opened and you click to open a second one, the black box should remain visible. At the moment the black box disappears when you click on a second dropdown and reappears after the dropdown is completely opened.
Update
I also noticed the black box shows after a dropdown is open and it should open at the same time.
I hope this makes sense and thank you for your help!
$(document).ready(function() {
$(".click").on("click", function(e) {
var menu = $(this);
toggleDropDown(menu);
});
$(document).on('mouseup',function(e) {
var container = $("nav .top-bar-section ul");
// if the target of the click isn't the container nor a descendant of the container
if (!container.is(e.target) && container.has(e.target).length === 0) {
$('a.active').parent().find('.showup').stop(true, true).slideUp(500, function() {
$(".main-container").removeClass("black-bg");
if ($('a.active').hasClass('active')) {
$('a.active').removeClass('active');
}
});
}
});
});
function toggleDropDown(menu) {
var isActive = $('a.active').length;
$('a.active').parent().find('.showup').stop(true, true).slideUp(500, function() {
$(".main-container").removeClass("black-bg");
if (menu.hasClass('active')) {
menu.removeClass('active');
} else {
$('a.active').removeClass('active');
menu.addClass('active');
menu.parent().find('.showup').stop(true, true).slideDown(500, function() {
$(".main-container").addClass("black-bg");
});
}
});
if (!isActive) {
menu.addClass('active');
menu.parent().find('.showup').stop(true, true).slideDown(500, function() {
$(".main-container").addClass("black-bg");
});
}
}
* {
box-sizing: border-box;
}
body {
margin: 0;
}
.nav-wrapper {
width: 100%;
overflow: hidden;
background: #424242;
}
nav {
width: 1024px;
margin: auto;
overflow: hidden;
background: #424242;
}
.nav-content {
width: 100%;
z-index: 999;
background: #ccc;
}
.top-bar-section {
float: left;
}
.top-bar-section a.active {
background: #f00;
}
.showup {
display: none;
background: #ccc;
position: absolute;
width: 100%;
top: 70px;
left: 0;
z-index: 99;
padding: 30px 15px 30px 20px;
}
p {
font-size: 14px;
line-height: 1.4;
}
li.nav-item {
display: inline-block;
background: #f5f5f5;
}
li.nav-item a {
display: block;
text-decoration: none;
padding: 10px;
}
.main-container {
width: 80%;
height: 400px;
margin: auto;
}
.black-bg {
background: #000;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="nav-wrapper">
<nav>
<div class="top-bar-section">
<ul>
<li class="nav-item">
Nav item 1
<div class="showup">
<div class="nav-content">
<p>
Dropdown for Nav Item 1.
</p>
</div>
</div>
</li>
<li class="nav-item">
Nav item 2
<div class="showup">
<div class="nav-content">
<p>
Dropdown for Nav Item 2.
</p>
</div>
</div>
</li>
<li class="nav-item">
Nav item 3
<div class="showup">
<div class="nav-content">
<p>
Dropdown for Nav Item 3.
</p>
</div>
</div>
</li>
<li class="nav-item">
Nav item 4
<div class="showup">
<div class="nav-content">
<p>
Dropdown for Nav Item 4.
</p>
</div>
</div>
</li>
</ul>
</div>
</nav>
</div>
<div class="main-container">
</div>
If you want black-bg being added once the menu is clicked, then do not remove and add black-bg class on every click event. Simply add it once if the menu have active class and remove it when menu do not active class. If you remove and add class on every click event then black-bg will first disappear and again it will appear. To black-bg at the time drop-down is open then remove $(".main-container").addClass("black-bg"); from callback function of slideDown() because a callback function is executed after the current effect is finished.
$(document).ready(function() {
$(".click").on("click", function(e) {
var menu = $(this);
toggleDropDown(menu);
});
$(document).on('mouseup',function(e) {
var container = $("nav .top-bar-section ul");
// if the target of the click isn't the container nor a descendant of the container
if (!container.is(e.target) && container.has(e.target).length === 0) {
$('a.active').parent().find('.showup').stop(true, true).slideUp(500, function() {
$(".main-container").removeClass("black-bg");
if ($('a.active').hasClass('active')) {
$('a.active').removeClass('active');
}
});
}
});
});
function toggleDropDown(menu) {
var isActive = $('a.active').length;
$('a.active').parent().find('.showup').stop(true, true).slideUp(500, function() {
if (menu.hasClass('active')) {
menu.removeClass('active');
$(".main-container").removeClass("black-bg");
} else {
$('a.active').removeClass('active');
menu.addClass('active');
menu.parent().find('.showup').stop(true, true).slideDown(500, function() {
});
}
});
if (!isActive) {
menu.addClass('active');
menu.parent().find('.showup').stop(true, true).slideDown(500);
$(".main-container").addClass("black-bg");
}
}
* {
box-sizing: border-box;
}
body {
margin: 0;
}
.nav-wrapper {
width: 100%;
overflow: hidden;
background: #424242;
}
nav {
width: 1024px;
margin: auto;
overflow: hidden;
background: #424242;
}
.nav-content {
width: 100%;
z-index: 999;
background: #ccc;
}
.top-bar-section {
float: left;
}
.top-bar-section a.active {
background: #f00;
}
.showup {
display: none;
background: #ccc;
position: absolute;
width: 100%;
top: 70px;
left: 0;
z-index: 99;
padding: 30px 15px 30px 20px;
}
p {
font-size: 14px;
line-height: 1.4;
}
li.nav-item {
display: inline-block;
background: #f5f5f5;
}
li.nav-item a {
display: block;
text-decoration: none;
padding: 10px;
}
.main-container {
width: 80%;
height: 400px;
margin: auto;
}
.black-bg {
background: #000;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="nav-wrapper">
<nav>
<div class="top-bar-section">
<ul>
<li class="nav-item">
Nav item 1
<div class="showup">
<div class="nav-content">
<p>
Dropdown for Nav Item 1.
</p>
</div>
</div>
</li>
<li class="nav-item">
Nav item 2
<div class="showup">
<div class="nav-content">
<p>
Dropdown for Nav Item 2.
</p>
</div>
</div>
</li>
<li class="nav-item">
Nav item 3
<div class="showup">
<div class="nav-content">
<p>
Dropdown for Nav Item 3.
</p>
</div>
</div>
</li>
<li class="nav-item">
Nav item 4
<div class="showup">
<div class="nav-content">
<p>
Dropdown for Nav Item 4.
</p>
</div>
</div>
</li>
</ul>
</div>
</nav>
</div>
<div class="main-container">
</div>
Just move $(".main-container").removeClass("black-bg"); into if (menu.hasClass('active')) {
$(document).ready(function() {
$(".click").on("click", function(e) {
var menu = $(this);
toggleDropDown(menu);
});
$(document).on('mouseup',function(e) {
var container = $("nav .top-bar-section ul");
// if the target of the click isn't the container nor a descendant of the container
if (!container.is(e.target) && container.has(e.target).length === 0) {
$('a.active').parent().find('.showup').stop(true, true).slideUp(500, function() {
$(".main-container").removeClass("black-bg");
if ($('a.active').hasClass('active')) {
$('a.active').removeClass('active');
}
});
}
});
});
function toggleDropDown(menu) {
var isActive = $('a.active').length;
$('a.active').parent().find('.showup').stop(true, true).slideUp(500, function() {
//$(".main-container").removeClass("black-bg"); FROM HERE
if (menu.hasClass('active')) {
menu.removeClass('active');
$(".main-container").removeClass("black-bg"); // TO HERE
} else {
$('a.active').removeClass('active');
menu.addClass('active');
menu.parent().find('.showup').stop(true, true).slideDown(500, function() {
$(".main-container").addClass("black-bg");
});
}
});
if (!isActive) {
menu.addClass('active');
menu.parent().find('.showup').stop(true, true).slideDown(500, function() {
$(".main-container").addClass("black-bg");
});
}
}
* {
box-sizing: border-box;
}
body {
margin: 0;
}
.nav-wrapper {
width: 100%;
overflow: hidden;
background: #424242;
}
nav {
width: 1024px;
margin: auto;
overflow: hidden;
background: #424242;
}
.nav-content {
width: 100%;
z-index: 999;
background: #ccc;
}
.top-bar-section {
float: left;
}
.top-bar-section a.active {
background: #f00;
}
.showup {
display: none;
background: #ccc;
position: absolute;
width: 100%;
top: 70px;
left: 0;
z-index: 99;
padding: 30px 15px 30px 20px;
}
p {
font-size: 14px;
line-height: 1.4;
}
li.nav-item {
display: inline-block;
background: #f5f5f5;
}
li.nav-item a {
display: block;
text-decoration: none;
padding: 10px;
}
.main-container {
width: 80%;
height: 400px;
margin: auto;
}
.black-bg {
background: #000;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="nav-wrapper">
<nav>
<div class="top-bar-section">
<ul>
<li class="nav-item">
Nav item 1
<div class="showup">
<div class="nav-content">
<p>
Dropdown for Nav Item 1.
</p>
</div>
</div>
</li>
<li class="nav-item">
Nav item 2
<div class="showup">
<div class="nav-content">
<p>
Dropdown for Nav Item 2.
</p>
</div>
</div>
</li>
<li class="nav-item">
Nav item 3
<div class="showup">
<div class="nav-content">
<p>
Dropdown for Nav Item 3.
</p>
</div>
</div>
</li>
<li class="nav-item">
Nav item 4
<div class="showup">
<div class="nav-content">
<p>
Dropdown for Nav Item 4.
</p>
</div>
</div>
</li>
</ul>
</div>
</nav>
</div>
<div class="main-container">
</div>
Is this what you are looking for?
$(document).ready(function() {
$(".click").on("click", function(e) {
var menu = $(this);
toggleDropDown(menu);
});
$(document).on('mouseup',function(e) {
var container = $("nav .top-bar-section ul");
// if the target of the click isn't the container nor a descendant of the container
if (!container.is(e.target) && container.has(e.target).length === 0) {
$('a.active').parent().find('.showup').stop(true, true).slideUp(500, function() {
$(".main-container").removeClass("black-bg");
if ($('a.active').hasClass('active')) {
$('a.active').removeClass('active');
}
});
}
});
});
function toggleDropDown(menu) {
var isActive = $('a.active').length;
$('a.active').parent().find('.showup').stop(true, true).slideUp(500, function() {
if (menu.hasClass('active')) {
menu.removeClass('active');
} else {
$('a.active').removeClass('active');
menu.addClass('active');
menu.parent().find('.showup').stop(true, true).slideDown(500, function() {
$(".main-container").addClass("black-bg");
});
}
});
if (!isActive) {
menu.addClass('active');
menu.parent().find('.showup').stop(true, true).slideDown(500, function() {
$(".main-container").addClass("black-bg");
});
}
The black box will remain there in this case. What you were previously doing was that you were removing black-box explicitly.

jQuery .hover() or .mouseleave() not working on chrome

Problem description:
In my menu when .mouseenter() the menu opens and when .mouseleave() it closes, but if i click a lot , the .mouseleave() event is executed.
This only happened on chrome browser.
I have other .click() events inside my menu, but every click I made, the .mouseleave() event is execute.
$(document).ready(function() {
$("#nav1 li").hover(
function() {
$(this).find('ul').slideDown();
},
function() {
$(this).find('ul').slideUp();
});
});
#nav1 a {
color: #FFFFFF;
}
#nav1 li ul li a:hover {
background-color: #394963;
}
div ul li ul {
background-color: #4a5b78;
list-style: none
}
#nav1 > li > a {
padding: 16px 18px;
display: block;
border-bottom: 2px solid #212121;
}
#nav1 li ul li a {
padding: 10px 0;
}
div {
background-color: #000000;
background-color: #343434;
width: 280px;
}
/* Hide Dropdowns by Default */
#nav1 li ul {
display: none;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div id="container">
<ul id="nav1">
<li>Hover here and infinite click
<ul>
<li>Stage1</li>
<li>Stage2</li>
<li>Stage3</li>
<li>Stage4</li>
</ul>
</li>
<li>Menu Heading 2
<ul>
<li>Stage1</li>
<li>Stage2</li>
<li>Stage3</li>
<li>Stage4</li>
</ul>
</li>
</ul>
<div>
Try click "Hover here and infinite click" to see this problem.
EDIT:
As you guys said, the problem occurs in this example.
Here is a video: Video link
When you click many times the browser has lost the element reference, try this example:
<div id="container">
<ul id="nav1">
<li>Menu Heading 1
<ul>
<li>Stage1</li>
<li>Stage2</li>
<li>Stage3</li>
<li>Stage4</li>
</ul>
</li>
<li>Menu Heading 2
<ul>
<li>Stage1</li>
<li>Stage2</li>
<li>Stage3</li>
<li>Stage4</li>
</ul>
</li>
<li>Menu Heading 3
<ul>
<li>Stage1</li>
<li>Stage2</li>
<li>Stage3</li>
<li>Stage4</li>
</ul>
</li>
</ul>
<div>
Css
ul,
li,
a {
padding: 0px;
margin: 0px;
}
.show {
display: block !important;
}
#nav1 a {
color: #FFFFFF;
}
#nav1 li ul li a:hover {
background-color: #394963;
}
div ul li ul {
background-color: #4a5b78;
list-style: none
}
#nav1 > li > a {
background-color: #343434;
padding: 16px 18px;
text-decoration: none;
display: block;
border-bottom: 2px solid #212121;
background: linear-gradient(top, #343434, #111111);
}
#nav1 li ul li a {
padding: 10px 0;
padding-left: 30px;
text-decoration: none;
display: block;
}
div {
background-color: #000000;
background-color: #343434;
width: 280px;
}
/* Hide Dropdowns by Default */
#nav1 li ul {
display: none;
}
JS
$(document).ready(function() {
$("#nav1 li").hover(
function(e) {
let ulMenu = $(this).find('ul');
ulMenu.addClass('show');
//$(this).find('ul').slideDown();
},
function(e) {
if(e.relatedTarget){
let ulMenu = $(this).find('ul');
ulMenu.removeClass('show');
} else {
console.log('fail ');
}
//$(this).find('ul').slideUp();
});
});
Codepen Example Works
You can add a stropPropagation in your click event.
$("#nav1 li").click(
function(e){
e.stopPropagation();
});
maybe the event is getting lost in the process, try to verify it, and if so set the actual element.
see this: https://api.jquery.com/event.relatedTarget/

jQuery slide toggle corresponding service item

Working on a jQuery slide toggle where upon click of an item in a ul toggle down the corresponding item in another ul. I'm having trouble getting the click to be linked to the id and toggling the correct ul item.
jQuery is:
$(document).ready(function() {
//on click of subservices list item toggle down the corresponding subservices item
$(".subServices").find("li").hide().end() // Hide all other ULs
.click(function(e) {
if (this == e.target) { // if the handler element is where the event originated
$(this).children('ul.subServicesList.subServiceItem').slideToggle('fast');
}
});
});
Can anyone help :)
Fiddle here
First, ID of an element must be unique so you can't use same ID for subServices and SubServicesList. In the below solution we uses a data-target attribute for subServices.
Also you need to register the handler to .SubServicesList a element, not the SubServicesList
$(document).ready(function() {
//on click of subservices list item toggle down the corresponding subservices item
$(".subServices > li").hide().end() // Hide all other ULs
$('.SubServicesList a').click(function(e) {
$('#' + $(this).data('target')).slideToggle()
});
});
.SubServicesList {
display: block;
width: 55%;
text-align: center;
margin-left: auto;
margin-right: auto;
}
.SubServicesList li {
display: inline;
list-style: none;
list-style-type: none;
margin-right: 10px;
text-align: center;
line-height: 26px;
cursor: pointer;
}
.SubServicesList li a:hover {
color: #333333;
}
.subServices {
width: 75%;
margin: 0 auto;
}
.subServices li.subServiceItem {
display: block;
list-style: none;
list-style-type: none;
height: auto;
clear: both;
}
.subServices li.subServiceItem .image {
float: left;
display: block;
margin-right: 10px;
margin-bottom: 10px;
}
.subServices li.subServiceItem .image {
float: left;
display: block;
}
/*.subServices li.subServiceItem { display:none; } */
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.0/jquery.min.js"></script>
<ul class="SubServicesList">
<li><a data-target="1">Name 1</a></li>
<li><a data-target="2">Name 2</a></li>
<li><a data-target="3">Name 3</a></li>
</ul>
<ul class="subServices">
<li class="subServiceItem" id="1">
1 hwiufhwriufhiurhfiureh
</li>
<li class="subServiceItem" id="2">
2 hwiufhwriufhiurhfiureh
</li>
<li class="subServiceItem" id="3">
3 hwiufhwriufhiurhfiureh
</li>
</ul>
This is how I did it
$(".SubServicesList > li > a").click(function () {
$(".subServices>li").hide();
$(".subServices").find("li[id='" + $(this).attr('id') + "']").slideToggle(true);
});
Here is the JSFiddle

JavaScript & Delay on Hovering Links?

Is there a way through JavaScript to set the links on a timer before its closes out? I don't want it to seem so sensitive. Such as if a user accidentally mouses off the link it closes right away. Any video recommendation or links?
Thanks,
I am not using jQuery......
* {
padding: 0;
margin: 0;
}
body {
padding: 5px;
font-family: Cambria, "Hoefler Text", "Liberation Serif", Times, "Times New Roman", serif;
}
ul {
list-style: none;
}
ul li {
float: left;
padding-right: 1px;
position: relative;
}
ul a {
display: table-cell;
vertical-align: middle;
width: 100px;
height: 50px;
text-align: center;
background-color: #2F2F2F;
color: #AE0002;
text-decoration: none;
}
ul a:hover {
background-color: #828282;
color: #FFFFFF;
}
li > ul {
display: none;
position: absolute;
left: 0;
top: 100%;
}
li:hover > ul {
display: block;
}
li > ul li {
padding: 0px;
padding-top: 1px;
}
li > ul li > ul {
left: 100%;
top: 0;
padding-left: 1px;
}
li > ul li > ul li {
width: 100px;
}
<body>
<ul>
<li>Sports News
<ul>
<li>Football
<ul>
<li>NFL
</li>
<li>ESPN Football
</li>
</ul>
</li>
<li>Baseball
<ul>
<li>MLB
</li>
<li>ESPN Baseball
</li>
</ul>
</li>
<li>Soccer
<ul>
<li>FIFA
</li>
<li>ESPN Soccer
</li>
</ul>
</li>
<li>Basketball
<ul>
<li>NBA
</li>
<li>ESPN Basketball
</li>
</ul>
</li>
<li>Auto Racing
<ul>
<li>ESPN Racing
</li>
<li>Nascar
</li>
</ul>
</li>
</ul>
</li>
</ul>
</body>
Instead of css, show/hide ul using javascript. Handle mouseover and mouseout events to show/hide. To delay, on hover, show using timer and on mouseout, hide as well as clear the timer.
function show(ul) {
ul.css("display", "inline-block");
}
function hide(ul) {
ul.css("display", "none");
}
$("li").mouseover(function () {
var ul = $(this).children("ul");
var timer = setTimeout(function () {
show(ul);
}, 400);
$(this).data("timer", timer);
}).mouseout(function () {
var ul = $(this).children("ul");
var timer = $(this).data("timer");
clearTimeout(timer);
hide(ul);
});
Demo: http://jsfiddle.net/k06dLnmk/
You can use transition delay.
transition-delay:1s;
Similar Question:
Delay hover
or you can use javascript to toggle with the css clasess
window.setInterval("javascript function", milliseconds);
Edit: Oh sorry as the comment pointed out. display none does not work with transition delay. Would you consider using visibility property instead?
div > ul {
. . .
visibility:hidden;
opacity:0;
transition:visibility 0s linear 0.5s,opacity 0.5s linear;
}
div:hover > ul {
visibility:visible;
opacity:1;
transition-delay:0s;
}

Categories

Resources