I have made a script for animating my menu li element after mouseovering the a element inside it.
Everything works fine, but I want something else. I want the effect not to disappear but to linger as long as the mouse is over the a element.
What function to use?
Script so far:
jQuery(document).ready(function($){
$(".main-navigation a").mouseover(function() {
$(this).parent().animate({
backgroundColor: "green"
}, "normal"),
$(this).parent().animate({
backgroundColor: "transparent"
})
.mouseleave(function() {
$(this).parent().animate({
backgroundColor: "transparent"
}, "normal")
});
});
});
http://jsfiddle.net/neugu8r9/
You could do this using CSS's #keyframes without jQuery.
ul {
position: relative;
width: 250px;
height: 50px;
padding: 0;
margin: 0;
list-style: none;
}
li a {
width: 100%;
height: 100%;
line-height: 50px;
text-align: center;
}
li a:before {
position: absolute;
content: '';
width: 100%;
height: 100%;
display: block;
z-index: -1;
}
li {
position: relative;
height: 50px;
width: 250px;
text-align: center;
border: 1px solid black;
}
a:hover:before {
-webkit-animation: pulse 0.8s ease-in-out infinite alternate;
animation: pulse 0.8s ease-in-out infinite alternate;
}
#-webkit-keyframes pulse {
0% {
background: transparent;
}
50% {
background: green;
}
100% {
background: transparent;
}
}
#keyframes pulse {
0% {
background: transparent;
}
50% {
background: green;
}
100% {
background: transparent;
}
}
<nav class="main-navigation">
<ul>
<li><a>Menu-item#1</a></li>
<li><a>Menu-item#2</a></li>
<li><a>Menu-item#3</a></li>
<li><a>Menu-item#4</a></li>
</ul>
</nav>
Here is the Full jQuery solution for you buddy, hope it helps:=)
jQuery(document).ready(function($){
var intervalID;
$(".main-navigation ul li a").hover(function(){
var that = $(this);
var opacityToggle = function(){
if(!that.children('.green').length){
$(that).prepend('<span class="green"></span>');
$('.green').animate({opacity:1},500);
}
else if(that.children('.green').length){
$('.green').animate({opacity:0},500,function(){
$('.green').remove();
});
}
}
intervalID = setInterval(opacityToggle, 500);
},function(){
$('.green').remove();
clearInterval(intervalID);
intervalID = 0;
});
});
ul{
list-style:none;
}
li a {
height:100%;
text-align:center;
position:relative;
width:inherit;
display:block;
}
li {
height: 50px;
width: 250px;
text-align: center;
border: 1px solid black;
}
.green{
position:absolute;
background-color:green;
width:100%;
height:100%;
display:block;
opacity:0;
z-index:-1;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<nav class="main-navigation">
<ul>
<li><a>Menu-item#1</a></li>
<li><a>Menu-item#2</a></li>
<li><a>Menu-item#3</a></li>
<li><a>Menu-item#4</a></li>
</ul>
</nav>
Related
My best attempt to remedy this toggles the visibility on and off when hovering. However, this isn't ideal because the menu is supposed to transition into view. If the visibility is toggled, the transition isn't seen by the user when approaching the "hover element" from below.
My testing makes me think the issue is purely CSS related but I've gone ahead and included the javascript if it helps. The visibility toggle I mentioned above is commented out.
let items = document.getElementsByClassName('items');
let menuBtn = document.getElementById('menuBtn');
let menuList = document.getElementById('menuList');
let menuClass = document.getElementsByClassName('menu');
menuBtn.addEventListener('mouseenter', func, false);
menuList.addEventListener('mouseleave',func2, false);
//visibilityToggle('hidden', 'none');
function func() {
console.log('out');
//visibilityToggle('visible', 'visible');
}
function func2() {
//visibilityToggle('hidden', 'none');
console.log('in');
}
function visibilityToggle(vis, point) {
for (let i = 0; i < items.length; i++){
items[i].style.visibility = vis;
items[i].style.pointerEvents = point;
}
}
.trigger {
width: 200px;
height: 53px;
/*
border: 1px solid black;
background: green;
*/
}
.menu {
width: 200px;
pointer-events: visible;
}
.menu a {
background-color: #eee;
color: black;
display: block;
padding: 12px;
text-decoration: none;
}
.menu a:hover {
background-color: #ccc;
}
.menu a.active {
background-color: #04AA6D;
color: white;
}
.items {
font-size: 50px;
opacity: 0;
position: relative;
top: -20px;
cursor: pointer;
pointer-events: none;
transition: opacity 400ms ease-in-out, transform 400ms ease-in-out;
}
.trigger:hover .items {
opacity: 1;
cursor: pointer;
transform: translate(0px, 20px);
}
#menuBtn {
border: 5px solid black;
}
<p>I am lost</p>
<div class="trigger">
<div class="menu" id="menuList">
Menu
<div class="items">
One
Two
Three
Four
</div>
</div>
</div>
I guess that issue can solve without js. Just change hover event to a #menuBtn and .items and insert reset pointer-events: initial . And should changing link class from items to item, because you applying styles to the group of links and the links itself.
.trigger {
width: 200px;
height: 53px;
/*
border: 1px solid black;
background: green;
*/
}
.menu {
width: 200px;
pointer-events: visible;
}
.menu a {
background-color: #eee;
color: black;
display: block;
padding: 12px;
text-decoration: none;
}
.menu a:hover {
background-color: #ccc;
}
.menu a.active {
background-color: #04aa6d;
color: white;
}
.items {
font-size: 50px;
opacity: 0;
position: relative;
top: -20px;
cursor: pointer;
pointer-events: none;
transition: opacity 400ms ease-in-out, transform 400ms ease-in-out;
}
#menuBtn:hover + .items, /* Add event to #menuBtn */
.items:hover { /* Keep hover effect on the .items */
opacity: 1;
cursor: pointer;
transform: translate(0px, 20px);
pointer-events: initial; /* Reset pointer-events */
}
#menuBtn {
border: 5px solid black;
}
<div class="trigger">
<div class="menu" id="menuList">
Menu
<div class="items">
One
<!-- Changed items to item -->
Two
<!-- Changed items to item -->
Three
<!-- Changed items to item -->
Four
<!-- Changed items to item -->
</div>
</div>
</div>
Issue was ur items was position:relative so it actually is in same position as they are visible,So need to make them relatable only when hover otherwise make it position:absolute
.item-div{
position: absolute;
}
.trigger:hover .items {
position:relative;
}
let items = document.getElementsByClassName('items');
let menuBtn = document.getElementById('menuBtn');
let menuList = document.getElementById('menuList');
let menuClass = document.getElementsByClassName('menu');
menuBtn.addEventListener('mouseenter', func, false);
menuList.addEventListener('mouseleave',func2, false);
//visibilityToggle('hidden', 'none');
function func() {
console.log('out');
//visibilityToggle('visible', 'visible');
}
function func2() {
//visibilityToggle('hidden', 'none');
console.log('in');
}
function visibilityToggle(vis, point) {
for (let i = 0; i < items.length; i++){
items[i].style.visibility = vis;
items[i].style.pointerEvents = point;
}
}
.trigger {
width: 200px;
height: 53px;
/*
border: 1px solid black;
background: green;
*/
}
.menu {
width: 200px;
pointer-events: visible;
position:relative;
}
.menu a {
background-color: #eee;
color: black;
display: block;
padding: 12px;
text-decoration: none;
}
.menu a:hover {
background-color: #ccc;
}
.item-div{
position: absolute;
width: 100%
}
.menu a.active {
background-color: #04AA6D;
color: white;
}
.items {
font-size: 50px;
opacity: 0;
top: -20px;
cursor: pointer;
pointer-events: none;
transition: opacity 400ms ease-in-out, transform 400ms ease-in-out;
}
.trigger:hover .items {
opacity: 1;
cursor: pointer;
transform: translate(0px, 20px);
position:relative;
}
#menuBtn {
border: 5px solid black;
}
p:first-child {
text-decoration: line-through;
}
<p>I am lost</p>
<p>Your are Alive</p>
<div class="trigger">
<div class="menu" id="menuList">
Menu
<div class="items item-div">
One
Two
Three
Four
</div>
</div>
</div>
I am trying to build a menu that slides in and out with the press of a button. Also, when menu is opened, it should slide out when clicked any part of the screen.
So far I have managed to create everything except the slide out effect, now the slide just disappears, without moving from right to left.
var navBtn = document.getElementById("navBtn");
var navMenu = document.getElementById("navMenu");
var container = document.getElementById("container");
navBtn.addEventListener("click", showMenu);
container.addEventListener("click", hideMenu);
navMenu.style.display = "none";
function showMenu(){
if(navMenu.style.display !== "none"){
navMenu.style.display = "none"}
else{navMenu.style.display = "block", container.style.background = "rgba(0, 102, 199, 1)";}}
function hideMenu(){
if(navMenu.style.display = "block"){
navMenu.style.display = "none", container.style.background = "lightblue";}}
#main-container {
width: 350px;
height: 600px;
border: 1px solid black;
position: absolute;
overflow: hidden;
}
#container {
width: 350px;
height: 100%;
display: absolute;
z-index: 1;
background: rgba(0, 102, 199, 0.8);
}
#navBtn {
width: 50px;
height: 50px;
background: red;
position: absolute;
z-index: 999;
}
#navMenu {
width: 250px;
height: 100%;
background: blue;
position: absolute;
z-index: 9999;
top: 0;
animation-name: slidein;
animation-duration: .5s;
}
#-webkit-keyframes slidein {
0% {transform: translateX(-200px);}
100% {transform: translateX(0px);}
}
#navMenu.close {
animation-name: slideout;
animation-duration: .5s;
}
#-webkit-keyframes slideout {
0% {transform: translateX(0px);}
100% {transform: translateX(-200px);}
}
<div id="main-container">
<div id="navBtn"></div>
<div id="container">
<div id="navMenu"></div>
</div>
</div>
Maybe someone could show me a way to achieve this? Basically the slide in effect should be the same as the slide in, just in a reverse way.
function openNav() {
document.getElementById("mySidenav").style.width = "250px";
document.getElementById("main").style.marginLeft = "250px";
}
function closeNav() {
document.getElementById("mySidenav").style.width = "0";
document.getElementById("main").style.marginLeft = "0";
}
body {
font-family: "Lato", sans-serif;padding:40px;
}
.sidenav {
height: 100%;
width: 0;
position: fixed;
z-index: 1;
top: 0;
left: 0;
background-color: #B971BB;
overflow-x: hidden;
transition: 0.5s;
padding-top: 60px;
}
.sidenav a {
padding: 8px 8px 8px 32px;
text-decoration: none;
font-size: 25px;
color: #fff;
display: block;
transition: 0.3s;
}
.sidenav a:hover {
color: #f1f1f1;
}
.sidenav .closebtn {
position: absolute;
top: 0;
right: 25px;
font-size: 36px;
margin-left: 50px;
}
#main {
transition: margin-left .5s;
padding: 16px;
}
#media screen and (max-height: 450px) {
.sidenav {padding-top: 15px;}
.sidenav a {font-size: 18px;}
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.2.1/jquery.min.js"></script>
<div id="mySidenav" class="sidenav">
×
About
Services
Clients
Contact
</div>
<div id="main">
<h2>Sidena Example</h2>
<p>Click on the element below to open the side navigation menu, and push this content to the right.</p>
<span style="font-size:30px;cursor:pointer" onclick="openNav()">☰ open</span>
</div>
html
<div id="main-container">
<div id="navBtn"></div>
<div id="container">
<div id="navMenu"></div>
</div>
</div>
jsCode
var navBtn = document.getElementById("navBtn");
var navMenu = document.getElementById("navMenu");
var container = document.getElementById("container");
navBtn.addEventListener("click", showMenu);
container.addEventListener("click", hideMenu);
//navMenu.style.display = "none"; // remove the display: none as you cannot animate display block to display none
function showMenu() {
container.classList.add('open');
}
function hideMenu() {
container.classList.remove('open');
}
and the css
#main-container {
width: 350px;
height: 600px;
border: 1px solid black;
position: absolute;
overflow: hidden;
}
#container {
width: 350px;
height: 100%;
z-index: 1;
background: rgba(0, 102, 199, 0.8);
transition: all 0.3s ease-in-out;
}
#navBtn {
width: 50px;
height: 50px;
background: red;
position: absolute;
z-index: 999;
}
#navMenu {
width: 250px;
height: 100%;
background: blue;
position: absolute;
z-index: 9999;
top: 0;
left: -250px;
transition: all 0.3s ease-in-out;
}
#container.open {
background: rgba(0, 102, 199,1);
}
#container.open #navMenu {
left: 0;
}
Looks like you attached the slide-out animation to a .close class that you never apply to the menu.
The easiest way to do this and to have more control is to add a class to the container, when the menu should be opened. afterwards just use css and left position along with transition to animate the menu. I'll provide code in a minute
I was trying a javascript function to fix a part of header on scrollup. It's working fine but I want to make the movement of fixed part smooth by adding transition property of CSS3. I tried but its not working. Request your help plz.
window.onscroll = myFunction;
function myFunction() {
if(document.body.scrollTop > 200 || document.documentElement.scrollTop > 200) {
document.getElementById("hdr_nav").style.position = "fixed";
} else {
document.getElementById("hdr_nav").style.position = "";
}
}//end function
*{margin: 0; padding: 0; box-sizing: border-box; -webkit-box-sizing: border-box; }
body {height: 3000px;}
.hdr_box {float: left; width: 100%; height: 65px; background: #eff1f2; position: relative; padding: 0; margin: 0;}
.hdr_box > .row1 {
float: left;
width: 100%;
height: 20px;
padding: 15px;
}
nav {
float: left;
width: 100%;
height: auto;
background: #e4e6e8;
position: relative;
transition: all 1s;
-webkit-transition: all 1s;
-moz-transition: all 1s;
}
nav ul {
list-style: none;
float: left;
width: 100%;
padding: 0;
margin: 0;
}
nav ul li {
float: left;
width: auto;
border-right: solid 1px #cacaca;
}
nav ul li a {
float: left;
width: auto;
padding: 16px;
text-align: center;
font-size: 14px;
}
<div class="hdr_box" id="hdr">
<div class="row1" id="hdr_row1"><h3>CompanyName</h3></div>
</div>
<nav id="hdr_nav">
<ul>
<li>About Us</li>
<li>Business</li>
<li>Our Work</li>
<li>Challenges</li>
</ul>
</nav>
That is because you change the position property from absolute to fixed and that can't be animated / transitioned. Transitions only work for properties with a unit, eg. px, rem, %, or stuff like opacity.
You can fix it however with a keyframe animation:
nav.is-fixed {
position: fixed;
animation: scroll .5s ease-out;
}
#keyframes scroll {
from {
transform: tranlateY(-100%);
}
to {
transform: tranlateY(0%);
}
}
Make sure to prefix #keyframes and transform if needed.
And a little change to the JS:
window.onscroll = myFunction;
function myFunction() {
var scrollAmount = document.body.scrollTop || document.documentElement.scrollTop;
var nav = document.getElementById("hdr_nav");
if(scrollAmount > 200) {
nav.classList.add('is-fixed');
} else {
nav.classList.remove('is-fixed');
}
}
https://jsfiddle.net/41nspon8/3/
add new CSS rule
.nav-fixed {
position: fixed;
-webkit-animation: slideInDown 450ms 1 ease-in-out;
}
#-webkit-keyframes slideInDown {
from {transform: translate(0%, -100%); }
to {transform: translate(0%, 0%); }
}
modify your js code
//document.getElementById("hdr_nav").style.position = "fixed";
document.getElementById("hdr_nav").classList.add("nav-fixed");
} else {
//document.getElementById("hdr_nav").style.position = "";
document.getElementById("hdr_nav").classList.remove("nav-fixed");
https://jsfiddle.net/13m8u7xm/
At the moment my hamburger button works just fine before it transforms, however after the hamburger button tranforms to the red "X" button if you click on any part of the "X" the button will transform, but it will not close the menu like it should. I can not find where I messed up.
Here is jsfiddle: https://jsfiddle.net/ex3z5o8L/
Here is the code:
<!DOCTYPE html>
<html>
<head>
<title></title>
<style type="text/css">
*{
margin: 0px;
padding: 0px;
font-family: "Verdana";
}
#image {
position: relative;
z-index: -1 ;
height: 100vh;
width: 100%;
}
#content {
position: relative;
height: 100vh;
width: 100%;
background-color:#4d5555;
}
#footer {
position: relative;
width: 100%;
height: 100vh;
background-color:#ffffff;
}
div#header #fullScreenNav{
position:fixed;
height:0px;
width:100%;
background:#000;
top:0px;
left:0px;
overflow:hidden;
z-index:2;
}
#fullScreenNavbtn{
background: #f3f3f3;
padding: 10px;
position: absolute;
z-index: 1 ;
top: 70vh;
left: 50%;
margin-right: -50%;
transform: translate(-50%, -50%)
}
/* ---------------------------------------------------------Start Of Hamburger Button------------------------------------------------------- */
.c-hamburger {
display: block;
position: fixed;
overflow: hidden;
margin: 0;
padding: 0;
width: 64px;
height: 64px;
font-size: 0;
text-indent: -9999px;
appearance: none;
box-shadow: none;
border-radius: none;
border: none;
cursor: pointer;
transition: background 0.1s;
border-radius:10px;
background: transparent;
right:5px;
top:5px;
z-index: 3;
}
.c-hamburger:focus {
outline: none;
}
.c-hamburger:hover span,
.c-hamburger:hover span::before,
.c-hamburger:hover span::after
{background: black;}
.c-hamburger span {
display: block;
position: absolute;
top: 28px;
left: 10px;
right: 10px;
height: 8px;
background: #e6e6e6;
border-radius:100px;
}
.c-hamburger span::before,
.c-hamburger span::after {
position: absolute;
display: block;
left: 0;
width: 100%;
height: 8px;
background-color: #e6e6e6;
content: "";
border-radius:100px;
}
.c-hamburger span::before {
top: -15px;
}
.c-hamburger span::after {
bottom: -15px;
}
.c-hamburger--htx {
}
.c-hamburger--htx span {
}
.c-hamburger--htx span::before,
.c-hamburger--htx span::after {
transition-duration: 0.1s, 0.1s;
transition-delay: 0.1s, 0s;
}
.c-hamburger--htx span::before {
transition-property: top, transform;
}
.c-hamburger--htx span::after {
transition-property: bottom, transform;
}
/* active state, i.e. menu open */
.c-hamburger--htx.is-active {
background-color: #cb0032;
}
.c-hamburger--htx.is-active span {
background: none;
}
.c-hamburger--htx.is-active span::before {
top: 0;
transform: rotate(45deg);
background: white;
}
.c-hamburger--htx.is-active span::after {
bottom: 0;
transform: rotate(-45deg);
background: white;
}
.c-hamburger--htx.is-active span::before,
.c-hamburger--htx.is-active span::after {
transition-delay: 0s, 0.1s;
}
/* ---------------------------------------------------------End of Hamburger Button-------------------------------------------------- */
</style>
</head>
<body>
<div id="header">
<div id="headerBtnHolder">
<img onload="parallex1('image')" src="" id="image" />
<button id="fullScreenNavbt" class="c-hamburger c-hamburger--htx" onclick="toggleNavPanel('fullScreenNav','100vh','fullScreenNavbt')">
<span>toggle menu</span>
</button>
</div>
<div id="fullScreenNav">
<div>
</div>
</div>
</div>
<div id="content"></div>
<div id="footer"></div>
<script>
(function() {
"use strict";
var toggles = document.querySelectorAll(".c-hamburger");
for (var i = toggles.length - 1; i >= 0; i--) {
var toggle = toggles[i];
toggleHandler(toggle);
};
function toggleHandler(toggle) {
toggle.addEventListener( "click", function(e) {
e.preventDefault();
(this.classList.contains("is-active") === true) ? this.classList.remove("is-active") : this.classList.add("is-active");
});
}
})();
</script>
<script>
function toggleNavPanel(dropDivId, height, btnId){
var panel = document.getElementById(dropDivId), maxH= height, nav = btnId;
if(panel.style.height == maxH){
panel.style.height = "0px";
} else {
panel.style.height = maxH;
}
window.addEventListener('mouseup', function(event){
if(event.target != panel && event.target.parentNode !=panel && event.target.id != nav ){
panel.style.height = "0px";
}
});
}
</script>
<script type="text/javascript">
function parallex1(ObjectId){
var ypos, image;
function parallex () {
ypos = window.pageYOffset;
image = document.getElementById(ObjectId);
image.style.top = ypos * .6 + 'px';
}
window.addEventListener('scroll', parallex);}
</script>
</body>
</html>
Your basic problem is that on every click you're adding an eventListener so you re creating an event hell. Remove the onClick and add the event listeners only once to run your methods. Also your checks for toggling the panel are wrong. There's a span inside the button which should toggle as well.
I have a demo website. how can I get the menu hover effect as in the reference website given below. I have fiddled little bit here, but I didn't get the transition when I hover on the menu item
ref site :- click here
hover on the top menu and see the effect. how do I get that effect ?
see the code here till I have done
HTML
<li>
<div class="header-navigation-item-state-wrapper">
<div class="white">
<h4 class="header-white">Collections</h4>
</div>
<div class="black">
<h4 class="header-black">Collections</h4>
</div>
</div>
</li>
CSS
* {
background:yellow
}
li {
list-style:none;
}
.header-black {
background:#000;
color:#fff;
padding:10px;
display:block
}
.black {
display:none;
}
.header-white {
background:#fff;
color:#000;
padding:10px;
display:block
}
JQuery
$(document).ready(function () {
$("li").mouseenter(function () {
$(".white").css('display', 'none');
$(".black").css('display', 'block');
});
$("li").mouseleave(function () {
$(".white").css('display', 'block');
$(".black").css('display', 'none');
});
})
You can use 3d effect following way.
.menu li {
display: inline-block;
}
.menu li a {
color: #fff;
display: block;
text-decoration: none;
overflow: visible;
line-height: 20px;
font-size: 24px;
padding: 15px 10px;
}
/* animation domination */
.threed {
perspective: 200px;
transition: all .07s linear;
position: relative;
cursor: pointer;
}
/* complete the animation! */
.threed:hover .box,
.threed:focus .box {
transform: translateZ(-25px) rotateX(90deg);
}
.box {
transition: all .3s ease-out;
transform: translatez(-25px);
transform-style: preserve-3d;
pointer-events: none;
position: absolute;
top: 0;
left: 0;
display: block;
width: 100%;
height: 100%;
}
.white {
transform: rotatex(0deg) translatez(25px);
background: white;
color: black;
}
.black {
transform: rotatex(-90deg) translatez(25px);
color: white;
background: black;
}
.white, .black {
display: block;
width: 100%;
height: 100%;
position: absolute;
top: 0;
left: 0;
padding: 15px 10px;
pointer-events: none;
box-sizing: border-box;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.0.0/jquery.min.js"></script>
<ul class="menu">
<li><a href="/" class="threed">
Home
<span class="box">
<span class="white">Home</span>
<span class="black">Home</span>
</span>
</a></li>
</ul>
You can change as per your requirement.
Hope it helps.