Navbar disappears after scrollIntoView() use on mobile view - javascript

Problem: NavBar disappears after scrollIntoView() used on mobile view.
Related JS
function disableScroll() {
window.addEventListener('DOMMouseScroll', preventDefault, false); // older FF
window.addEventListener(wheelEvent, preventDefault, wheelOpt); // modern desktop
window.addEventListener('touchmove', preventDefault, wheelOpt); // mobile
window.addEventListener('keydown', preventDefaultForScrollKeys, false);
}
function enableScroll() {
window.removeEventListener('DOMMouseScroll', preventDefault, false);
window.removeEventListener(wheelEvent, preventDefault, wheelOpt);
window.removeEventListener('touchmove', preventDefault, wheelOpt);
window.removeEventListener('keydown', preventDefaultForScrollKeys, false);
}
function scroll_to_chapters() {
const chapters = document.getElementsByClassName("chapter_list")[0];
if (nav.classList.contains("nav-active")) {
navLinks.forEach((link) => {
if (link.style.animation) {
link.style.animation = '';
}
});
enableScroll();
burger.classList.toggle('toggle');
nav.classList.toggle('nav-active');
}
chapters.scrollIntoView({ block: 'start', behavior: 'smooth' })
}
const navSlide = ()=> {
burger.addEventListener('click', ()=> {
//Toggle NavBar
nav.classList.toggle('nav-active');
//Animate Links
navLinks.forEach((link, index)=> {
if (link.style.animation) {
enableScroll();
link.style.animation = '';
}
else {
disableScroll();
link.style.animation = `navLinkFade 0.5s ease forwards ${index / 7 + 0.5}s`;
}
});
burger.classList.toggle('toggle');
});
}
I'm not quite sure but there might be a problem with the disabling and enabling scrolling. I didn't want mobile users to be able to scroll while the navbar menus are opened.
Navbar HTML
<div class="wrapper">
<div class="fix">
<header>
<div class="container">
<nav>
<img src="{% static 'img/northernlogo.png' %}" class="logo" alt="logo">
<ul class="nav-links">
<li>Home</li>
<li>Chapters</li>
<li>About</li>
<li>Links</li>
</ul>
<div class="burger">
<div class="line1"></div>
<div class="line2"></div>
<div class="line3"></div>
</div>
</nav>
</div>
</header>
</div>
</div>
Related CSS
.container {
width: 100%;
margin: 0 0;
}
.container::after {
content: '';
display: grid;
clear: both;
}
.burger {
display: none;
margin-top: 20px;
cursor: pointer;
}
.burger div {
width: 25px;
height: 3px;
background: #EEEEEE;
margin: 5px;
transition: all 0.3s ease;
}
#media only screen and (max-width: 800px) {
.wrapper {
overflow: hidden;
position: relative;
}
.nav-links {
-webkit-box-shadow: inset 0 0.5em 1.5em -0.5em black;
position: absolute;
right: 0;
height: 100%;
top: 70px;
background-color: #3a345c;
z-index: 99;
display: flex;
flex-direction: column;
align-items: center;
width: 100%;
transform: translateX(100%);
transition: transform 0.5s ease-in;
}
.nav-links li {
opacity: 0;
padding-bottom: 50px;
padding-top: 50px;
}
.nav-links li a {
font-size: 20px;
font-weight: bold;
}
.burger {
display: block;
}
}
Picture of the Error
Before
After
How to Reproduce
Open the website on mobile view. Open the navbar from the home menu and click chapters. It'll take you to the chapters but now the navbar is gone.
Editor's note:
The accepted answer features a self-contained reproducible example.

This happens because .nav-links are position: absolute with:
a position: static (by default) parent .fix, and
a position: relative grandparent .wrapper.
In this case, scrollIntoView({block: 'start', ...}) scrolls .fix out of view of .wrapper before scrolling .wrapper itself.
{block: 'center', ...} does the same.
{block: 'end', ...} and {block: 'nearest', ...} don't.
You can't scroll .fix back into view because .wrapper has overflow: hidden.
Solution
Make .fix have position: relative and make .nav-links have height: 100vh.
.fix {
position: relative;
}
.nav-links {
height: 100vh;
}
Run this code snippet to reproduce the problem, and click on the toggle to try with answer:
const burger = document.querySelector('.burger');
const nav = document.querySelector('.nav-links');
const navLinks = document.querySelectorAll('.nav-links li');
// left: 37, up: 38, right: 39, down: 40,
// spacebar: 32, pageup: 33, pagedown: 34, end: 35, home: 36
var keys = {
37: 1,
38: 1,
39: 1,
40: 1
};
function preventDefault(e) {
e.preventDefault();
}
function preventDefaultForScrollKeys(e) {
if (keys[e.keyCode]) {
preventDefault(e);
return false;
}
}
// modern Chrome requires { passive: false } when adding event
var supportsPassive = false;
try {
window.addEventListener("test", null, Object.defineProperty({}, 'passive', {
get: function() {
supportsPassive = true;
}
}));
} catch (e) {}
var wheelOpt = supportsPassive ? {
passive: false
} : false;
var wheelEvent = 'onwheel' in document.createElement('div') ? 'wheel' : 'mousewheel';
// call this to Disable
function disableScroll() {
window.addEventListener('DOMMouseScroll', preventDefault, false); // older FF
window.addEventListener(wheelEvent, preventDefault, wheelOpt); // modern desktop
window.addEventListener('touchmove', preventDefault, wheelOpt); // mobile
window.addEventListener('keydown', preventDefaultForScrollKeys, false);
}
// call this to Enable
function enableScroll() {
window.removeEventListener('DOMMouseScroll', preventDefault, false);
window.removeEventListener(wheelEvent, preventDefault, wheelOpt);
window.removeEventListener('touchmove', preventDefault, wheelOpt);
window.removeEventListener('keydown', preventDefaultForScrollKeys, false);
}
function read_more_less(button) {
var x = $('#more');
$(button).find('i').remove();
if ($(button).text().trim() === 'Read more') {
$(button).html($('<i/>', {
class: 'fas fa-sort-down'
})).append(' Read less');
x.fadeIn();
} else {
$(button).html($('<i/>', {
class: 'fas fa-sort-up'
})).append(' Read more');
x.fadeOut();
}
}
function scroll_to_chapters() {
const chapters = document.getElementsByClassName("chapter_list")[0];
if (nav.classList.contains("nav-active")) {
navLinks.forEach((link) => {
if (link.style.animation) {
link.style.animation = '';
}
});
enableScroll();
burger.classList.toggle('toggle');
nav.classList.toggle('nav-active');
}
chapters.scrollIntoView({
block: 'start',
behavior: 'smooth'
})
}
const navSlide = () => {
burger.addEventListener('click', () => {
//Toggle NavBar
nav.classList.toggle('nav-active');
//Animate Links
navLinks.forEach((link, index) => {
if (link.style.animation) {
enableScroll();
link.style.animation = '';
} else {
disableScroll();
link.style.animation = `navLinkFade 0.5s ease forwards ${index / 7 + 0.5}s`;
}
});
burger.classList.toggle('toggle');
});
}
navSlide();
function toggleAnswer(button) {
var wrapper = document.querySelector('.wrapper');
wrapper.classList.toggle('answer');
button.innerHTML = wrapper.classList.contains('answer') ? 'Click to try without answer' : 'Click to try with answer';
}
body {
margin: 0;
background: #212121;
font-family: 'Glory', serif !important;
}
.container {
width: 100%;
margin: 0 0;
}
.container::after {
content: '';
display: grid;
clear: both;
}
.burger {
display: none;
margin-top: 20px;
cursor: pointer;
}
.burger div {
width: 25px;
height: 3px;
background: #EEEEEE;
margin: 5px;
transition: all 0.3s ease;
}
header {
background: #3a345c;
}
nav {
justify-content: space-around;
display: flex;
}
nav ul {
margin: 0;
padding: 0;
list-style: none;
}
nav a:not([data-attr="img"]) {
color: #eeeeee;
text-decoration: none;
text-transform: uppercase;
font-size: 15px;
}
#media only screen and (max-width: 800px) {
.wrapper {
overflow: hidden;
position: relative;
}
.nav-links {
-webkit-box-shadow: inset 0 0.5em 1.5em -0.5em black;
position: absolute;
right: 0;
height: 100%;
top: 70px;
background-color: #3a345c;
z-index: 99;
display: flex;
flex-direction: column;
align-items: center;
width: 100%;
transform: translateX(100%);
transition: transform 0.5s ease-in;
}
.nav-links li {
opacity: 0;
padding-bottom: 50px;
padding-top: 50px;
}
.nav-links li a {
font-size: 20px;
font-weight: bold;
}
.burger {
display: block;
}
}
.nav-active {
transform: translateX(0%);
}
#keyframes navLinkFade {
from {
opacity: 0;
transform: translateX(50px);
}
to {
opacity: 1;
transform: translateX(0);
}
}
/* Work within Stack Snippets window height */
.nav-links li {
padding: 10px;
}
/* Answer */
.answer .fix {
position: relative;
}
.answer .nav-links {
height: 100vh;
}
<html>
<head>
</head>
<body>
<div class="wrapper">
<div class="fix">
<header>
<div class="container">
<nav>
<a style="height: 70px;"></a>
<ul class="nav-links">
<li>Home</li>
<li>Chapters</li>
<li>About</li>
<li>Links</li>
</ul>
<div class="burger">
<div class="line1"></div>
<div class="line2"></div>
<div class="line3"></div>
</div>
</nav>
</div>
</header>
</div>
<button onclick="toggleAnswer(this);">Click to try with answer</button>
<div style="height: 500px;">
</div>
<div class="chapter_list">
<h2 style="color: white; padding-left: 10px;">Chapter list</h2>
</div>
</div>
</body>
</html>

I do not know what is wrong with scrollIntoView, but I remark that when I move the chapiters parts to be a direct child of body, that problem disapear.
However, there is a way to do that same behavior without any js code:
In your CSS code, add scroll-behavior: smooth; to the root.
Add an id to the chapiter : <div id="chap_id" class="chapter_list">
Turn the href attribut of chapiter link in to : an page#id link : <a href="page_chapters#chap_id">
You can find a doc on scroll-behavior here.

So you are using the body as overscroll and there is also a wrapper with the same height (and it's basically the same as the body) with an overscroll hidden.
Your menu you let slide in has a 100% height, so the bottom is at nav:height + 100%. I assume the scroll into view first scrolls the wrapper (as it overflows the nav:height) and then it scrolls the body. Making the nav-bar disappear, as the overflow is hidden.
You can fix this by adjusting the menu height to make it actually 100% in height: e.g. CSS: calc(100% - 70px) or using flex-box and let the menu flex:1.

You have to fix you navbar using "position: fixed" property. Add & Modify given CSS
Here is the result
#media only screen and (max-width: 800px) {
/*ADD This*/
.fix {
position: fixed;
width: 100%;
z-index: 1;
}
/*modify this*/
.nav-links {
height: 100vh;
}
.content {
margin-top: 90px;
}
}

Related

slowly scrolling bug, div stay on page but shouldn't

I have three div boxes in a row, and on scroll, they should show slowly from the side, but when I scroll up slowly and a little after they show up, the left and right boxes for some reason stay on the page.
My function showBox3 writes in console "false" and classList where is "show" class, but this class shouldn't be there.
Actually, my code works when I scroll normally but when I stop scrolling slightly above the limit, the left and right boxes stay on page.
And one more problem is when "topBox" is a little below the limit, and I scroll up just a little more, but still below the limit, boxes quickly remove from the page and show up again.
const box21 = document.querySelector(".box21");
const box22 = document.querySelector(".box22");
const box23 = document.querySelector(".box23");
var trigger = window.innerHeight * 0.8;
window.addEventListener("scroll", showBox2);
function showBox2() {
var check;
const topBox = box22.getBoundingClientRect().top;
if (trigger > topBox) {
box22.classList.add("show");
check = true;
} else {
box22.classList.remove("show");
check = false;
}
showBox1(check);
showBox3(check);
}
function showBox1(ch) {
if (ch == true) {
setTimeout(() => {
box21.classList.add("show");
}, 400);
} else {
box21.classList.remove("show");
}
}
function showBox3(ch) {
if (ch == true) {
setTimeout(function () {
box23.classList.add("show");
}, 700);
} else {
box23.classList.remove("show");
console.log(box23.classList);
console.log(ch);
}
}
* {
box-sizing: border-box;
margin: 0;
padding: 0;
}
.box1 {
height: 110vh;
background-color: aqua;
display: flex;
align-items: center;
justify-content: center;
}
/* I have a bug in box 2 */
.box2 {
height: 60vh;
width: 100%;
background-color: #ddd;
display: flex;
align-items: center;
justify-content: space-around;
}
.box2>div {
height: 70%;
width: 27%;
background-color: black;
}
.box21 {
transform: translateX(-140%) rotate(-45deg);
transition: transform 1.4s ease;
}
.box21.show {
transform: translateX(0%) rotate(0deg);
}
.box22 {
transform: translateX(340%) rotate(+45deg);
transition: transform 0.8s ease;
}
.box22.show {
transform: translateX(0%) rotate(0deg);
}
.box23 {
transform: translateX(340%) rotate(-45deg);
transition: transform 1.8s ease;
}
.box23.show {
transform: translateX(0%) rotate(0deg);
}
/* this part below is not important */
.box3 {
height: 60vh;
width: 100%;
background-color: cornflowerblue;
}
<!DOCTYPE html>
<html>
<head>
<link rel="stylesheet" href="css.css" />
</head>
<body>
<div class="box1">
<h1>Scroll down</h1>
</div>
<div class="box2">
<div class="box21"></div>
<div class="box22"></div>
<div class="box23"></div>
</div>
<div class="box3"></div>
</body>
<script src="js.js"></script>
</html>

How to Detect mousewheel Movement and Make It not Incremental

May you all have a good day Today!
I finally made my scrollable tab, but it's not what I want. Because, when I scroll up one time it moves to the previous tab in which one scroll is one movement, it's incremental. But, what I want is as much I scroll the mouse once, it changes to another tab. I already add the console.log to my code below. My reference is Fullpage JS and this landing page. Please go see it if you don't understand my explanation.
UPDATE-1 :
I already found it in another post of stackoverflow that very similar to my problem in here : Detect the number of times mouse wheel was spun and not the length it was spun. But, alvaro commented that this method not working in kinetic devices.
Please help me to get through this. So, here's my code :
//Add & remove class tab, contents, & menu onclick & wheel
window.addEventListener('DOMContentLoaded', ()=> {
let tabs = document.querySelectorAll('.tab');
let content = document.querySelectorAll('.content');
let firstTab = function(tabs) {tabs.classList.add('tab-active')};
let firstContent = function(content) {content.classList.add('content-active')};
let activeTab = 0;
firstTab(tabs[0]);
firstContent(content[0]);
for (let i = 0; i < tabs.length; i++) {
tabs[i].addEventListener('click', () => tabClick(i));
}
function detect(e) {
var delta = null,
direction = false;
if(!e) {e = window.event;}
if(e.wheelDelta) {delta = e.wheelDelta / 60;
} else if(e.detail) {delta = -e.detail / 2;}
if(delta !== null) {
direction = delta > 0 ? 'up' : 'down';}
return direction;
}
function handle(direction) { //mousewheel to change tabs
console.log(direction);
if(direction == 'down') {
if(activeTab >= tabs.length - 1) {
activeTab = 0;
tabClick(activeTab);
} else {
tabClick(activeTab + 1);
}
} else if(direction == 'up') {
if(activeTab === 0) {
activeTab = tabs.length - 1;
tabClick(activeTab);
} else {
tabClick(activeTab - 1);
}
} else {
// this means the direction of the mouse wheel could not be determined
}
}
document.onmousewheel = function(e) {handle(detect(e));};
if(window.addEventListener) {document.addEventListener
('DOMMouseScroll', function(e) {handle(detect(e));});
}
function tabClick(currentTab) {
removeActive();
//Add Active Class
tabs[currentTab].classList.add('tab-active');
content[currentTab].classList.add('content-active');
activeTab = currentTab;
}
function removeActive() {
for (let i = 0; i < tabs.length; i++) {
//Remove Active Class
content[i].classList.remove('content-active');
content[i].classList.add('content-show');
setTimeout(function() {
content[i].classList.remove('content-show');
},1500);
tabs[i].classList.remove('tab-active');
}
}
})
/* WHOLE CONTAINER */
.container {
width: 96vw;
height: 96vh;
}
/* TABS */
.tabs {
display: flex;
height: 50px;
overflow: hidden;
align-items: center;
justify-content: center;
width: 100%;
}
.tab {
font-size: 14px;
padding: 5px 10px;
cursor: pointer;
letter-spacing: 2px;
text-alignment: center;
}
#red.tab-active {background-color: rgb(245, 66, 66);}
#blue.tab-active {background-color: rgb(66, 135, 245);}
#yellow.tab-active {background-color: rgb(245, 215, 66);}
#green.tab-active {background-color: rgb(56, 235, 98);}
#cyan.tab-active {background-color: rgb(79, 247, 219);}
/* TAB CONTENTS */
.contents {
width: 100%;
margin-top: 5px;
height: 80%;
}
.content {
width: 96%;
height: 80%;
display: none;
padding: 0;
margin: 0;
border: none;
position: absolute;
}
.content-show {
display: flex;
animation-name: fade-out;
animation-duration: 2.5s;
}
#keyframes fade-out {
0% {
opacity: 1;
display: flex;
}
99% {
opacity: 0;
display: flex;
}
100% {
opacity: 0;
display: none;
}
}
.content-active {
display: flex;
border: none;
justify-content: center;
animation-name: fade-in;
animation-duration: 2.5s;
}
#keyframes fade-in {
0% {
display: none;
opacity: 0;
}
1% {
display: block;
opacity: 0.01;
}
100%{
display: block;
opacity: 1;
}
}
#red.content-active {background-color: rgb(245, 66, 66);}
#blue.content-active {background-color: rgb(66, 135, 245);}
#yellow.content-active {background-color: rgb(245, 215, 66);}
#green.content-active {background-color: rgb(56, 235, 98);}
#cyan.content-active {background-color: rgb(79, 247, 219);}
<div class="container">
<div class="tabs">
<div id="red" class="tab">RED</div>
<div id="blue" class="tab">BLUE</div>
<div id="yellow" class="tab">YELLOW</div>
<div id="green" class="tab">GREEN</div>
<div id="cyan" class="tab">CYAN</div>
</div>
<div class="contents">
<div id="red" class="content"></div>
<div id="blue" class="content"></div>
<div id="yellow" class="content"></div>
<div id="green" class="content"></div>
<div id="cyan" class="content"></div>
</div>
</div>
Thanks A lot Guys..

Wordpress Divi - problem with inserting code for Animated Cursor

This is my new clear site: www.talas.me
And this is what i want to copy: Awesome Link Hover Effect / Animated Cursor
(function () {
const link = document.querySelectorAll('nav > .hover-this');
const cursor = document.querySelector('.cursor');
const animateit = function (e) {
const span = this.querySelector('span');
const { offsetX: x, offsetY: y } = e,
{ offsetWidth: width, offsetHeight: height } = this,
move = 25,
xMove = x / width * (move * 2) - move,
yMove = y / height * (move * 2) - move;
span.style.transform = `translate(${xMove}px, ${yMove}px)`;
if (e.type === 'mouseleave') span.style.transform = '';
};
const editCursor = e => {
const { clientX: x, clientY: y } = e;
cursor.style.left = x + 'px';
cursor.style.top = y + 'px';
};
link.forEach(b => b.addEventListener('mousemove', animateit));
link.forEach(b => b.addEventListener('mouseleave', animateit));
window.addEventListener('mousemove', editCursor);
})();
html, body {
margin: 0;
padding: 0;
cursor: none;
}
.nav-wrapper {
width: 100%;
height: 100vh;
background: #161616;
}
nav {
width: 100%;
margin: 0 auto;
text-align: center;
position: absolute;
top: 50%;
}
.hover-this {
transition: all 0.3s ease;
}
span {
display: inline-block;
font-family: "Monument Extended";
font-weight: 300;
color: #fff;
font-size: 36px;
text-transform: uppercase;
pointer-events: none;
transition: transform 0.1s linear;
}
.cursor {
pointer-events: none;
position: fixed;
padding: 0.3rem;
background-color: #fff;
border-radius: 50%;
mix-blend-mode: difference;
transition: transform 0.3s ease;
}
.hover-this:hover ~ .cursor {
transform: translate(-50%, -50%) scale(8);
}
#media(min-width: 900px) {
nav {
display: flex;
justify-content: space-around;
}
}
#media(max-width: 900px) {
nav {
top: 30%;
}
.hover-this {
width: 100%;
padding: 20px 0;
display: inline-block;
}
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div class="nav-wrapper">
<nav>
<span>Home</span>
<span>Our Story</span>
<span>Studio</span>
<span>Contact</span>
<div class="cursor"></div>
</nav>
</div>
There is problem somewhere and i can't figure out where. As you can see now (when i copy this code correctly) we can't see the cursor on my site.
Can someone tell me what is the problem and how to fix it?
This is very important for my site because the site will be black and white, and this cursor effect is so important to me.
Thank you!
as far as i know that Divi theme provide a option in theme settings where we can add custom jQuery or javascript so you can directly add over there
this below link may help you to resolve issue
https://divi.space/tutorials/how-to-add-javascript-and-jquery-to-divi/

Adding a style to a link when a class is clicked, and removing it once that class is clicked again

I have a burger (3 lines) <div class="burger"> in my navbar for mobile view (768px/less). When I click on it the menu slides from the right. the burger is hidden in desktop view.
I want to add a width to the menu links #menu li a once I click on the burger, than removing the width once the burger gets clicked on again, or once the page width is above 768px.
So far I managed to get the width to apply to the burger when it's clicked, but even when I click it again and check the desktop view the width won't go away.
My current codes:
// Navbar Slide
const burger = document.querySelector('.burger');
const menu = document.getElementById('menu');
const menuLinks = document.querySelectorAll('#menu li');
const menuCS = window.getComputedStyle(menu);
const width = menuCS.width;
const widthTest = '200px';
const navLinks = document.querySelectorAll('#menu li a');
const navSlide = () => {
burger.addEventListener('click', () => {
// # toggle nav
menu.classList.toggle('menu-active');
// # nav links width
navLinks.forEach((link) => {
link.style.width = width;
});
// # links animation
menuLinks.forEach((link, index) => {
if (link.style.animation) {
link.style.animation = '';
} else {
link.style.animation = `menuLinkFade .5s ease forwards ${index / 7 + 0.4}s`;
}
});
// # burger animation
burger.classList.toggle('toggle');
});
}
navSlide();
#menu {
display: flex;
justify-content: space-around;
width: auto;
height: 8vh;
margin-right: 10%;
}
#menu li a {
display: inline-block;
line-height: 8vh;
color: #ffffff;
text-decoration: none;
padding: 0 20px;
}
.burger {
display: none;
margin-right: 10%;
}
#media screen and (max-width:768px) {
#menu {
position: absolute;
top: 8vh;
right: 0;
height: 92vh;
width: 50%;
display: flex;
flex-direction: column;
align-items: center;
background-color: #313131;
margin: 0;
justify-content: normal;
transform: translateX(100%);
transition: transform .5s ease-in;
}
#menu.menu-active {
transform: translateX(0%);
}
#menu li a {
text-align: center;
padding: 40px 0;
}
.burger {
display: block;
cursor: pointer;
position: absolute;
right: 0;
}
}
<div id="nav">
<div class="logo">
<h4>The Nav</h4>
</div>
<ul id="menu">
<li class="active">Home</li>
<li><a href="#">About</a class="view"></li>
<li><a href="#">Contact</a class="view"></li>
<li><a href="#">Product</a class="view"></li>
</ul>
<div class="burger">
<div class="line1"></div>
<div class="line2"></div>
<div class="line3"></div>
</div>
</div>
I tried different approaches but nothing seems to work for me.
SOLVED. I just added a class="desktop" to the links and put a width: auto !important in it, and than added that to javascript:
// # nav links width
navLinks.forEach((link) => {
link.style.width = width;
link.classList.toggle('desktop');
});
// Check Width
window.addEventListener("resize", function(event) {
if (document.body.clientWidth > 751) {
if (!navLinks.desktop) {
navLinks.forEach((link) => {
link.classList.add('desktop');
});
}
menu.classList.remove('menu-active');
burger.classList.remove('toggle');
menuLinks.forEach((link, index) => {
if (link.style.animation) {
link.style.animation = '';
} else {
link.style.animation = '';
}
});
}
menu.style.transition = '';
});
}

Why is my responsive navigation bar, made with Javascript, working only after refresh in iPhone browsers?

If a user, using iPhone (actual devices), lands on my website for the first time the "hamburger menu" will not open the menu at all, and navbar will not appear on scrolldown. It seems to be working just fine on Android devices (except maybe Nexus 4 in portrait mode if we were to believe responsinator ), and Win desktops.
The actual website's backend is made with Razor/ASP.NET but obviously I believe this is a pure frontend issue.
After a refresh it starts to work on Apple devices (well, iPhone) as well. And then sometimes stops working (once or twice it stopped working again, I believe).
Head (tried removing async and defer, did not work):
<script type="text/javascript" src="script.js" async defer></script>
Here is HTML (with bad usage of h2 tag with logo image in it):
<div id="navigation-main">
<h2 class="logo">
<a href="#">
<img src="images/white-logo.png" alt="">
</a>
</h2>
<div id="menu-icon">
<span class="icon-menu-hamburguer"></span>
</div>
<nav id="menu-main">
<ul>
<li><a class="scroll" href="#about-anchor">About us</a></li>
<li><a class="scroll" href="#agenda-anchor">Agenda</a></li>
<li><a class="scroll" href="#gallery-anchor">Gallery</a></li>
<li><a class="scroll" href="#sponsors-anchor">Sponsors</a></li>
<li><a class="scroll" href="#contact-anchor">Contact</a></li>
<li>Log in <img src="images/login_icon.png" alt=""></li>
</ul>
</nav>
CSS:
#navigation-main {
min-height: 60px;
z-index: 9;
overflow: hidden;
-webkit-transition: all 0.5s linear;
-moz-transition: all 0.5s linear;
-ms-transition: all 0.5s linear;
-o-transition: all 0.5s linear;
transition: all 0.5s linear;
}
#navigation-main:active {
background-color: #000000;
}
#navigation-main .logo {
float: left;
}
#navigation-main .logo img {
display: none;
}
#navigation-main nav {
position: relative;
top: 20px;
}
#navigation-main nav ul {
margin: 0;
padding-left: 0;
}
#navigation-main nav ul li {
list-style: none
}
#navigation-main nav ul li a {
color: #FFFFFF;
text-decoration: none
}
#navigation-main #menu-icon {
display: none;
}
#navigation-main.active {
background-color: rgb(0, 0, 0);
position: fixed;
top: 0;
height: 60px;
width: 100%;
margin-bottom: 0;
-webkit-transition: all 0.5s linear;
-moz-transition: all 0.5s linear;
-ms-transition: all 0.5s linear;
-o-transition: all 0.5s linear;
transition: all 0.5s linear;
}
#navigation-main.active img {
display: inline-block;
}
#navigation-main.active #menu-icon {
top: 10px;
}
#navigation-main.active .logo img {
max-width: 50%;
}
#navigation-main.active nav li a {
color: #FFFFFF
}
#navigation-main nav ul li img {
vertical-align: middle;
}
#media (max-width: 768px) {
#navigation-main .logo img {
max-width: 80%
}
#navigation-main #menu-icon {
padding: 18px 12px;
margin: 2px 0;
position: relative;
top: 20px;
display: block;
float: right;
z-index: 10;
cursor: pointer;
}
#navigation-main #menu-icon .icon-menu-hamburguer {
background: #ff0000;
width: 30px;
height: 4px;
margin: 2px 0;
display: block;
}
#navigation-main #menu-icon .icon-menu-hamburguer:after,
#navigation-main #menu-icon .icon-menu-hamburguer:before {
content: '';
background: #ff0000;
width: 30px;
height: 4px;
display: block;
margin: 2px 0;
position: relative;
}
#navigation-main #menu-icon .icon-menu-hamburguer:before {
bottom: 8px;
}
#navigation-main #menu-icon .icon-menu-hamburguer:after {
top: 2px;
}
#navigation-main nav {
display: none;
width: 100%;
}
#navigation-main nav.menu-active {
display: block;
clear: both;
height: 100%;
position: fixed;
z-index: 1;
left: 0;
top: 0;
background-color: rgb(0, 0, 0);
background-color: rgba(0, 0, 0, 0.80);
overflow-x: hidden;
}
#navigation-main nav.menu-active ul {
position: relative;
top: 15%;
width: 100%;
text-align: center;
margin-top: 30px;
}
#navigation-main nav.menu-active a {
padding: 8px;
text-decoration: none;
font-size: 1.75rem;
display: block;
}
}
#media (min-width: 768px) {
#navigation-main nav {
float: right;
padding-right: 20px;
}
#navigation-main nav ul li,
#navigation-main nav ul li img {
display: inline-block;
}
#navigation-main nav ul li a {
padding: 0 5px;
font-size: 0.9rem;
}
}
Javascript:
(function() {
////////// Sticky navbar and hamburger icon
var headerScroll = getId('navigation-main'),
scrollHeight = 250,
menuIcon = getId('menu-icon'),
menuMain = getId('menu-main'),
classMenu = 'menu-active',
classHeader = 'active';
// Scroll
window.addEventListener("scroll", scrollOn);
function scrollOn() {
animatedScroll(headerScroll, classHeader, scrollHeight);
}
// Responsive menu
menuIcon.onclick = function() {
toggle(menuMain, classMenu);
}
menuMain.onclick = function() {
toggle(menuMain, classMenu);
}
// Moving the element after scrolling
function animatedScroll(element, classN, height) {
y = pageYOffset;
if (y > height) {
element.className = classN;
} else {
element.className = '';
}
}
// Change the element's class
function toggle(element, classe) {
element.className = element.className ? '' : classe;
}
// Return the element
function getId(id) {
return document.getElementById(id);
}
////////// Sticky navbar and hamburger icon
// Feature Test
if ('querySelector' in document && 'addEventListener' in window && Array.prototype.forEach) {
// Function to animate the scroll
var smoothScroll = function(anchor, duration) {
// Calculate how far and how fast to scroll
var startLocation = window.pageYOffset;
var endLocation = anchor.offsetTop;
var distance = endLocation - startLocation;
var increments = distance / (duration / 16);
var stopAnimation;
// Scroll the page by an increment, and check if it's time to stop
var animateScroll = function() {
window.scrollBy(0, increments);
stopAnimation();
};
// If scrolling down
if (increments >= 0) {
// Stop animation when you reach the anchor OR the bottom of the page
stopAnimation = function() {
var travelled = window.pageYOffset;
if ((travelled >= (endLocation - increments)) || ((window.innerHeight + travelled) >= document.body.offsetHeight)) {
clearInterval(runAnimation);
}
};
}
// If scrolling up
else {
// Stop animation when you reach the anchor OR the top of the page
stopAnimation = function() {
var travelled = window.pageYOffset;
if (travelled <= (endLocation || 0)) {
clearInterval(runAnimation);
}
};
}
// Loop the animation function
var runAnimation = setInterval(animateScroll, 16);
};
// Define smooth scroll links
var scrollToggle = document.querySelectorAll('.scroll');
// For each smooth scroll link
[].forEach.call(scrollToggle, function(toggle) {
// When the smooth scroll link is clicked
toggle.addEventListener('click', function(e) {
// Prevent the default link behavior
e.preventDefault();
// Get anchor link and calculate distance from the top
var dataID = toggle.getAttribute('href');
var dataTarget = document.querySelector(dataID);
var dataSpeed = toggle.getAttribute('data-speed');
// If the anchor exists
if (dataTarget) {
// Scroll to the anchor
smoothScroll(dataTarget, dataSpeed || 500);
}
}, false);
});
}
})();
And here is JSFiddle.
If it's touchstart/onclick issue why does it work after the refresh? Should I remove IFFE? Should I put script tag at the end of the page?
What seems to be the issue here?
Apparently the line in the header was an issue.I have removed "async" and the navigation menu started working.
<script type="text/javascript" src="script.js" async defer></script>
changed to:
<script type="text/javascript" src="script.js" defer></script>

Categories

Resources