Open div on mouse enter and keep it open - javascript

I'm trying to make a div open when you hover a link. Which is simple enough and I'm doing fine. But I also want to be able to access the div without it closing. So if I hover over the newly opened div it will stay open. But If I hover out of the div I want it to close.
I also want to make sure that if I hover out of the link that the div closes. I have done this a few times before but for the life of me I cant sort it back out. I remember using setTimeout previously but my mind has went to mush and it's late so thought I might as well ask for some help.
I'm also aware that mouseenter and mouseleave would be far better than hover in this situation I just typed it up as hover for speed.
UPDATE
Changing the HTML is not an option this is a jquery question not an html or CSS one.
jQuery(document).ready(function($) {
"use strict";
$("li.true a").hover(
function() {
$(".open").fadeIn(1000);
}, function() {
$(".open").fadeOut(1000);
}
);
$(".open").hover(
function() {
$(this).show();
}, function() {
$(this).fadeOut(1000);
}
);
});
ul,
li {
list-style: none;
}
li {
display: inline-block;
}
a {
display: block;
padding: 10px;
background-color: black;
color: white;
-webkit-transition: all 0.35s ease-in-out;
transition: all 0.35s ease-in-out;
cursor: pointer;
}
a:hover {
color: black;
background-color: white;
}
li.true a {
background-color: green;
}
li.true a:hover {
background-color: blue;
color: green;
}
div.open {
background-color: red;
width: 100%;
height: 300px;
display: none;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.10.2/jquery.min.js"></script>
<nav>
<ul>
<li><a>not</a>
</li>
<li><a>not</a>
</li>
<li class="true"><a>true</a>
</li>
<li><a>not</a>
</li>
<li><a>not</a>
</li>
</ul>
</nav>
<div class="open"></div>

Move the div with the class open to the li as child element. The JS is now also simpler for your case. You can find the fiddle here: https://jsfiddle.net/ej5gkgat/.
<nav>
<ul>
<li><a>not</a>
</li>
<li><a>not</a>
</li>
<li class="true">
<a>true</a>
<div class="open"></div>
</li>
<li><a>not</a>
</li>
<li><a>not</a>
</li>
</ul>
</nav>
New CSS:
ul,
li {
list-style: none;
}
li {
display: inline-block;
}
a {
display: block;
padding: 10px;
background-color: black;
color: white;
-webkit-transition: all 0.35s ease-in-out;
transition: all 0.35s ease-in-out;
cursor: pointer;
}
a:hover {
color: black;
background-color: white;
}
li.true a {
background-color: green;
}
li.true a:hover {
background-color: blue;
color: green;
}
div.open {
position: absolute;
background-color: red;
width: 300px;
height: 300px;
display: none;
}
New JS:
jQuery(document).ready(function($) {
"use strict";
$("li.true").hover(
function() {
$(".open").fadeIn(1000);
}, function() {
$(".open").fadeOut(1000);
}
);
});

Simple solution is not to use both parameters of hover in jquery.
when hover on "li.true a" simply ignore the second parameter, which hides your div. use null to skip on div.open's hover.
but if you ask for the right way. use CSS for these type of interactions. there is no need for JS to do this.
Edit: If you need to hide it when on siblings of "li.true a"'s hover.
jQuery(document).ready(function($) {
"use strict";
$("li.true a").hover(
function() {
$(".open").fadeIn(1000);
}
);
$("li:not(.true) a").hover(
function() {
$(".open").fadeOut(1000);
}
);
$(".open").hover(null, function() {
$(this).fadeOut(1000);
}
);
});
ul,
li {
list-style: none;
}
li {
display: inline-block;
}
a {
display: block;
padding: 10px;
background-color: black;
color: white;
-webkit-transition: all 0.35s ease-in-out;
transition: all 0.35s ease-in-out;
cursor: pointer;
}
a:hover {
color: black;
background-color: white;
}
li.true a {
background-color: green;
}
li.true a:hover {
background-color: blue;
color: green;
}
div.open {
background-color: red;
width: 100%;
height: 300px;
display: none;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.10.2/jquery.min.js"></script>
<nav>
<ul>
<li><a>not</a>
</li>
<li><a>not</a>
</li>
<li class="true"><a>true</a>
</li>
<li><a>not</a>
</li>
<li><a>not</a>
</li>
</ul>
</nav>
<div class="open"></div>

Use this js it uses timeout
jQuery(document).ready(function($) {
"use strict";
var t;
$("li.true a, .open").hover( function() {
clearTimeout (t);
$(".open").fadeIn(1000);
}, function() {
clearTimeout (t);
t = setTimeout(function(){
$(".open").fadeOut(1000);
},1000);
} );
});

You can do this with only css:
body{ font-family:sans-serif; }
nav {
background:blue;
padding:12px;
}
ul {
list-style:none;
}
ul li {
display:inline-block;
padding:6px;
border:1px inset white;
cursor:pointer;
transition:all .5s;
background:red;
}
ul li:hover {
background:white;
color:black;
}
ul ul {
display:none;
}
ul li:hover > ul {
display:inherit;
position:absolute;
top:68px;
float:none;
}
ul ul li {
display:inherit;
float:none;
position:relative;
left:-47px;
}
HTML:
<nav>
<ul>
<li> Example.com </li>
<li> Languages
<ul>
<li> HTML </li>
<li> CSS </li>
<li> Javascript </li>
</ul>
</li>
<li> Something
<ul>
<li> Something </li>
</ul>
</li>
</ul>
</nav>

You can try doing it without timeout (not a big fan of), but with fadeTo() and stop()
Opacity is used to check visibility and calculate estimate remaining fade time.
JSFiddle example
jQuery(document).ready(function($) {
"use strict";
var fadeout = 1000;
var fadein = 800;
$("li.true a").hover(function() {
var opacity = $(".open").css("opacity");
opacity = opacity && opacity < 0.8 ? opacity : 0;
$(".open").stop(true).fadeTo(fadein*(1-opacity), 1);
}, function() {
var opacity = $(".open").css("opacity");
if (opacity > 0) $(".open").fadeTo(fadeout, 0);
});
$(".open").hover(function() {
var opacity = $(this).css("opacity");
if (opacity > 0) $(this).stop(true).fadeTo(fadein*(1-opacity), 1);
}, function() {
$(this).fadeTo(fadeout, 0);
});
});

Related

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/

CSS how to add sliding transition

I have the following fiddle demo of a working sidenav menu with sliding sub menu contents. I followed the same demo without using Jquery (actually first using plain JS and then via CSS hover selector instead of click) and in my case sub menu doesn't slides/animates in the same way.
.submenu {
display: none;
}
.parent:hover .submenu,.submeun:hover {
display: block;
}
Is that animation due to Jquery toggle method?
$(document).ready(function() {
$('.parent').click(function() {
$('.submenu').toggle('visible');
});
});
How can I replicate the same approach without using jquery, via css or plain JS as I don't want to use jquery just for one simple sliding animation.
JSFIDDLE
This way ?
document.getElementById('home').addEventListener('click', function(e) {
var nextEl = e.target.nextElementSibling;
if(!nextEl.classList.contains('submenu')) {
return false;
}
if(nextEl.classList.contains('show')) {
nextEl.classList.remove('show')
}
else {
nextEl.classList.add('show');
}
});
.submenu {
-webkit-transition: max-height 1s;
-moz-transition: max-height 1s;
-ms-transition: max-height 1s;
-o-transition: max-height 1s;
transition: max-height 1s;
background: #e5feff;
overflow: hidden;
max-height: 0;
}
.submenu.show {
max-height: 300px;
}
<div id="sidebar">
<ul>
<li id="home" class="parent">Home</li>
<li class="submenu"><ul >
<li>Home 1</li>
<li>Home 2</li>
<li>Home 3</li>
</ul> </li>
<li>Explore</li>
</ul>
</div>
You could use slideToggle() and so avoid changing classes . This is just an option
Also , keep in mind that a submenu must be inside the parent li, for example <li>Home<ul><li>Sub link</li></ul></li> . I changed your HTML accordingly
see snippet below
$(document).ready(function() {
$('.parent').click(function() {
$(this).children(".submenu").slideToggle()
});
});
body, html {
height: 100%;
margin: 0;
overflow:hidden;
}
#sidebar {
background: #DF314D;
width: 240px;
height: 100%;
}
#sidebar ul {
padding: 0;
list-style: none;
}
#sidebar ul li {
padding: 15px 20px 15px 35px;
color: white;
}
#sidebar li:hover {
background: #C9223D;
}
.submenu {
display: none;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div id="sidebar">
<ul>
<li class="parent">Home
<ul class="submenu">
<li>Home 1</li>
<li>Home 2</li>
<li>Home 3</li>
</ul>
</li>
<li>Explore</li>
</ul>
</div>

add collapsible functionality to js tabs

I have some tabs I'm making and I'd like for them to be collapsible, but with my current code, that isn't possible because the script uses addClass/removeClass instead of something else, and I'm not sure how to fix that:
Code
$(document).ready(function() {
$('.tabs .tab-links a').on('click', function(e) {
var currentAttrValue = $(this).attr('href');
$('.tabs ' + currentAttrValue).fadeIn(600).siblings().hide();
$(this).parent('li').addClass('active').siblings().removeClass('active');
e.preventDefault();
});
});
$(document).ready(function() {
$('#filterOptions li a').click(function() {
var ourClass = $(this).attr('class');
$('#filterOptions li').removeClass('active');
$(this).parent().addClass('active');
if (ourClass == 'all') {
$('#ourHolder').children('div.item').show();
} else {
$('#ourHolder').children('div:not(.' + ourClass + ')').hide();
$('#ourHolder').children('div.' + ourClass).show();
}
return false;
});
});
.tabs {
width: 200px;
padding: 0;
overflow: hidden;
}
.tab-links li {
display: inline;
text-align: center;
list-style: none;
margin-left: 0;
padding: 0;
}
ul.tab-links {
padding: 0 0 10px 0;
text-align: center;
list-style: none;
margin: 0!important;
}
.tab-links a {
color: #000;
}
.tab-links b {
color: #fff000;
font-weight: 900;
}
.tab {
display: none;
}
.tab.active {
display: block;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.0/jquery.min.js"></script>
<div class="tabs">
<ul class="tab-links">
<li class="active">
<b>first</b>
</li>
<li>second
</li>
<li>third
</li>
</ul>
</div>
<div class="tabs">
<!-- TAB 1 -->
<div id="tab1" class="tab">
first
</div>
<!-- TAB 2 -->
<div id="tab2" class="tab">
second
</div>
<div id="tab3" class="tab">
third
</div>
Check this fiddle using toggleClass (not sure if I have understood your requirement though)
$(document).ready(function() {
$('.tabs .tab-links a').on('click', function(e) {
var currentAttrValue = $(this).attr('href');
if ( $('.tabs ' + currentAttrValue).is(':visible') )
{
$(this).parent('li').toggleClass('active');
$('.tabs ' + currentAttrValue).hide();
}
else
{
$('.tabs ' + currentAttrValue).fadeIn(600).siblings().hide();
$(this).parent('li').toggleClass('active').siblings().removeClass('active');
}
e.preventDefault();
});
});
.tab-links li.active {
color:#fff000;
font-weight:900;
}
<div class="tabs">
<ul class="tab-links">
<li class="active">
first</li>
<li>second</li>
<li>third</li>
</ul>
</div>
Try this:
$(document).ready(function() {
$('.tab-links li a').click(function() {
var ourClass = $(this).attr('href');
if(!$(ourClass).hasClass('active')){
$('.tabs').find('.active').removeClass('active');
}
$(ourClass).toggleClass('active');
return false;
});
});
Css:
.tab {
// display:none;
opacity: 0;
-webkit-transition: opacity .8s ease-in;
-moz-transition: opacity .8s ease-in;
-ms-transition: opacity .8s ease-in;
-o-transition: opacity .8s ease-in;
transition: opacity .8s ease-in;
height: 0px;
}
.tab.active {
// display:block;
opacity: 1;
height: 20px;
}
Fiddle

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;
}

html : navigation style change on hover

this is a part of a code in which i'm trying to change the menu item color when hover on a different div. I can modify the background color but not the actual text color.
<!DOCTYPE html>
<html>
<head>
<title>Untitled</title>
<style type="text/css">
.navigation li a { color: grey;}
</style>
</head>
<body>
<ul class="navigation" id="nav">
<li id="a" onmouseover="chbg('red')" onmouseout="chbg('black')">ABOUT </li>
<li id="b" onmouseover="chbg1('red')" onmouseout="chbg1('white')">CONTENT</li>
</ul>
<script type="text/javascript">
function chbg(color) {
document.getElementById('b').style.Color = color;
}
function chbg1(color) {
document.getElementById('a').style.backgroundColor = color;
}
</script>
</body>
</html>`
Need help in solving this issue.
Thanks
You are applying color to the li but the a is already getting color: gray; from the CSS.
As mentioned in the comment you would be much better off handling stuff like this with CSS and not JavaScript.
a {
color: gray;
}
a:hover,
a:focus {
color: red;
}
li:hover {
background-color: gray;
}
EDIT: It also seems like you misspelled gray. In CSS the american spelling is used. This is part of why I use hex-values in stead.
Use CSS its much easier
.navigation #a {
background:black;
}
.navigation #b {
background:white;
}
.navigation li:hover {
background:black;
}
Demo
#a {
background-color: black;
}
#b {
background-color: white;
}
#b:hover {
background-color: red;
}
#a:hover > a {
color: green;
}
#b:hover > a {
color: yellow;
}
HTML
<ul class="navigation" id="nav">
<li id="a">ABOUT
</li>
<li id="b">CONTENT
</li>
</ul>

Categories

Resources