I am working on a website and I have included a full-screen menu that drops in when the menu icon is clicked. However, I am running into an issue where the menu items (buttons) are still clickable when the menu is closed.
I am using React.js + Scss.
const MyNav = () => {
const toggleClass = (element, stringClass) => {
if(element.classList.contains(stringClass))
element.classList.remove(stringClass);
else
element.classList.add(stringClass);
}
useEffect(() => {
const body = document.querySelector('body');
const menu = document.querySelector('.menu-icon');
menu.addEventListener('click', () => toggleClass(body, 'nav-active'));
},[]);
console.log("this is being loaded");
return (
<>
<div class="menu-icon">
<span class="menu-icon__line menu-icon__line-left"></span>
<span class="menu-icon__line"></span>
<span class="menu-icon__line menu-icon__line-right"></span>
</div>
<div class="nav">
<div class="nav__content">
<ul class="nav__list">
<li class="nav__list-item">Home</li>
<li class="nav__list-item">About</li>
<li class="nav__list-item">Portfolio</li>
<li class="nav__list-item">Journal</li>
<li class="nav__list-item">Contact</li>
</ul>
</div>
</div>
</>
)
}
export default MyNav;
$font--color:var(--primary);
$font--color--active:var(--primary);
$transition--length: .8;
//default state
.menu-icon{
$size: 30px;
height: $size;
width: $size;
position: fixed;
z-index:2;
left: 50px;
top: 30px;
cursor: pointer;
&__line{
height: 2px;
width: $size;
display: block;
background-color: $font--color;
margin-bottom: 4px;
transition: transform .2s ease, background-color .5s ease;
}
&__line-left{
width: $size / 2;
}
&__line-right{
width: $size / 2;
float: right;
}
}
.nav{
$width: 100vw;
$height: 100vh;
$font--size--calc: calc(2vw + 10px);
$transition--easing: cubic-bezier(.77,0,.175,1);
position: fixed;
z-index:1;
&:before,&:after{
content: "";
position: fixed;
width:$width;
height:$height;
background: rgba(#eaeaea, .2);
z-index: -1;
transition: transform $transition--easing $transition--length + s;
transform: translateX(0%) translateY(-100%);
}
&:after{
background: var(--highlight);
transition-delay: 0s;
}
&:before{
transition-delay: .1s;
}
&__content{
position: fixed;
top:50%;
transform: translate(0%,-50%);
width: 100%;
text-align: center;
font-size: $font--size--calc;
font-weight: 200;
cursor: pointer;
}
&__list-item{
position: relative;
display: inline-block;
transition-delay: $transition--length + s;
opacity: 0;
transform: translate(0%, 100%);
transition: opacity .2s ease, transform .3s ease;
margin-right: 25px;
&:before{
content: "";
position: absolute;
background: $font--color--active;
width: 20px;
height: 1px;
top: 100%;
transform: translate(0%, 0%);
transition: all .3s ease;
z-index: -1;
}
&:hover{
&:before{
width: 100%;
}
}
}
}
//active state
body.nav-active{
$menu--items--count: 5;
.menu-icon{
&__line{
background-color: var(--primary);
transform: translateX(0px) rotate(-45deg);
}
&__line-left{
transform: translateX(1px) rotate(45deg);
}
&__line-right{
transform: translateX(-2px) rotate(45deg);
}
}
.nav{
visibility:visible;
&:before,&:after{
transform: translateX(0%) translateY(0%);
}
&:after{
transition-delay: .1s;
}
&:before{
transition-delay: 0s;
}
&__list-item{
pointer-events: all;
opacity: 1;
transform: translateX(0%);
transition: opacity .3s ease, transform .3s ease, color .3s ease;
#for $i from 0 through $menu--items--count {
&:nth-child(#{$i}){
transition-delay: $transition--length * $i / 8 + .5 + s;
}
}
}
}
}
Bonus points if you can tell me how to not have the site scrollable when the menu is open.
Thanks!
You need to have the visibility property set to hidden on the nav when it is not visible like this
.nav{
$width: 100vw;
$height: 100vh;
//add this when nav is not active by default
visibility: hidden;
transition:visibility .3s cubic-bezier(.77,0,.175,1);
$font--size--calc: calc(2vw + 10px);
$transition--easing: cubic-bezier(.77,0,.175,1);
position: fixed;
z-index:1;
.
.
.
}
To remove the scrollbar when menu is open you can set the overflow hidden on body using .nav-active class only
body.nav-active{
overflow:hidden;
$menu--items--count: 5;
.menu-icon{
.
.
.
}
Hope this helps !
I am a beginner in JS.
I found a mobile menu on codepen but I need to edit it to make it right for what i need.
Basically, the mobile menu I need to create contains few links that have anchors and redirect users to sections in the page.
The codepen example I found doesn't close the menu once a link is clicked. I tried to modify the code myself but it doesn't work.
Here the link to the original codepen: https://codepen.io/Gatsby/pen/YdWGgW
And this is the version I did but not working.
(function () {
let header = document.querySelector('.header');
let icon = document.querySelector('.icon-container');
let all = document.querySelectorAll('.menu-item');
icon.onclick = function () {
header.classList.toggle('menu-open');
}
all.onclick = function () {
header.classList.toggle('menu-open');
}
}());
Any help would be greatly appreciated. Thank you.
You can do it this way :
Basically, you get all of the menu classes, and add an event listener on them to close the menu on each click on any of them
(function() {
let header = document.querySelector('.header');
let icon = document.querySelector('.icon-container');
let menu_item = document.getElementsByClassName('menu-item');
icon.onclick = function() {
header.classList.toggle('menu-open');
}
var close = function() {
header.classList.toggle('menu-open');
};
for (var i = 0; i < menu_item.length; i++) {
menu_item[i].addEventListener('click', close, false);
}
}());
#import url(https://fonts.googleapis.com/css?family=Nobile);
/* Just container/placeholder rulesets - remove once in production */
body {
font-family: "Nobile";
margin: 0 auto;
line-height: 1.5;
background: #e0e0e0;
}
.container {
background: #f0f0f0;
position: relative;
overflow: hidden;
width: 375px;
height: 600px;
margin: 50px auto 0;
box-shadow: 0 0 50px 10px #aaa;
}
.container .header {
position: absolute;
display: block;
top: 0;
left: 0;
}
.content {
padding: 40px 5% 20px;
text-align: justify;
max-height: 100%;
color: #333;
overflow-y: scroll;
}
.content img {
width: 100%;
position: relative;
display: block;
margin: 40px auto 30px;
}
#media (max-width: 480px) {
.container {
margin: 0 auto;
width: 100%;
height: 100%;
box-shadow: none;
}
.container .header {
position: fixed;
}
.content {
overflow-y: hidden;
}
}
/* End container/placeholder */
/* Menu Header */
.header {
background: rgba(0, 0, 0, 0.8);
overflow: hidden;
height: 55px;
width: 100%;
z-index: 1;
position: fixed;
transition: all 0.4s ease-out, background 1s ease-out;
}
.header.menu-open {
height: 100%;
background: #111;
transition: all 0.45s ease-out, background 0.8s ease-out;
}
/* Menu List items */
.mobile-menu {
clear: both;
}
.header ul.menu {
position: relative;
display: block;
padding: 0px 40px 0;
list-style: none;
}
.header ul.menu li.menu-item a {
display: block;
position: relative;
color: #fff;
text-decoration: none;
font-size: 18px;
line-height: 2.8;
width: 100%;
-webkit-tap-highlight-color: transparent;
}
.header ul.menu li.menu-item {
border-bottom: 1px solid #333;
margin-top: 5px;
opacity: 0;
transition: opacity 0.6s cubic-bezier(0.4, 0.01, 0.165, 0.99), -webkit-transform 0.5s cubic-bezier(0.4, 0.01, 0.165, 0.99);
transition: transform 0.5s cubic-bezier(0.4, 0.01, 0.165, 0.99), opacity 0.6s cubic-bezier(0.4, 0.01, 0.165, 0.99);
transition: transform 0.5s cubic-bezier(0.4, 0.01, 0.165, 0.99), opacity 0.6s cubic-bezier(0.4, 0.01, 0.165, 0.99), -webkit-transform 0.5s cubic-bezier(0.4, 0.01, 0.165, 0.99);
}
.header ul.menu li.menu-item:nth-child(1) {
transition-delay: 0.35s;
}
.header ul.menu li.menu-item:nth-child(2) {
transition-delay: 0.3s;
}
.header ul.menu li.menu-item:nth-child(3) {
transition-delay: 0.25s;
}
.header ul.menu li.menu-item:nth-child(4) {
transition-delay: 0.2s;
}
.header ul.menu li.menu-item:nth-child(5) {
transition-delay: 0.15s;
}
.header ul.menu li.menu-item:nth-child(6) {
transition-delay: 0.1s;
}
.header ul.menu li.menu-item:nth-child(7) {
transition-delay: 0.05s;
}
.header.menu-open ul.menu li.menu-item {
opacity: 1;
}
.header.menu-open ul.menu li.menu-item:nth-child(1) {
transition-delay: 0.05s;
}
.header.menu-open ul.menu li.menu-item:nth-child(2) {
transition-delay: 0.1s;
}
.header.menu-open ul.menu li.menu-item:nth-child(3) {
transition-delay: 0.15s;
}
.header.menu-open ul.menu li.menu-item:nth-child(4) {
transition-delay: 0.2s;
}
.header.menu-open ul.menu li.menu-item:nth-child(5) {
transition-delay: 0.25s;
}
.header.menu-open ul.menu li.menu-item:nth-child(6) {
transition-delay: 0.3s;
}
.header.menu-open ul.menu li.menu-item:nth-child(7) {
transition-delay: 0.35s;
}
/* Menu Icon */
.icon-container {
position: relative;
display: inline-block;
z-index: 2;
float: right;
/* Simply change property to float left to switch icon side :) */
height: 55px;
width: 55px;
cursor: pointer;
-webkit-tap-highlight-color: transparent;
-webkit-transform: rotate(0deg);
transform: rotate(0deg);
transition: all 0.3s cubic-bezier(0.4, 0.01, 0.165, 0.99);
}
.icon-container #menuicon {
width: 20px;
height: 10px;
position: relative;
display: block;
margin: -4px auto 0;
top: 50%;
}
#menuicon .bar {
width: 100%;
height: 1px;
display: block;
position: relative;
background: #fff;
transition: all 0.3s cubic-bezier(0.4, 0.01, 0.165, 0.99);
}
#menuicon .bar.bar1 {
-webkit-transform: translateY(0px) rotate(0deg);
transform: translateY(0px) rotate(0deg);
}
#menuicon .bar.bar2 {
-webkit-transform: translateY(6px) rotate(0deg);
transform: translateY(6px) rotate(0deg);
}
.menu-open .icon-container {
-webkit-transform: rotate(90deg);
transform: rotate(90deg);
}
.menu-open .icon-container #menuicon .bar {
transition: all 0.4s cubic-bezier(0.4, 0.01, 0.165, 0.99);
transition-delay: 0.1s;
}
.menu-open .icon-container #menuicon .bar.bar1 {
-webkit-transform: translateY(4px) rotate(45deg);
transform: translateY(4px) rotate(45deg);
}
.menu-open .icon-container #menuicon .bar.bar2 {
-webkit-transform: translateY(3px) rotate(-45deg);
transform: translateY(3px) rotate(-45deg);
}
<div class="container">
<div class="header">
<div class="icon-container">
<div id="menuicon">
<div class="bar bar1"></div>
<div class="bar bar2"></div>
</div>
</div>
<div class="mobile-menu">
<ul class="menu">
<li class="menu-item">Mac
</li>
<li class="menu-item">iPad
</li>
<li class="menu-item">iPhone
</li>
<li class="menu-item">Watch
</li>
<li class="menu-item">TV
</li>
<li class="menu-item">Music
</li>
<li class="menu-item">Support
</li>
</ul>
</div>
</div>
<div class="content">
<img src="https://images.apple.com/v/iphone/home/y/images/overview/hero-iphone-xr_large.jpg" alt="" />
<p>“With so many trees in the city, you could see the spring coming each day until a night of warm wind would bring it suddenly in one morning. Sometimes the heavy cold rains would beat it back so that it would seem that it would never come and that
you were losing a season out of your life. This was the only truly sad time in Paris because it was unnatural. You expected to be sad in the fall. Part of you died each year when the leaves fell from the trees and their branches were bare against
the wind and the cold, wintry light."</p>
<p><em>- Ernest Hemingway, A Moveable Feast</em></p>
<img src="https://images.apple.com/v/iphone/home/y/images/overview/film_large.jpg" alt="" />
<p>"On under the heavy trees of the small town that are a part of your heart if it is your town and you have walked under them, but that are only too heavy, that shut out the sun and dampen the houses for a stranger; out past the last house and on to
the highway that rose and fell straight away ahead with banks of red dirt sliced cleanly away and the second growth timber on both sides. It was not his country but it was the middle of fall and all of this country was good to drive through and
to see. "</p>
<p><em>- Ernest Hemingway, "Fathers and Sons"</em></p>
</div>
</div>
Here I am using document.getElementsByClassName but you could also use document.querySelectorAll which is more useful if you want to use more complex selectors
I have designed a process timeline for my website.
Here's the code:
$('.pt-action-bar > .pt-action-bar-button').click(function () {
$(this).toggleClass('pt-action-bar-button--active').siblings().removeClass('pt-action-bar-button--active');
});
.process-timeline {
position: relative
}
.process-timeline .pt-timeline {
top: 57px;
left: 85px;
right: 85px;
position: absolute;
display: none;
height: 1px
}
#media (min-width: 768px) {
.process-timeline .pt-timeline {
display: block
}
}
.process-timeline .pt-timeline__backside-bar {
height: 1px;
background-color: #ebebeb
}
.process-timeline .pt-timeline__frontside-bar {
width: 0;
height: 1px;
top: 0;
left: 0;
position: absolute;
background-color: #00cdac;
-webkit-transition: width .4s ease;
transition: width .4s ease
}
.process-timeline .pt-action-bar {
display: -webkit-box;
display: -ms-flexbox;
display: flex;
-webkit-box-orient: vertical;
-webkit-box-direction: normal;
-ms-flex-direction: column;
flex-direction: column;
-webkit-box-align: center;
-ms-flex-align: center;
align-items: center
}
#media (min-width: 768px) {
.process-timeline .pt-action-bar {
position: relative;
-webkit-box-orient: horizontal;
-webkit-box-direction: normal;
-ms-flex-direction: row;
flex-direction: row;
-webkit-box-align: start;
-ms-flex-align: start;
align-items: flex-start;
-webkit-box-pack: justify;
-ms-flex-pack: justify;
justify-content: space-between
}
}
.process-timeline .pt-action-bar-button {
position: relative;
-webkit-box-align: center;
-ms-flex-align: center;
align-items: center;
background: none;
border: 0;
display: -webkit-box;
display: -ms-flexbox;
display: flex;
-webkit-box-orient: vertical;
-webkit-box-direction: normal;
-ms-flex-direction: column;
flex-direction: column;
margin: 0;
outline: none;
padding: 0;
width: 170px;
cursor: pointer
}
.process-timeline .pt-action-bar-button__background-number {
top: 0;
left: 50%;
position: absolute;
color: #ebebeb;
font-family: CamphorBold;
font-weight: 800;
font-size: 100px;
line-height: 1em;
-webkit-transition: top .4s ease;
transition: top .4s ease;
opacity: .3;
-webkit-transform: translateX(-50%);
transform: translateX(-50%)
}
.process-timeline .pt-action-bar-button-icon {
width: 114px;
height: 114px;
position: relative;
margin: 0 auto
}
.process-timeline .pt-action-bar-button-icon__inner-ring-1 {
width: 114px;
height: 114px;
top: 0;
left: 0;
position: absolute;
border: 1px solid #ebebeb;
border-radius: 100px;
opacity: .2;
-webkit-transform: scale(0);
transform: scale(0);
-webkit-transition: -webkit-transform .4s ease;
transition: -webkit-transform .4s ease;
transition: transform .4s ease;
transition: transform .4s ease, -webkit-transform .4s ease
}
.process-timeline .pt-action-bar-button-icon__inner-ring-2 {
width: 84px;
height: 84px;
left: 15px;
position: absolute;
top: 15px;
border: 1px solid #ebebeb;
border-radius: 100px;
opacity: .5;
-webkit-transform: scale(0);
transform: scale(0);
-webkit-transition: -webkit-transform .4s ease;
transition: -webkit-transform .4s ease;
transition: transform .4s ease;
transition: transform .4s ease, -webkit-transform .4s ease
}
.process-timeline .pt-action-bar-button-icon__inner-ring-3 {
width: 54px;
height: 54px;
left: 30px;
position: absolute;
top: 30px;
border: 1px solid #ebebeb;
border-radius: 100px;
opacity: .8;
-webkit-transform: scale(0);
transform: scale(0);
-webkit-transition: -webkit-transform .4s ease;
transition: -webkit-transform .4s ease;
transition: transform .4s ease;
transition: transform .4s ease, -webkit-transform .4s ease
}
.process-timeline .pt-action-bar-button-icon__inner-ring-4 {
-webkit-box-shadow: 0 4px 8px 0 rgba(0, 205, 172, 0.4);
box-shadow: 0 4px 8px 0 rgba(0, 205, 172, 0.4);
opacity: 0;
-webkit-transition: opacity .4s ease;
transition: opacity .4s ease
}
.process-timeline .pt-action-bar-button-icon__inner-ring-4,
.process-timeline .pt-action-bar-button-icon__inner-ring-5 {
width: 26px;
height: 26px;
left: 44px;
position: absolute;
top: 44px;
background-color: #00cdac;
border: 6px solid #00cdac;
border-radius: 100px
}
.process-timeline .pt-action-bar-button-icon__inner-ring-5 {
-webkit-transform: scale(0.5);
transform: scale(0.5);
-webkit-transition: -webkit-transform .4s ease;
transition: -webkit-transform .4s ease;
transition: transform .4s ease;
transition: transform .4s ease, -webkit-transform .4s ease
}
.process-timeline .pt-action-bar-button-icon__inner-ring-6 {
width: 14px;
height: 14px;
left: 50px;
position: absolute;
top: 50px;
background-color: #fff;
border-radius: 100px;
-webkit-transform: scale(0);
transform: scale(0);
-webkit-transition: -webkit-transform .2s ease;
transition: -webkit-transform .2s ease;
transition: transform .2s ease;
transition: transform .2s ease, -webkit-transform .2s ease
}
.process-timeline .pt-action-bar-button__title {
top: -20px;
position: relative;
font-family: CamphorRegular;
font-size: 18px;
line-height: 24px;
-webkit-transition: color .4s ease;
transition: color .4s ease;
color: #cfd7df
}
.process-timeline .pt-action-bar-button__text {
color: #6b7c93;
font-family: CamphorThin;
font-size: 14px;
line-height: 24px;
-webkit-transition: opacity .4s ease;
transition: opacity .4s ease
}
#media (min-width: 768px) {
.process-timeline .pt-action-bar-button--active .pt-action-bar-button__background-number {
top: -60px
}
.process-timeline .pt-action-bar-button--active .pt-action-bar-button-icon__inner-ring-1 {
-webkit-transform: scale(1);
transform: scale(1)
}
.process-timeline .pt-action-bar-button--active .pt-action-bar-button-icon__inner-ring-2 {
-webkit-transform: scale(1);
transform: scale(1)
}
.process-timeline .pt-action-bar-button--active .pt-action-bar-button-icon__inner-ring-3 {
-webkit-transform: scale(1);
transform: scale(1)
}
.process-timeline .pt-action-bar-button--active .pt-action-bar-button-icon__inner-ring-4 {
opacity: 1
}
.process-timeline .pt-action-bar-button--active .pt-action-bar-button-icon__inner-ring-5 {
-webkit-transform: scale(1);
transform: scale(1)
}
.process-timeline .pt-action-bar-button--active .pt-action-bar-button-icon__inner-ring-6 {
-webkit-transform: scale(1);
transform: scale(1)
}
.process-timeline .pt-action-bar-button--active .pt-action-bar-button__title {
color: #0e2b5c
}
.process-timeline .pt-action-bar-button--active .pt-action-bar-button__text {
opacity: 1
}
.process-timeline .pt-action-bar-button__text {
opacity: 0
}
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div class="process-timeline">
<div class="pt-timeline">
<div class="pt-timeline__backside-bar">
<div class="pt-timeline__frontside-bar" style="width: 0%;"></div>
</div>
</div>
<div class="pt-action-bar"><button class="pt-action-bar-button pt-action-bar-button--active">
<div class="pt-action-bar-button__background-number">
01
</div>
<div class="pt-action-bar-button-icon">
<div class="pt-action-bar-button-icon__inner-ring-1"></div>
<div class="pt-action-bar-button-icon__inner-ring-2"></div>
<div class="pt-action-bar-button-icon__inner-ring-3"></div>
<div class="pt-action-bar-button-icon__inner-ring-4"></div>
<div class="pt-action-bar-button-icon__inner-ring-5"></div>
<div class="pt-action-bar-button-icon__inner-ring-6"></div>
</div>
<div class="pt-action-bar-button__title">Fast development</div>
<div class="pt-action-bar-button__text">Ruby on Rails is perfect for
producing high quality code very quickly. If you want your project to
be ready for a deadline or hit the market fast, Ruby is the way to go.</div>
</button><button class="pt-action-bar-button">
<div class="pt-action-bar-button__background-number">
02
</div>
<div class="pt-action-bar-button-icon">
<div class="pt-action-bar-button-icon__inner-ring-1"></div>
<div class="pt-action-bar-button-icon__inner-ring-2"></div>
<div class="pt-action-bar-button-icon__inner-ring-3"></div>
<div class="pt-action-bar-button-icon__inner-ring-4"></div>
<div class="pt-action-bar-button-icon__inner-ring-5"></div>
<div class="pt-action-bar-button-icon__inner-ring-6"></div>
</div>
<div class="pt-action-bar-button__title">Fast prototyping</div>
<div class="pt-action-bar-button__text">Developing a software project from
scratch can be a long process, but RoR allows for creating MVPs quickly
thanks to dozens of ready-made libraries.</div>
</button><button class="pt-action-bar-button">
<div class="pt-action-bar-button__background-number">
03
</div>
<div class="pt-action-bar-button-icon">
<div class="pt-action-bar-button-icon__inner-ring-1"></div>
<div class="pt-action-bar-button-icon__inner-ring-2"></div>
<div class="pt-action-bar-button-icon__inner-ring-3"></div>
<div class="pt-action-bar-button-icon__inner-ring-4"></div>
<div class="pt-action-bar-button-icon__inner-ring-5"></div>
<div class="pt-action-bar-button-icon__inner-ring-6"></div>
</div>
<div class="pt-action-bar-button__title">Libraries for every occasion</div>
<div class="pt-action-bar-button__text">The Ruby community has created a
rich repository of libraries, called gems. Gems are ready-made
solutions and make development much easier and faster.</div>
</button><button class="pt-action-bar-button">
<div class="pt-action-bar-button__background-number">
04
</div>
<div class="pt-action-bar-button-icon">
<div class="pt-action-bar-button-icon__inner-ring-1"></div>
<div class="pt-action-bar-button-icon__inner-ring-2"></div>
<div class="pt-action-bar-button-icon__inner-ring-3"></div>
<div class="pt-action-bar-button-icon__inner-ring-4"></div>
<div class="pt-action-bar-button-icon__inner-ring-5"></div>
<div class="pt-action-bar-button-icon__inner-ring-6"></div>
</div>
<div class="pt-action-bar-button__title">Highest standard of web
development</div>
<div class="pt-action-bar-button__text">RoR has been battle-tested by many
developers in commercial projects. At Netguru, we can deliver
high-quality large-scale projects successfully.</div>
</button></div>
</div>
Now here's what I want:
When ".pt-action-bar-button--active" is added to "pt-action-bar-button" the width of ".pt-timeline__frontside-bar" should get increased/ decreased by 33%.
So the line also gets the green color.
I am attaching a screenshot so that you can understand what I want:
Something like this perhaps? JSFiddle: http://jsfiddle.net/s7xvpa23/1/
$('.pt-action-bar > .pt-action-bar-button').click(function () {
$(this).toggleClass('pt-action-bar-button--active').siblings().removeClass('pt-action-bar-button--active');
let buttonsArr = Array.from($('.pt-action-bar').children('button'));
buttonsArr.forEach((button, index) => {
if(button.className.indexOf('active') !== -1){
if(index === 0){
$('.pt-timeline__frontside-bar').css('width', '0%');
}
else if(index === 1){
$('.pt-timeline__frontside-bar').css('width', '33%');
}
else if(index === 2){
$('.pt-timeline__frontside-bar').css('width', '66%');
}
else if(index === 3){
$('.pt-timeline__frontside-bar').css('width', '100%');
}
}
});
});
I implemented this Vertical Fixed Navigation from Codyhouse into my site and everything works fine. The problem is with the fixed main-nav I have on top of the page (i.e. two navs in total, one on top and one vertical).
I would like to make both navigations behave the same, i.e. smooth scrolling and toggling class depending on scroll position, with a specific addClass for each nav.
I tried to select the links elements from both navs this way:
var navigationItems = $('#cd-vertical-nav a', '#main-nav a')
but it didn't work. As a matter of fact, in the snippet below the JQuery isn't working too. Dunno why :) But in my site the vertical nav works fine.
I am still a noob coder and new at StackOverflow. I would really appreciate any help!
jQuery(document).ready(function($) {
var contentSections = $('.cd-section'),
navigationItems = $('#cd-vertical-nav a');
updateNavigation();
$(window).on('scroll', function() {
updateNavigation();
});
//smooth scroll to the section
navigationItems.on('click', function(event) {
event.preventDefault();
smoothScroll($(this.hash));
});
//smooth scroll to second section
$('.arrow-down').on('click', function(event) {
event.preventDefault();
smoothScroll($(this.hash));
});
//open-close navigation on touch devices
$('.touch .cd-nav-trigger').on('click', function() {
$('.touch #cd-vertical-nav').toggleClass('open');
});
//close navigation on touch devices when selectin an elemnt from the list
$('.touch #cd-vertical-nav a').on('click', function() {
$('.touch #cd-vertical-nav').removeClass('open');
});
function updateNavigation() {
contentSections.each(function() {
$this = $(this);
var activeSection = $('#cd-vertical-nav a[href="#' + $this.attr('id') + '"]').data('number') - 1;
if (($this.offset().top - $(window).height() / 2 < $(window).scrollTop()) && ($this.offset().top + $this.height() - $(window).height() / 2 > $(window).scrollTop())) {
navigationItems.eq(activeSection).addClass('is-selected');
} else {
navigationItems.eq(activeSection).removeClass('is-selected');
}
});
}
function smoothScroll(target) {
$('body,html').animate({
'scrollTop': target.offset().top - 120
},
1500, 'easeOutExpo'
);
}
});
.main-header-container {
position: fixed;
width: 100%;
top: 0;
left: 0;
z-index: 9999;
}
header {
background: DarkGray;
}
a {
text-decoration: none;
color: white;
}
li {
list-style-type: none;
}
.menu {
line-height: 1.5;
margin: auto;
}
.menu,
.menu__list {
padding: 0;
}
.menu__list {
position: relative;
display: -webkit-flex;
display: -webkit-box;
display: -ms-flexbox;
display: flex;
-webkit-flex-wrap: wrap;
-ms-flex-wrap: wrap;
flex-wrap: wrap;
margin: 0;
list-style: none;
-webkit-box-pack: center;
-webkit-justify-content: center;
-ms-flex-pack: center;
justify-content: center;
}
.menu__item {
display: block;
margin: 1em 0;
}
.menu__link {
color: white;
text-transform: uppercase;
letter-spacing: 2.3px;
text-decoration: none;
font-size: 0.9em;
font-weight: 600;
display: block;
cursor: pointer;
-webkit-user-select: none;
-moz-user-select: none;
-ms-user-select: none;
user-select: none;
-webkit-touch-callout: none;
-khtml-user-select: none;
-webkit-tap-highlight-color: rgba(0, 0, 0, 0);
position: relative;
margin: 0 1em;
padding: 0.75em 0;
text-align: center;
-webkit-transition: color 0.3s;
transition: color 0.3s;
}
.menu__link:hover,
.menu__link:focus {
outline: none;
color: yellow;
}
.menu__item--current .menu__link {
color: yellow;
}
.menu__link::before {
content: '';
position: absolute;
left: 0;
bottom: 3px;
width: 100%;
height: 2px;
background: yellow;
-webkit-transform: scale3d(0, 1, 1);
transform: scale3d(0, 1, 1);
-webkit-transition: -webkit-transform 0.1s;
transition: -webkit-transform 0.1s;
transition: transform 0.1s;
transition: transform 0.1s, -webkit-transform 0.1s;
}
.menu__item--current .menu__link::before {
-webkit-transform: scale3d(1, 1, 1);
transform: scale3d(1, 1, 1);
-webkit-transition-timing-function: cubic-bezier(0.4, 0, 0.2, 1);
transition-timing-function: cubic-bezier(0.4, 0, 0.2, 1);
-webkit-transition-duration: 0.3s;
transition-duration: 0.3s;
}
/****Vertical Nav Styles****/
#cd-vertical-nav {
position: fixed;
right: 40px;
top: 50%;
bottom: auto;
z-index: 9999;
-webkit-transform: translate3d(0, -50%, 0);
transform: translate3d(0, -50%, 0);
}
#cd-vertical-nav li {
text-align: right;
}
#cd-vertical-nav a {
display: inline-block;
-webkit-backface-visibility: hidden;
backface-visibility: hidden;
}
#cd-vertical-nav a:after {
content: "";
display: table;
clear: both;
}
#cd-vertical-nav a span {
float: right;
display: inline-block;
-webkit-transform: scale(0.6);
-ms-transform: scale(0.6);
transform: scale(0.6);
}
#cd-vertical-nav a:hover span {
-webkit-transform: scale(1);
-ms-transform: scale(1);
transform: scale(1);
}
#cd-vertical-nav a:hover .cd-label {
opacity: 1;
}
#cd-vertical-nav a.is-selected .cd-dot {
background-color: white;
-webkit-transform: scale(1);
-ms-transform: scale(1);
transform: scale(1);
}
#cd-vertical-nav .cd-dot {
position: relative;
top: 8px;
height: 10px;
width: 10px;
border-radius: 50%;
background-color: white;
-webkit-transition: background-color 0.5s, -webkit-transform 0.5s;
transition: background-color 0.5s, -webkit-transform 0.5s;
transition: background-color 0.5s, transform 0.5s;
transition: background-color 0.5s, transform 0.5s, -webkit-transform 0.5s;
transition: background-color 0.5s, transform 0.5s, -webkit-transform 0.3s;
transition: transform 0.5s, background-color 0.5s;
transition: transform 0.5s, background-color 0.5s, -webkit-transform 0.5s;
transition: transform 0.5s, background-color 0.5s, -webkit-transform 0.3s;
-webkit-transform-origin: 50% 50%;
-ms-transform-origin: 50% 50%;
transform-origin: 50% 50%;
}
#cd-vertical-nav .cd-label {
position: relative;
margin-right: 10px;
padding: .4em .5em;
color: white;
font-size: 14px;
font-size: 0.875rem;
letter-spacing: 1.3px;
font-weight: 400;
-webkit-transition: opacity 0.3s, -webkit-transform 0.3s;
transition: opacity 0.3s, -webkit-transform 0.3s;
transition: transform 0.3s, opacity 0.3s;
transition: transform 0.3s, opacity 0.3s, -webkit-transform 0.3s;
opacity: 0;
-webkit-transform-origin: 100% 50%;
-ms-transform-origin: 100% 50%;
transform-origin: 100% 50%;
}
.cd-section {
height: 400px;
}
#landing-section {
background: DarkCyan;
}
#biography-section {
background: CornflowerBlue;
}
#recordings-section {
background: OrangeRed;
}
#gallery-section {
background: Coral;
}
#contact-section {
background: MediumPurple;
}
<link href="https://cdnjs.cloudflare.com/ajax/libs/jqueryui/1.11.4/jquery-ui.css" rel="stylesheet" />
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/jqueryui/1.11.4/jquery-ui.js"></script>
<div class="main-header-container">
<header>
<nav class="menu clearfix" id="main-nav">
<ul class="menu__list">
<li class="menu__item menu__item--current" id="news">
<a class="menu__link" href="#landing-section" data-number="1">News</a>
</li>
<li class="menu__item" id="biography">
<a class="menu__link" href="#biography-section" data-number="2">Biography</a>
</li>
<li class="menu__item" id="recordings">
<a class="menu__link" href="#recordings-section" data-number="3">Recordings</a>
</li>
<li class="menu__item" id="gallery">
<a class="menu__link" href="#gallery-section" data-number="4">Gallery</a>
</li>
<li class="menu__item" id="contact">
<a class="menu__link" href="#contact-section" data-number="5">Contact</a>
</li>
</ul>
</nav>
</header>
</div>
<nav id="cd-vertical-nav">
<ul>
<li id="vertical-nav1">
<a href="#landing-section" data-number="1">
<span class="cd-dot"></span>
<span class="cd-label">News</span>
</a>
</li>
<li id="vertical-nav2">
<a href="#biography-section" data-number="2">
<span class="cd-dot"></span>
<span class="cd-label">Biography</span>
</a>
</li>
<li id="vertical-nav3">
<a href="#recordings-section" data-number="3">
<span class="cd-dot"></span>
<span class="cd-label">Recordings</span>
</a>
</li>
<li id="vertical-nav4">
<a href="#gallery-section" data-number="4">
<span class="cd-dot"></span>
<span class="cd-label">Gallery</span>
</a>
</li>
<li id="vertical-nav5">
<a href="#contact-section" data-number="5">
<span class="cd-dot"></span>
<span class="cd-label">Contact</span>
</a>
</li>
</ul>
</nav>
<section id="landing-section" class="cd-section"></section>
<section id="biography-section" class="cd-section"></section>
<section id="recordings-section" class="cd-section"></section>
<section id="gallery-section" class="cd-section"></section>
<section id="contact-section" class="cd-section"></section>
To select multiple elements, you put them in a single selector string, separated by commas, not separate arguments to the jQuery() function.
var navigationItems = $('#cd-vertical-nav a, #main-nav a');
When you call jQuery with multiple arguments, the first argument is a selector, and the second argument is the context to search within, i.e.
$('#cd-vertical-nav a', '#main-nav a')
is equivalent to
$('#main-nav a').find('#cd-vertical-nav a')
Another way you can do this in a more general way is to use a class.
<nav class="menu clearfix fixed-nav" id="main-nav">
<nav class="fixed-nav" id="cd-vertical-nav">
Then you can use $('.fixed-nav a').
You need to use the mutliplse selector syntax
navigationItems = $('#cd-vertical-nav a, #main-nav a')
If you pass the second selector as a separate argument, then it will be considered as a context parameter
jQuery(document).ready(function($) {
var contentSections = $('.cd-section'),
navigationItems = $('#cd-vertical-nav a, #main-nav a');
updateNavigation();
$(window).on('scroll', function() {
updateNavigation();
});
//smooth scroll to the section
navigationItems.on('click', function(event) {
event.preventDefault();
smoothScroll($(this.hash));
});
//smooth scroll to second section
$('.arrow-down').on('click', function(event) {
event.preventDefault();
smoothScroll($(this.hash));
});
//open-close navigation on touch devices
$('.touch .cd-nav-trigger').on('click', function() {
$('.touch #cd-vertical-nav').toggleClass('open');
});
//close navigation on touch devices when selectin an elemnt from the list
$('.touch #cd-vertical-nav a').on('click', function() {
$('.touch #cd-vertical-nav').removeClass('open');
});
function updateNavigation() {
contentSections.each(function() {
$this = $(this);
var activeSection = $('#cd-vertical-nav a[href="#' + $this.attr('id') + '"]').data('number') - 1;
if (($this.offset().top - $(window).height() / 2 < $(window).scrollTop()) && ($this.offset().top + $this.height() - $(window).height() / 2 > $(window).scrollTop())) {
navigationItems.eq(activeSection).addClass('is-selected');
} else {
navigationItems.eq(activeSection).removeClass('is-selected');
}
});
}
function smoothScroll(target) {
console.log('x', target.get())
$('body,html').animate({
'scrollTop': target.offset().top - 120
},
1500, 'easeOutExpo'
);
}
});
.main-header-container {
position: fixed;
width: 100%;
top: 0;
left: 0;
z-index: 9999;
}
header {
background: DarkGray;
}
a {
text-decoration: none;
color: white;
}
li {
list-style-type: none;
}
.menu {
line-height: 1.5;
margin: auto;
}
.menu,
.menu__list {
padding: 0;
}
.menu__list {
position: relative;
display: -webkit-flex;
display: -webkit-box;
display: -ms-flexbox;
display: flex;
-webkit-flex-wrap: wrap;
-ms-flex-wrap: wrap;
flex-wrap: wrap;
margin: 0;
list-style: none;
-webkit-box-pack: center;
-webkit-justify-content: center;
-ms-flex-pack: center;
justify-content: center;
}
.menu__item {
display: block;
margin: 1em 0;
}
.menu__link {
color: white;
text-transform: uppercase;
letter-spacing: 2.3px;
text-decoration: none;
font-size: 0.9em;
font-weight: 600;
display: block;
cursor: pointer;
-webkit-user-select: none;
-moz-user-select: none;
-ms-user-select: none;
user-select: none;
-webkit-touch-callout: none;
-khtml-user-select: none;
-webkit-tap-highlight-color: rgba(0, 0, 0, 0);
position: relative;
margin: 0 1em;
padding: 0.75em 0;
text-align: center;
-webkit-transition: color 0.3s;
transition: color 0.3s;
}
.menu__link:hover,
.menu__link:focus {
outline: none;
color: yellow;
}
.menu__item--current .menu__link {
color: yellow;
}
.menu__link::before {
content: '';
position: absolute;
left: 0;
bottom: 3px;
width: 100%;
height: 2px;
background: yellow;
-webkit-transform: scale3d(0, 1, 1);
transform: scale3d(0, 1, 1);
-webkit-transition: -webkit-transform 0.1s;
transition: -webkit-transform 0.1s;
transition: transform 0.1s;
transition: transform 0.1s, -webkit-transform 0.1s;
}
.menu__item--current .menu__link::before {
-webkit-transform: scale3d(1, 1, 1);
transform: scale3d(1, 1, 1);
-webkit-transition-timing-function: cubic-bezier(0.4, 0, 0.2, 1);
transition-timing-function: cubic-bezier(0.4, 0, 0.2, 1);
-webkit-transition-duration: 0.3s;
transition-duration: 0.3s;
}
/****Vertical Nav Styles****/
#cd-vertical-nav {
position: fixed;
right: 40px;
top: 50%;
bottom: auto;
z-index: 9999;
-webkit-transform: translate3d(0, -50%, 0);
transform: translate3d(0, -50%, 0);
}
#cd-vertical-nav li {
text-align: right;
}
#cd-vertical-nav a {
display: inline-block;
-webkit-backface-visibility: hidden;
backface-visibility: hidden;
}
#cd-vertical-nav a:after {
content: "";
display: table;
clear: both;
}
#cd-vertical-nav a span {
float: right;
display: inline-block;
-webkit-transform: scale(0.6);
-ms-transform: scale(0.6);
transform: scale(0.6);
}
#cd-vertical-nav a:hover span {
-webkit-transform: scale(1);
-ms-transform: scale(1);
transform: scale(1);
}
#cd-vertical-nav a:hover .cd-label {
opacity: 1;
}
#cd-vertical-nav a.is-selected .cd-dot {
background-color: white;
-webkit-transform: scale(1);
-ms-transform: scale(1);
transform: scale(1);
}
#cd-vertical-nav .cd-dot {
position: relative;
top: 8px;
height: 10px;
width: 10px;
border-radius: 50%;
background-color: white;
-webkit-transition: background-color 0.5s, -webkit-transform 0.5s;
transition: background-color 0.5s, -webkit-transform 0.5s;
transition: background-color 0.5s, transform 0.5s;
transition: background-color 0.5s, transform 0.5s, -webkit-transform 0.5s;
transition: background-color 0.5s, transform 0.5s, -webkit-transform 0.3s;
transition: transform 0.5s, background-color 0.5s;
transition: transform 0.5s, background-color 0.5s, -webkit-transform 0.5s;
transition: transform 0.5s, background-color 0.5s, -webkit-transform 0.3s;
-webkit-transform-origin: 50% 50%;
-ms-transform-origin: 50% 50%;
transform-origin: 50% 50%;
}
#cd-vertical-nav .cd-label {
position: relative;
margin-right: 10px;
padding: .4em .5em;
color: white;
font-size: 14px;
font-size: 0.875rem;
letter-spacing: 1.3px;
font-weight: 400;
-webkit-transition: opacity 0.3s, -webkit-transform 0.3s;
transition: opacity 0.3s, -webkit-transform 0.3s;
transition: transform 0.3s, opacity 0.3s;
transition: transform 0.3s, opacity 0.3s, -webkit-transform 0.3s;
opacity: 0;
-webkit-transform-origin: 100% 50%;
-ms-transform-origin: 100% 50%;
transform-origin: 100% 50%;
}
.cd-section {
height: 400px;
}
#landing-section {
background: DarkCyan;
}
#biography-section {
background: CornflowerBlue;
}
#recordings-section {
background: OrangeRed;
}
#gallery-section {
background: Coral;
}
#contact-section {
background: MediumPurple;
}
<link href="https://cdnjs.cloudflare.com/ajax/libs/jqueryui/1.11.4/jquery-ui.css" rel="stylesheet" />
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/jqueryui/1.11.4/jquery-ui.js"></script>
<div class="main-header-container">
<header>
<nav class="menu clearfix" id="main-nav">
<ul class="menu__list">
<li class="menu__item menu__item--current" id="news">
<a class="menu__link" href="#landing-section" data-number="1">News</a>
</li>
<li class="menu__item" id="biography">
<a class="menu__link" href="#biography-section" data-number="2">Biography</a>
</li>
<li class="menu__item" id="recordings">
<a class="menu__link" href="#recordings-section" data-number="3">Recordings</a>
</li>
<li class="menu__item" id="gallery">
<a class="menu__link" href="#gallery-section" data-number="4">Gallery</a>
</li>
<li class="menu__item" id="contact">
<a class="menu__link" href="#contact-section" data-number="5">Contact</a>
</li>
</ul>
</nav>
</header>
</div>
<nav id="cd-vertical-nav">
<ul>
<li id="vertical-nav1">
<a href="#landing-section" data-number="1">
<span class="cd-dot"></span>
<span class="cd-label">News</span>
</a>
</li>
<li id="vertical-nav2">
<a href="#biography-section" data-number="2">
<span class="cd-dot"></span>
<span class="cd-label">Biography</span>
</a>
</li>
<li id="vertical-nav3">
<a href="#recordings-section" data-number="3">
<span class="cd-dot"></span>
<span class="cd-label">Recordings</span>
</a>
</li>
<li id="vertical-nav4">
<a href="#gallery-section" data-number="4">
<span class="cd-dot"></span>
<span class="cd-label">Gallery</span>
</a>
</li>
<li id="vertical-nav5">
<a href="#contact-section" data-number="5">
<span class="cd-dot"></span>
<span class="cd-label">Contact</span>
</a>
</li>
</ul>
</nav>
<section id="landing-section" class="cd-section"></section>
<section id="biography-section" class="cd-section"></section>
<section id="recordings-section" class="cd-section"></section>
<section id="gallery-section" class="cd-section"></section>
<section id="contact-section" class="cd-section"></section>
Try this one
var navigationItems = $('#cd-vertical-nav>a', '#main-nav>a');
I tried to change the jQuery (see the updated snippet) in order to add a class to the active link of each nav, based on scroll position.
There must be a problem here (also somewhere else?):
updateMainNavigation()
updateVerticalNavigation()
Here they are comma separated but I also tried to write two complete different functions, even if the behaviour is the same. I can't figure out what I should do to make it work.
I am the same noob as yesterday and any help ist most welcome!
jQuery(document).ready(function($) {
var contentSections = $('.cd-section'),
navigationItems = $('.fixed-nav a');
updateMainNavigation(), updateVerticalNavigation();
$(window).on('scroll', function() {
updateMainNavigation(), updateVerticalNavigation();
});
//smooth scroll to the section
navigationItems.on('click', function(event) {
event.preventDefault();
smoothScroll($(this.hash));
});
//smooth scroll to second section
$('.arrow-down').on('click', function(event) {
event.preventDefault();
smoothScroll($(this.hash));
});
function updateMainNavigation() {
contentSections.each(function() {
$this = $(this);
var activeSection = $('#main-nav a[href="#' + $this.attr('id') + '"]').data('number') - 1;
if (($this.offset().top - $(window).height() / 2 < $(window).scrollTop()) && ($this.offset().top + $this.height() - $(window).height() / 2 > $(window).scrollTop())) {
navigationItems.eq(activeSection).addClass('menu__item--current');
} else {
navigationItems.eq(activeSection).removeClass('menu__item--current');
}
});
}
function updateVerticalNavigation() {
contentSections.each(function() {
$this = $(this);
var activeSection = $('#cd-vertical-nav a[href="#' + $this.attr('id') + '"]').data('number') - 1;
if (($this.offset().top - $(window).height() / 2 < $(window).scrollTop()) && ($this.offset().top + $this.height() - $(window).height() / 2 > $(window).scrollTop())) {
navigationItems.eq(activeSection).addClass('is-selected');
} else {
navigationItems.eq(activeSection).removeClass('is-selected');
}
});
}
function smoothScroll(target) {
$('body,html').animate({
'scrollTop': target.offset().top - 120
},
1500, 'easeOutExpo'
);
}
});
.main-header-container {
position: fixed;
width: 100%;
top: 0;
left: 0;
z-index: 9999;
}
header {
background: DarkGray;
}
a {
text-decoration: none;
color: white;
}
li {
list-style-type: none;
}
.menu {
line-height: 1.5;
margin: auto;
}
.menu,
.menu__list {
padding: 0;
}
.menu__list {
position: relative;
display: -webkit-flex;
display: -webkit-box;
display: -ms-flexbox;
display: flex;
-webkit-flex-wrap: wrap;
-ms-flex-wrap: wrap;
flex-wrap: wrap;
margin: 0;
list-style: none;
-webkit-box-pack: center;
-webkit-justify-content: center;
-ms-flex-pack: center;
justify-content: center;
}
.menu__item {
display: block;
margin: 1em 0;
}
.menu__link {
color: white;
text-transform: uppercase;
letter-spacing: 2.3px;
text-decoration: none;
font-size: 0.9em;
font-weight: 600;
display: block;
cursor: pointer;
-webkit-user-select: none;
-moz-user-select: none;
-ms-user-select: none;
user-select: none;
-webkit-touch-callout: none;
-khtml-user-select: none;
-webkit-tap-highlight-color: rgba(0, 0, 0, 0);
position: relative;
margin: 0 1em;
padding: 0.75em 0;
text-align: center;
-webkit-transition: color 0.3s;
transition: color 0.3s;
}
.menu__link:hover,
.menu__link:focus {
outline: none;
color: yellow;
}
.menu__item--current .menu__link {
color: yellow;
}
.menu__link::before {
content: '';
position: absolute;
left: 0;
bottom: 3px;
width: 100%;
height: 2px;
background: yellow;
-webkit-transform: scale3d(0, 1, 1);
transform: scale3d(0, 1, 1);
-webkit-transition: -webkit-transform 0.1s;
transition: -webkit-transform 0.1s;
transition: transform 0.1s;
transition: transform 0.1s, -webkit-transform 0.1s;
}
.menu__item--current .menu__link::before {
-webkit-transform: scale3d(1, 1, 1);
transform: scale3d(1, 1, 1);
-webkit-transition-timing-function: cubic-bezier(0.4, 0, 0.2, 1);
transition-timing-function: cubic-bezier(0.4, 0, 0.2, 1);
-webkit-transition-duration: 0.3s;
transition-duration: 0.3s;
}
/****Vertical Nav Styles****/
#cd-vertical-nav {
position: fixed;
right: 40px;
top: 50%;
bottom: auto;
z-index: 9999;
-webkit-transform: translate3d(0, -50%, 0);
transform: translate3d(0, -50%, 0);
}
#cd-vertical-nav li {
text-align: right;
}
#cd-vertical-nav a {
display: inline-block;
-webkit-backface-visibility: hidden;
backface-visibility: hidden;
}
#cd-vertical-nav a:after {
content: "";
display: table;
clear: both;
}
#cd-vertical-nav a span {
float: right;
display: inline-block;
-webkit-transform: scale(0.6);
-ms-transform: scale(0.6);
transform: scale(0.6);
}
#cd-vertical-nav a:hover span {
-webkit-transform: scale(1);
-ms-transform: scale(1);
transform: scale(1);
}
#cd-vertical-nav a:hover .cd-label {
opacity: 1;
}
#cd-vertical-nav a.is-selected .cd-dot {
background-color: white;
-webkit-transform: scale(1);
-ms-transform: scale(1);
transform: scale(1);
}
#cd-vertical-nav .cd-dot {
position: relative;
top: 8px;
height: 10px;
width: 10px;
border-radius: 50%;
background-color: white;
-webkit-transition: background-color 0.5s, -webkit-transform 0.5s;
transition: background-color 0.5s, -webkit-transform 0.5s;
transition: background-color 0.5s, transform 0.5s;
transition: background-color 0.5s, transform 0.5s, -webkit-transform 0.5s;
transition: background-color 0.5s, transform 0.5s, -webkit-transform 0.3s;
transition: transform 0.5s, background-color 0.5s;
transition: transform 0.5s, background-color 0.5s, -webkit-transform 0.5s;
transition: transform 0.5s, background-color 0.5s, -webkit-transform 0.3s;
-webkit-transform-origin: 50% 50%;
-ms-transform-origin: 50% 50%;
transform-origin: 50% 50%;
}
#cd-vertical-nav .cd-label {
position: relative;
margin-right: 10px;
padding: .4em .5em;
color: white;
font-size: 14px;
font-size: 0.875rem;
letter-spacing: 1.3px;
font-weight: 400;
-webkit-transition: opacity 0.3s, -webkit-transform 0.3s;
transition: opacity 0.3s, -webkit-transform 0.3s;
transition: transform 0.3s, opacity 0.3s;
transition: transform 0.3s, opacity 0.3s, -webkit-transform 0.3s;
opacity: 0;
-webkit-transform-origin: 100% 50%;
-ms-transform-origin: 100% 50%;
transform-origin: 100% 50%;
}
.cd-section {
height: 400px;
}
#landing-section {
background: DarkCyan;
}
#biography-section {
background: CornflowerBlue;
}
#recordings-section {
background: OrangeRed;
}
#gallery-section {
background: Coral;
}
#contact-section {
background: MediumPurple;
}
<link href="https://cdnjs.cloudflare.com/ajax/libs/jqueryui/1.11.4/jquery-ui.css" rel="stylesheet" />
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/jqueryui/1.11.4/jquery-ui.js"></script>
<div class="main-header-container">
<header>
<nav class="menu clearfix" id="main-nav">
<ul class="menu__list">
<li class="menu__item menu__item--current" id="news">
<a class="menu__link" href="#landing-section" data-number="1">News</a>
</li>
<li class="menu__item" id="biography">
<a class="menu__link" href="#biography-section" data-number="2">Biography</a>
</li>
<li class="menu__item" id="recordings">
<a class="menu__link" href="#recordings-section" data-number="3">Recordings</a>
</li>
<li class="menu__item" id="gallery">
<a class="menu__link" href="#gallery-section" data-number="4">Gallery</a>
</li>
<li class="menu__item" id="contact">
<a class="menu__link" href="#contact-section" data-number="5">Contact</a>
</li>
</ul>
</nav>
</header>
</div>
<nav id="cd-vertical-nav">
<ul>
<li id="vertical-nav1">
<a href="#landing-section" data-number="1">
<span class="cd-dot"></span>
<span class="cd-label">News</span>
</a>
</li>
<li id="vertical-nav2">
<a href="#biography-section" data-number="2">
<span class="cd-dot"></span>
<span class="cd-label">Biography</span>
</a>
</li>
<li id="vertical-nav3">
<a href="#recordings-section" data-number="3">
<span class="cd-dot"></span>
<span class="cd-label">Recordings</span>
</a>
</li>
<li id="vertical-nav4">
<a href="#gallery-section" data-number="4">
<span class="cd-dot"></span>
<span class="cd-label">Gallery</span>
</a>
</li>
<li id="vertical-nav5">
<a href="#contact-section" data-number="5">
<span class="cd-dot"></span>
<span class="cd-label">Contact</span>
</a>
</li>
</ul>
</nav>
<section id="landing-section" class="cd-section"></section>
<section id="biography-section" class="cd-section"></section>
<section id="recordings-section" class="cd-section"></section>
<section id="gallery-section" class="cd-section"></section>
<section id="contact-section" class="cd-section"></section>
Hi everyone i have one problem with ajax hover. I am trying to make a userHoverCard like tumblr. But the hover animation not working when i use it with ajax.
This is working DEMO without ajax only css. In this demo you can see when you hover image then .p-tooltip will open with animation effect.
But if you click this DEMO from my test page then you can see when you hover an image then .p-tooltip will not open with animation effect.
HTML
<div class="p-tooltip"></div>
<div class="summary" data-id="25">
</div>
<div class="summary" data-id="20">
</div>
<div class="summary" data-id="25">
</div>
This is my ajax code:
$(document).ready(function() {
function showProfileTooltip(e, id){
e.append($('.p-tooltip').css({
'top':'20',
'left':'80'
}).show());
//send id & get info from get_profile.php
$.ajax({
url: 'get_profile.php?uid='+id,
beforeSend: function(){
$('.p-tooltip').html('Loading..');
},
success: function(html){
$('.p-tooltip').html(html);
}
});
}
function hideProfileTooltip(){
$('.p-tooltip').hide().fadeIn('fast');
}
$('.summary a').hover(function(e){
var id = $(this).attr('data-id');
showProfileTooltip($(this), id);
}, function(){
setTimeout(function(){
hideProfileTooltip();
},2000);
});
});
And here is CSS code:
.summary {
margin: 50px auto 0;
width: 50px;
height: 50px;
position: relative;
}
.profile-ava {
width: 50px;
height: 50px;
background-image: url(http://gravatar.com/avatar/3913c4e14034c0a7f28db2c632290c21?s=80);
border-radius: 3px;
background-size: 50px 50px;
display: block;
}
.summary a:hover:before {
content: '';
position: absolute;
display: block;
bottom: -10px;
left: 0;
height: 10px;
width: 100%;
z-index: 2;
}
.p-tooltip {
position: absolute;
margin-top: 10px;
top: 100%;
left: 50%;
margin-left: -140px;
width: 280px;
max-height: 120px;
border-radius: 5px;
overflow: hidden;
background-color: #F0F0F0;
visibility: hidden;
opacity: 0;
transition: all 0.5s ease;
}
.profile-header {
height: 120px;
background-image: url(https://pbs.twimg.com/profile_banners/571038694/1395748220/1500x500);
background-size: auto 120px;
background-position: 50%;
}
.profile-navigation {
position: absolute;
top: 0;
left: 0;
padding: 10px;
width: 100%;
box-sizing: border-box;
}
.profile-nick {
color: #fff;
margin: 0;
padding: 0.4em 0;
font-size: 0.8em;
font-weight: bold;
}
.profile-action {
float: right;
background-color: #eee;
padding: 0.4em;
border-radius: 2px;
color: inherit;
text-decoration: none;
font-size: 0.8em;
font-weight: bold;
}
.p-tooltip .profile-ava {
margin: -40px auto 0;
width: 80px;
height: 80px;
background-size: 80px;
border: 3px solid #F0F0F0;
border-radius: 5px;
}
.profile-info {
text-align: center;
padding: 10px;
opacity: 0;
}
.profile-title {font-size: 1.6em; margin: 0;}
.profile-description {
margin: 0;
font-size: 0.8em;
}
.profile-items {margin: 0px; padding: 10px;}
.profile-items:after {
content: '';
display: table;
clear: both;
}
.profile-items li {
width: 80px;
height: 80px;
background-size: cover;
background-position: center;
float: left;
display: block;
border-radius: 3px;
}
.profile-items li:not(:first-child) {margin-left: 10px;}
.profile-items li:nth-child(1) {
background-image: url(https://o.twimg.com/1/proxy.jpg?t=FQQVBBgwaHR0cHM6Ly9pLnl0aW1nLmNvbS92aS9CM3lna2lYRXVyWS9ocWRlZmF1bHQuanBnFAIWABIA&s=z1wybbbNHF0pyLthl3xhxVBNjbYlAEWEzPd-dUtrWOY);
}
.profile-items li:nth-child(2) {
background-image: url(https://pbs.twimg.com/media/B7pkXfgCIAAwoY0.jpg:thumb);
}
.profile-items li:nth-child(3) {
background-image: url(https://pbs.twimg.com/media/B7A3NHjIIAIt6eg.png:large);
}
.profile-header {
-webkit-transform: translate(0, -50px);
-moz-transform: translate(0, -50px);
transform: translate(0, -50px);
-webkit-transition: all 0.2s ease-out;
-moz-transition: all 0.2s ease-out;
transition: all 0.2s ease-out;
-webkit-transition-delay: 0.1s;
-moz-transition-delay: 0.1s;
transition-delay: 0.1s;
opacity: 0;
}
.profile-info {
-webkit-transform: translate(0, 50px);
-moz-transform: translate(0, 50px);
transform: translate(0, 50px);
-webkit-transition: all 0.3s ease-out;
-moz-transition: all 0.3s ease-out;
transition: all 0.3s ease-out;
-webkit-transition-delay: 0.1s;
-moz-transition-delay: 0.1s;
transition-delay: 0.1s;
}
.p-tooltip .profile-ava {
-webkit-transform: scale(0.5) translate(0, -10px);
-moz-transform: scale(0.5) translate(0, -10px);
transform: scale(0.5) translate(0, -10px);
-webkit-transition: all 0.5s ease-out;
-moz-transition: all 0.5s ease-out;
transition: all 0.5s ease-out;
-webkit-transition-delay: 0.1s;
-moz-transition-delay: 0.1s;
transition-delay: 0.1s;
opacity: 0;
}
.profile-items li {
-webkit-transform: translate(0, 50px);
-moz-transform: translate(0, 50px);
transform: translate(0, 50px);
-webkit-transition: all 0.3s ease-out;
-moz-transition: all 0.3s ease-out;
transition: all 0.3s ease-out;
-webkit-transition-delay: 0.3s;
-moz-transition-delay: 0.3s;
transition-delay: 0.3s;
opacity: 0;
}
.profile-items li:nth-child(2) {
-webkit-transition-delay: 0.35s;
-moz-transition-delay: 0.35s;
transition-delay: 0.35s;
}
.profile-items li:nth-child(3) {
-webkit-transition-delay: 0.4s;
-moz-transition-delay: 0.4s;
transition-delay: 0.4s;
}
.summary:hover .p-tooltip {
visibility: visible;
opacity: 1;
max-height: 600px;
}
.summary:hover .profile-header,
.summary:hover .profile-info,
.summary:hover .p-tooltip .profile-ava,
.summary:hover .profile-items li {
-webkit-transform: translate(0,0) scale(1);
-moz-transform: translate(0,0) scale(1);
transform: translate(0,0) scale(1);
opacity: 1;
}
Anyone can help me please!
Essentially, I've created a pretty clever workaround. It is a mask that covers the image (invisible) until the html is loaded, then the hover css takes place after the z-index is lowered. The hover javascript is on the container.
FIDDLE
.summary {
margin: -50px auto 0;
width: 50px;
height: 50px;
position: relative;
z-index: 0;
}
.summary-mask {
margin: 50px auto 0;
width: 50px;
height: 50px;
position: relative;
z-index: 1;
}
.loaded .summary-mask {
z-index: -1;
}
HTML
<div class="the-container">
<div class="summary-mask"></div>
<div class="summary" data-id="100">
<div class="user-container"></div>
</div>
</div>
JS
var response = '<div class="p-tooltip"> <div class="profile-header"></div> <div class="profile-navigation"> Follow <p class="profile-nick"> Page Name </p> </div> <div class="profile-ava"></div> <div class="profile-info"> <h1 class="profile-title">Username</h1> <p class="profile-description">Lorem Ipsum is simply dummy text of the printing and typesetting industry. Lorem Ipsum has been the industry\'s standard dummy ..</p> </div> <ul class="profile-items"> <li></li> <li></li> <li></li> </ul> </div>';
$(document).ready(function () {
function showProfileTooltip(e, id) {
//send id & get info from get_profile.php
$.ajax({
url: '/echo/html/',
data: {
html: response,
delay: 0
},
method: 'post',
success: function (returnHtml) {
e.find('.user-container').html(returnHtml).promise().done(function () {
$('.the-container').addClass('loaded');
});
}
});
}
function hideProfileTooltip() {
$('.the-container').removeClass('loaded');
}
$('.the-container').hover(function (e) {
var id = $(this).find('.summary').attr('data-id');
showProfileTooltip($(this), id);
}, function () {
hideProfileTooltip();
});
});
When you are showing the card, it only contains the loading message. When the content arrives and you put it in the card, that isn't a CSS change, so the transition isn't activated.
If you wait until the content has arrives to show the card, there is something to animate.