Toggle Button To Expanding Navigation Menu On Click - javascript

When I click on the menu anchor element it takes me back to the top of the page. As I scroll through the site I would like the menu to stay at the section that I have scrolled to when I click the menu anchor. I would like the menu anchor to only act as an open and close function of the expanding nav. [
function openMenu() {
document.getElementById('menu').style.width = "608px"
document.getElementById('content').style.marginLeft = "608px"
}
function closeMenu() {
document.getElementById('menu').style.width = "0px"
document.getElementById('content').style.marginLeft = "0px"
}
:root {
--main-color: #FEFF66;
--second-color: #000000;
--third-color: #FFFFFF;
}
* {
margin: 0;
padding: 0;
}
.slide {
margin: 18px;
font-size: 25px;
position: fixed;
}
.slide a {
text-decoration: none;
color: var(--second-color);
writing-mode: vertical-rl;
transform: rotate(-180deg);
}
.help a {
text-decoration: none;
color: var(--second-color);
}
.help {
display: flex;
height: 100%;
width: 0;
position: fixed;
z-index: 1;
top: 0;
left: 0;
background-color: var(--third-color);
color: var(--second-color);
overflow: hidden;
}
.links {
font-size: 40px;
line-height: 60px;
padding-top: 14px;
}
.header-menu {
writing-mode: vertical-rl;
transform: rotate(-180deg);
margin: 18px;
font-size: 25px;
padding-left: 55px;
}
<section id="header">
<span class="slide">
MENU
</span>
<div id="menu" class="help">
<div><a class="header-menu" href="#" onclick="closeMenu()">MENU</a></div>
<div class="links">
OUR STORY<br>
ROOMS + BOOK<br>
THE NEIGHBOURHOOD<br>
THE ART<br>
FAQ
</div>
</div>
</section>
]1

On your click listener pass in the event received as follow:
<div><a class="header-menu" href="#" onclick="closeMenu($event)">MENU</a></div>
The $event in the template has a special meaning in this case.
Then, on your closeMenu function adjust accordingly and prevent the default behavior of browser for anchor elements.
// Here, the function parameter can be named whatever you like,
// I named it "event" but anything else would work.
function closeMenu(event) {
// The line below will prevent the default behavior of the browser
// for this element and event, which means, it scroll to anywhere
// in this case, nor redirect to another page in case you had a URL
// in the href attribute.
event.preventDefault();
// Your code ...
}

Add event.preventDefault(); inside your javascript.
function openMenu(event) {
event.preventDefault();
document.getElementById('menu').style.width = "608px"
document.getElementById('content').style.marginLeft = "608px"
}
This prevent default actions of object you clicked, in this case anchor tag.
Reference: https://developer.mozilla.org/en-US/docs/Web/API/Event/preventDefault?retiredLocale=it

Related

a href's not working from inside a modal popup NOT BOOTSTRAP, NOT JQUERY

The aside element is a modal popup with multiple a href links inside, none of which are working. I can right click and go to the link but clicking on it does nothing. The open modal is triggered by Javascript. There are no external libraries, plugins etc that could be causing conflict.
What am I missing here?
const overlay = document.querySelector(".overlay");
const card = document.querySelectorAll(".card");
card.forEach((card) => {
card.addEventListener("click", () => {
const cardId = card.getAttribute("data-card");
const modal = document.getElementById(`${cardId}`);
modal.classList.remove("hidden");
overlay.classList.remove("hidden");
const vScrollPos = window.scrollY;
document.body.style.position = "fixed";
document.body.style.top = `-${vScrollPos}px`;
const closeModal = function() {
modal.classList.add("hidden");
overlay.classList.add("hidden");
const scrollY = document.body.style.top;
document.body.style.position = "";
document.body.style.top = "";
window.scrollTo(0, parseInt(scrollY || "0") * -1);
};
const modalCloseBtn = modal.querySelector(".close-modal");
modalCloseBtn.addEventListener("click", () => {
closeModal();
});
overlay.addEventListener("click", closeModal);
document.addEventListener("keydown", function(e) {
if (e.key === "Escape" && !modal.classList.contains("hidden")) {
closeModal();
}
});
});
});
.hidden {
display: none;
}
.modal {
position: fixed;
top: 50%;
left: 50%;
transform: translate(-50%, -50%);
width: calc(100vw - 16rem);
overflow-y: scroll;
max-height: calc(100vh - 16rem);
background-color: white;
padding: 6rem;
border-radius: 5px;
box-shadow: 0 3rem 5rem rgba(0, 0, 0, 0.3);
z-index: 10;
pointer-events: all;
cursor: pointer;
}
.overlay {
position: fixed;
top: 0;
left: 0;
width: 100%;
height: 100%;
background-color: rgba(0, 0, 0, 0.6);
backdrop-filter: blur(3px);
overflow-y: scroll;
z-index: 5;
}
.modal-title {
font-size: 2.4rem;
margin-bottom: 3rem;
}
.close-modal {
position: absolute;
top: 1.2rem;
right: 2rem;
font-size: 5rem;
color: #333;
cursor: pointer;
border: none;
background: none;
}
<article class="card" data-card="modal1">
<img class="card-img" src="img/card-thumb/cardImg.jpg" alt="card image">
<p class="card-title">open card modal</p>
</article>
<aside class="modal hidden" id="modal1">
<button class="close-modal">×</button>
<h5 class="modal-title">
<a href='https://www.google.com/' target='_blank' rel='noreferrer noopener nofollow'>WHY IS THIS LINK NOT OPENING?</a>
<h5>
</aside>
Ok. issue has been found and fixed.
I was using scrollIntoView to handle page nav and smooth scrolling and I imprecisely targeted all "a" elements before I wrote the code for this current section with "a" elements inside of modal containers. Solved issue by giving the page nav a's an additional class then targeting that class only for that section of JS code! Doooooh.

Hovering refuses to work when another element is on top

By the way, this is coming from a beginner coder, so don't expect any great amount of organization. I may have missed something obvious.
I couldn't get it to work here as a snippet (for security reasons, it won't allow images to be loaded, not even showing the failing to load icon), so I made a copy of it here.
The issue is that, while hovering over a folder, it works fine, but when I begin hovering over the menu that pops up while hovering over the folder, it starts flashing rapidly. Yes, the menu is supposed to delete itself when the user stops hovering over the folder and show when the user hovers over the folder.
HTML code:
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width">
<title>Something</title>
<link href="style.css" rel="stylesheet" type="text/css" />
<link href='https://fonts.googleapis.com/css?family=Poppins' rel='stylesheet'>
</head>
<body>
<!-- See CSS code for more explanation -->
<div class="sidebar">
<h1 style="padding: 1vw;">Todo</h1>
<div class="folder">
Folder 1
</div>
<div class="folder">
Folder 2
</div>
<div class="folder">
Folder 3
</div>
<div class="addBtn">+ Folder</div>
</div>
<script src="script.js"></script>
</body>
</html>
CSS code:
/* might have something to do with css; please read my hastily made comments */
/* self explanatory */
html,body {
height: 100%;
margin: 0px;
padding: 0px;
background-color: black;
}
/* sets some defaults */
* {
padding: 0px;
margin: 0px;
border: 0px;
overflow: hidden;
font-family: Poppins;
background-color: inherit;
}
/* sets text selection color to nothing */
*::selection {
background: inherit;
}
/* styling for the sidebar (the part that says "todo", shows folders, etc.) */
.sidebar {
background: #9caeb0;
display: inline-block;
width: calc(20% - 2vw);
height: 100vh;
padding: 1vw;
}
/* the text that says todo */
h1 {
font-size: 30px;
font-weight: 700;
}
/* a folder. */
.folder {
width: calc(15.4vw);
background-color: #8c9ca3;
padding: .6vw;
padding-left: 1.25vw;
padding-right: 1.25vw;
border-radius: 0px 5px 5px 0px;
font-weight: 200;
cursor: pointer;
transition: .45s;
margin: .6vw;
margin-left: -1vw;
margin-right: calc(0vw);
font-size: 15px;
position: relative;
}
/* uses css animations to change the folder upon hovering */
.folder:hover {
background-color: #75828a;
cursor: pointer;
margin-top: .8vw;
margin-bottom: .8vw;
margin-left: -2vw;
padding-left: 2.25vw;
width: 15.8vw;
font-size: 17px;
}
/* the add folder button */
.addBtn {
width: 15.4vw;
background-color: rgba(0,0,0,0);
padding: .6vw;
padding-left: 1.25vw;
padding-right: 1.25vw;
border-radius: 0px 5px 5px 0px;
font-weight: 200;
cursor: pointer;
transition: .45s;
margin-left: -1vw;
font-size: 15px;
border: 3px solid #8c9ca3;
border-left: 0;
/*position: absolute;
bottom: 4vh;*/
}
/* changes bg color upon hovering over add folder button */
.addBtn:hover {
background-color: #8c9ca3;
}
.smallMenu {
position: absolute;
height: 17px;
top: 50%;
width: 17px;
-ms-transform: translateY(-50%);
transform: translateY(-50%);
right: 0.5vw;
border-radius: 99px;
}
.menuBtn {
position: absolute;
height: 14px;
top: 1.5px;
left: 7px;
padding: 0px;
margin: 0px;
}
JS Code:
// probably can ignore these functions; scroll down to line 45; there's a lot of code here for purposes that I haven't quite finished yet
function inLocalStorage(item) {
if(!localStorage.getItem(item)) {
return false;
} else {
return true;
}
}
function lsAdd(label,value) {
localStorage.setItem(label, value);
}
function lsGet(item) {
return localStorage.getItem(item);
}
function lsClear() {
localStorage.clear();
}
function lsRemove(item) {
localStorage.removeItem(item);
}
var el;
var mouseOver = false;
// checks if the user has visited
if (!inLocalStorage('visited')) {
alert("Don't mind this alert");
lsAdd('visited','yes');
lsAdd('folders','1');
lsAdd('js','');
} else {
// load from local storage; execute stored JS
new Function(lsGet('js'))();
// upon mouseover of folder, show mini menu icon
for (let i = 0; i < document.getElementsByClassName("folder").length; i++) {
document.getElementsByClassName("folder")[i].addEventListener("click", function() {
console.log("You have clicked.");
});
// add menu upon mouseover
document.getElementsByClassName("folder")[i].addEventListener("mouseover", function() {
mouseOver = false;
el = document.createElement("div");
// this image obviously doesn't load but that's not important; the image is an svg with three vertical dots, and the image is transparent
el.innerHTML = '<div class="smallMenu"><img src="abc.svg" class="menuBtn" style="height:14px;"></div>';
el.setAttribute("id","menu");
document.getElementsByClassName('folder')[i].appendChild(el);
el = document.getElementsByClassName('smallMenu')[0];
el.addEventListener('mouseover', function() {
mouseOver = true;
console.log(mouseOver);
});
el.addEventListener('mouseout', function() {
mouseOver = false;
console.log(mouseOver);
});
});
// remove menu upon mouse out
document.getElementsByClassName("folder")[i].addEventListener("mouseout", function() {
if (mouseOver === false) {
el = document.getElementById("menu");
el.remove();
}
});
}
}

Disabling inactive toggle in jQuery

I have the following functional code. However, I would like to know how I can disable toggle buttons. I always want to have one of my bottom navbar icons active and its respective content should be shown in the main section. If I click on the active navbar icon (the toggle) it wouldn't be deactivated.
Thanks in advance for your help!
$(document).ready(function() {
// only show menu-1
$('.menu-1').click(function() {
if ($('.menu-2, .menu-3').hasClass('active')) {
$('.menu-2, .menu-3').removeClass('active');
$('.content-2, .content-3').removeClass('active');
}
$('.menu-1').toggleClass('active');
$('.content-1').toggleClass('active');
});
// only show menu-2
$('.menu-2').click(function() {
if ($('.menu-1, .menu-3').hasClass('active')) {
$('.menu-1, .menu-3').removeClass('active');
$('.content-1, .content-3').removeClass('active');
}
$('.menu-2').toggleClass('active');
$('.content-2').toggleClass('active');
});
// only show menu-3
$('.menu-3').click(function() {
if ($('.menu-2, .menu-1').hasClass('active')) {
$('.menu-2, .menu-1').removeClass('active');
$('.content-2, .content-1').removeClass('active');
}
$('.menu-3').toggleClass('active');
$('.content-3').toggleClass('active');
});
});
.container {
margin: 0 auto;
background-color: #eee;
border: 1px solid lightgrey;
width: 20vw;
height: 90vh;
font-family: sans-serif;
position: relative;
}
header {
background-color: lightgreen;
padding: 5px;
text-align: center;
text-transform: uppercase;
}
.bottom-navbar {
position: absolute;
bottom: 0;
width: 100%;
padding: 6px 0;
overflow: hidden;
background-color: lightgreen;
border-top: 1px solid var(--color-grey-dark-3);
z-index: 50;
display: flex;
justify-content: space-between;
> a {
display: block;
color: green;
text-align: center;
text-decoration: none;
font-size: 20px;
padding: 0 10px;
&.active {
color: black;
}
}
}
.menu-1.active,
.menu-2.active,
.menu-3.active {
color: black;
}
.content-1,
.content-2,
.content-3 {
display: none;
}
.content-1.active,
.content-2.active,
.content-3.active {
display: block;
position: absolute;
top: 50%;
left: 50%;
transform: translateX(-50%) translateY(-50%);
}
<div class="container">
<header>My header</header>
<div class="main-content">
<div class="content-1">House content</div>
<div class="content-2">Map content</div>
<div class="content-3">Explore content</div>
<div class="bottom-navbar">
<i class="fa fa-home"></i>
<i class="fa fa-map"></i>
<i class="fa fa-search"></i>
</div>
</div>
If you find it easier, here's my CodePen: https://codepen.io/fergos2/pen/vYYaRzN
You can use this jQuery code. Anyone can enhance that.
$(document).ready(function() {
$('.bottom-navbar a').click(function(){
var cls = $(this).attr('class');
var lastchr = cls.substr(cls.length - 1);
$(this).siblings('a').removeClass('active');
$(this).addClass('active');
$("div[class^='content-'],div[class*=' content-']").removeClass('active');
$('.content-'+ lastchr).addClass('active');
})
});
Instead of toggleClass() you could use addClass():
https://codepen.io/vladanme/pen/LYYBrqJ
$(document).ready(function() {
// only show menu-1
$('.menu-1').click(function() {
if ($('.menu-2, .menu-3').hasClass('active')) {
$('.menu-2, .menu-3').removeClass('active');
$('.content-2, .content-3').removeClass('active');
}
$('.menu-1').addClass('active');
$('.content-1').addClass('active');
});
// only show menu-2
$('.menu-2').click(function() {
if ($('.menu-1, .menu-3').hasClass('active')) {
$('.menu-1, .menu-3').removeClass('active');
$('.content-1, .content-3').removeClass('active');
}
$('.menu-2').addClass('active');
$('.content-2').addClass('active');
});
// only show menu-3
$('.menu-3').click(function() {
if ($('.menu-2, .menu-1').hasClass('active')) {
$('.menu-2, .menu-1').removeClass('active');
$('.content-2, .content-1').removeClass('active');
}
$('.menu-3').addClass('active');
$('.content-3').addClass('active');
});
});
Use addClass() instead of toggleClass().
It looks like you have the code to clear the inactive buttons already. So you're only left with the button that you would like to maintain active.
[..]
$('.menu-1').addClass('active');
$('.content-1').addClass('active');
[..]
[..]
$('.menu-2').addClass('active');
$('.content-2').addClass('active');
[..]
[..]
$('.menu-3').addClass('active');
$('.content-3').addClass('active');
[..]

Icon interfering with button click event

I have a button enclosing an icon. I believe the icon is interfering with my click event. I am only able to click on the icon margins to activate the onclick event, but nothing happens when I click on the icon. I replaced the icon with some text and the button onclick works perfectly fine. I have tried z-index to put the icon behind the button, but to no avail. Can someone explain why the icon blocks the click from occurring and how I can fix it?
html:
<div class="navMenu">
<button onclick="navClick()" class="navMenu-button"><i class="fas fa-bars"></i></button>
<div id="navList" class="navMenu-content">
Home
About
Resume
</div>
sass:
.navMenu{
position: relative;
display: inline-block;
margin-top:5px;
margin-left:5px;
&-button {
background-color: #615b5b;
border-radius:50%;
color: white;
padding: 7px;
opacity:0.7;
border:none;
font-size: 14px;
cursor: pointer;
}
&-button:hover, &-button:focus {
background-color: #615b5b;
}
&-content {
display: none;
position: absolute;
background-color: #f1f1f1;
min-width: 200px;
box-shadow: 0px 8px 16px 0px rgba(0,0,0,0.2);
z-index: 1;
}
&-content .navMenu-link{
color: $body-text-color;
padding: 12px 16px;
text-decoration: none;
display: block;
}
&-content .navMenu-link:hover {
background-color: #ddd;
}
&-show {
display:block;
}
}
js:
function navClick() {
document.getElementById("navList").classList.toggle("navMenu-show");
}
window.onclick = function(event) {
if (!event.target.matches('.navMenu-button')) {
var dropdowns = document.getElementsByClassName("navMenu-content");
var i;
for (i = 0; i < dropdowns.length; i++) {
var show = dropdowns[i];
if (show.classList.contains('navMenu-show')) {
show.classList.remove('navMenu-show');
}
}
}
}
This is happening becuase your are setting an event that verifies if the element clicked contains an especific class, and indeed when it clicks the icon, it won't match because the icon does not contains the class you can solve it asking if also the parent contains the class....
window.onclick = function(event) {
if (event.target.matches('.navMenu-button') ||
event.target.parentNode.matches('.navMenu-button')
) {
console.log("it matches...");
}
}
.icon {
background:red;
}
<button class="navMenu-button">this is the button
<div class="icon">this is the icon</div>
</button>
On the other hand you could reference the click event using the "onclick" method in this case it will solve it automatically..
var button = document.querySelectorAll('.navMenu-button')[0];
button.onclick = function() {
console.log("button clicked");
}

Go-to-top button completely dissapears on scroll

I'm trying to put go-to-top button in the bottom right angle of the screen. It should appear on scroll function, a disappear when I go back to top.
The button exists, but when I scroll down, it stays with "home page", so as I scroll more, it is not visible anymore. How to fix the problem? You can see my codes down here. Thanks a lot in advance!
window.onscroll = function(){goTop()};
let goTop = function() {
var rocket = document.querySelector(".go-to-top");
var scrollExt = document.body.scrollTop;
if(document.body.scrollTop > 500 || document.documentElement.scrollTop > 500){
rocket.style.display = "block";
} else{
rocket.style.position = "none";
}
};
let rocketClick = function() {
document.documentElement.scrollTop = 0;
}
.go-to-top{
display: none;
z-index: 10;
position: fixed;
bottom: 40px;
right: 40px;
width: 40px;
height: 40px;
transform: rotate(-45deg);
color: black;
padding: 10px;
text-decoration: none;
-webkit-box-sizing: border-box;
box-sizing: border-box;
}
.go-to-top i{
font-size: 50px;
}
.go-to-top:hover{
cursor: pointer;
text-decoration: none;
}
<!--the rest of markup-->
<div class="rocket">
<a href="#" class="go-to-top">
<i class="fas fa-rocket"></i>
</a>
</div>
<script src="script.js"></script>
<!--closing markup-->
rocket.style.position:none would give your element the css style of position:none. none is not a valid value for the position property.
You can see the position values here -> CSS position
By the look of your code you would need to use display instead of position.
Also, you make a variable scrollExt and you do not use it. Plus, you make a rocketClick function but you do not call it on your element.
window.onscroll = function() {
goTop();
};
const goTop = function() {
const rocket = document.querySelector('.go-to-top');
const scrollExt = document.body.scrollTop;
if (scrollExt > 500 || document.documentElement.scrollTop > 500) {
rocket.style.display = 'block';
} else {
rocket.style.display = 'none';
}
};
const rocketClick = function() {
document.documentElement.scrollTop = 0;
};
main {
height:1500px;
background:red;
}
.go-to-top{
display: none;
z-index: 10;
position: fixed;
bottom: 40px;
right: 40px;
width: 40px;
height: 40px;
transform: rotate(-45deg);
color: black;
padding: 10px;
text-decoration: none;
-webkit-box-sizing: border-box;
box-sizing: border-box;
}
.go-to-top i{
font-size: 50px;
}
.go-to-top:hover{
cursor: pointer;
text-decoration: none;
}
<main></main>
<div class="rocket" onclick=rocketClick()>
<a href="#" class="go-to-top">
rocket icon
</a>
</div>
Suggestions :
Keep using let and const. Do not use var. Also, use const for your functions. You do not change the content of the functions anywhere so you can use const instead of let.
Add an animation(transition) to the scrollTop.

Categories