I'm making a Navbar. Well, it is working correctly (I scroll down and the style changes), but then, when I scroll to the top, the styles stay the same. Is there a way to change styles when I scroll to the top part?
Here's the HTML
<div class="navbar">
<ul>
<li>Home</li>
<li>About us</li>
<li>Contact</li>
</ul>
<span>Visit San Francisco</span>
</div>
Here's the JavaScript:
var body = document.querySelector("body");
var navbar = document.querySelector(".navbar");
var cover = document.querySelector(".cover");
function changeNavbarStyle() {
navbar.classList.add("postConv");
}
function removeNavbarStyle() {
navbar.classList.remove("postConv");
}
body.onscroll = changeNavbarStyle;
Most of modern browsers such as "Firefox", "Opera", "Edge", ... use document.documentElement.scrollTop to detect the position of scroll from top of the page. So maybe if you change your script as follows, it works:
var body = document.querySelector("body");
var navbar = document.querySelector(".navbar");
var cover = document.querySelector(".cover");
function changeNavbarStyle() {
navbar.classList.add("postConv");
if(document.documentElement.scrollTop === 0) {
removeNavbarStyle();
}
}
function removeNavbarStyle() {
navbar.classList.remove("postConv");
}
body.onscroll = changeNavbarStyle;
body {
min-height: 850px;
}
.postConv {
background-color: #c5bdd1;
position: fixed;
top: 0;
left: 0;
width: 100%;
}
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>nav-style</title>
<link rel="stylesheet" href="style.css">
</head>
<body>
<div class="navbar">
<ul>
<li>Home</li>
<li>About us</li>
<li>Contact</li>
</ul>
<span>Visit San Francisco</span>
</div>
<script src="script.js"></script>
</body>
</html>
You can use HTML DOM onScroll event.
So your HTML code would look like:
<body id="body" onscroll="scroll()">
<div class="navbar">
<ul>
<li>Home</li>
<li>About us</li>
<li>Contact</li>
</ul>
<span>Visit San Francisco</span>
</div>
</body>
And in your JavaScript code you will define your scroll() method like:
function scroll() {
var elmnt = document.getElementById("body");
var y = elmnt.scrollTop;
if(y == 0) {
navbar.classList.remove("postConv");
} else {
navbar.classList.add("postConv");
}
}
Related
I am new to JavaScript and using an external file to populate my navigation bar. I would like my navigation tabs to change size/position using my "onTab" class when clicked, and stay that way as long as that navigation tab is supporting the active page. How would the JavaScript go?
I have tried several different onClick and add/remove functions to get this to happen, but apparently I don't know the proper JavaScript series and terms needed for this particular action, yet.
<div id="page-navigator" class="nav-tabs">
<ul class="tabs">
<li class="grow-xs onTab">Tab A</li>
<li class="grow-xs" >Tab B</li>
<li class="grow-xs" >Tab C</li>
<li class="grow-xs" >Tab D</li>
<li class="grow-xs" >Tab E</li>
<li class="grow-xs" >Tab F</li>
</ul>
</div>
EDIT:
I know this raw attempt is hilariously wrong, but I "think" I am looking for something like this:
identify current page url.
get.elementByClassName "tag"
look for class "tag" href that is same as URL
if - class tag is same as page url, add onTab class
$(document).ready(function ($) {
function getURL() {
window.location.href("url")
});
var y = document.getElementsByClassName("tag");
if (x.a[href="window.location.href"]); === y {
toolbar.classList.add('onTab')
}
});
Here is a possible solution, based on your approach:
Any HTML pages A, B, C [ files: page_A.html / page_B.html / page_C.html ]
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>page A </title> <!-- or B / C-->
<script src="navigation.js" defer></script>
<link rel="stylesheet" href="style.css">
</head>
<body>
<h3> this is page A </h3> <!-- or B / C-->
<p>Blah blah bla....</p>
</body>
</html>
JS code: [ file: navigation.js ] (witch use backQuotes)
const myMenu = document.createElement('menu')
;
myMenu.innerHTML = `
<li> go to page A </li>
<li> go to page B </li>
<li> go to page C </li>`
;
document.body.prepend(myMenu)
;
myMenu.querySelectorAll('li > a').forEach(elmA =>
{
if ( elmA.pathname === window.location.pathname )
{
elmA.classList.add('onTab')
}
})
I have also done a CSS: [ file: style.css ]
body {
font-family : Arial, Helvetica, sans-serif;
font-size : 16px;
}
menu {
list-style : none;
padding : 0;
margin : 1rem 0 2rem .2rem;
width : fit-content;
}
menu > li {
width : fit-content;
}
menu > li:not(:first-of-type) {
margin-top : .2rem;
}
menu a {
display : block;
width : 10em;
padding : .2rem .6rem;
background : darkgray;
}
menu a.onTab {
background : coral;
color : darkblue;
cursor : default;
pointer-events : none;
}
menu a:not(.onTab):hover {
background-color: cadetblue;
}
menu a { text-decoration: none; color: black; }
menu a:visited { color: black; }
I made a script that when I click on the container it hides a list. However, what I have been trying to do is that the list should hide when clicking outside the container and not inside. I have been looking for answers but nothing really worked for me as I use classes. Does someone know a solution?
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width" />
<title>Hiding the list</title>
</head>
<body>
<h1>Hiding the list</h1>
<div class="list">Hide the list by clicking outside
<li>Text1</li>
<li>Text2</li>
<li>Text3</li>
</div>
<div class="list">Hide the list by clicking outside
<li>Text1</li>
<li>Text2</li>
<li>Text3</li>
</div>
</body>
</html>
<style>
.list {
width: 50%;
height: 100%;
background-color: #f2f2f2;
}
li {
}
</style>
<script>
function hide_list() {
var children = this.children;
for (let i = 0; i < children.length; i++) {
children[i].style.display = "none";
}
}
document.querySelectorAll(".list").forEach(function (elem) {
elem.addEventListener("click", hide_list);
});
</script>
I am trying to add an active class to my buttons so that when you click on them the hover animation would stay on the active button. It seems like something in my javascript does not follow through with my call to add the active class to whatever element I put it on. pls help thnx ^_^
https://jsfiddle.net/purpkev/pf1vzx2t/7/
HTML:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>Ukiyo Sushi ツ</title>
<link href = "/style.css" type = "text/css" rel = "stylesheet">
<link href="https://fonts.googleapis.com/css?family=Fira+Sans&display=swap" rel="stylesheet">
<script src = "/script.js"></script>
</head>
<body>
<!--<div class = "hero active">
<div class = "hero1">
<div class = "hero2">-->
<header id = "bg">
<nav class = "navbar">
Ukiyo Sushi ツ
<ul>
<li>About us</li>
<li>Menu</li>
<li>Services</li>
<li>Contact</li>
</ul>
</nav>
<div class = "sushiPlatter">
<h2 id = "caption">Chef's Special Sushi Platter</h2>
<div class = "dots">
<button class = "dot" onclick = "imgslider(1)"></button>
<button class = "dot" onclick = "imgslider(2)"></button>
<button class = "dot" onclick = "imgslider(3)"></button>
</div>
View Menu
</div>
</header>
<!--</div>
</div>
</div>-->
<section class = "idkYet">
<div>
<span>hello I am filler content</span>
</div>
</section>
</body>
</html>
CSS:
.dots{
display: flex;
flex-direction: column;
align-self: flex-end;
margin: 0 1em;
}
.dot{
display: inline-block;
cursor: pointer;
height: 15px;
width: 15px;
background-color: transparent;
border: solid 2px white;
border-radius: 50%;
margin: .2em;
transform: scale(.75);
outline-color: white;
}
.active{
transform: scale(1);
opacity: .25;
}
.dot:hover, .dot:hover, .dot:hover{
transform: scale(1);
opacity: .25;
transition: transform 1s ease-in;
transition: opacity .5s;
}
Javascript:
function buttonClick(){
var button = document.getElementsByClassName("dots");
var dot = button.children;
dot[0].classList.add("active");
for(var i = 0; i < dot.length; i++){
dot[i].addEventListener("click", function(){
var active = document.getElementsByClassName("active");
active[0].className = active[0].className.replace("active", "");
this.className += "active";
});
}
}
edit:
I have tried suggestions in the comments but the active class still does not get added to the active button, here is what my code looks like:
function buttonClick(){
var button = document.getElementsByClassName("dots");
var dot = button[0].children;
dot[0].classList.add("active");
for(var i = 0; i < dot.length; i++){
dot[i].addEventListener("click", function(){
var active = document.getElementsByClassName("active");
active[0].className = active[0].className.replace("active", "");
this.className += "active";
});
}
}
document.getElementsByClassName returns array.
Use button[0].children or button = document.getElementsByClassName("dots")[0]
I am not very good at vanilla javascript. I will do the equivalent of jQuery as follows
$('.dots').on('click', '.dot', function(e) {
el = $(this);
el.parents('.dots').find('dot').removeClass('active');
el.addClass('active');
});
Looks like you're adding eventListeners again and again.
Maybe try this approach, where you send the button element to the function using the "this" keyword....
(see fiddle: https://jsfiddle.net/sre1dua9/1/ )
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>Ukiyo Sushi ツ</title>
<link href = "/style.css" type = "text/css" rel = "stylesheet">
<link href="https://fonts.googleapis.com/css?family=Fira+Sans&display=swap" rel="stylesheet">
<script src = "/script.js"></script>
</head>
<body>
<!--<div class = "hero active">
<div class = "hero1">
<div class = "hero2">-->
<header id = "bg">
<nav class = "navbar">
Ukiyo Sushi ツ
<ul>
<li>About us</li>
<li>Menu</li>
<li>Services</li>
<li>Contact</li>
</ul>
</nav>
<div class = "sushiPlatter">
<h2 id = "caption">Chef's Special Sushi Platter</h2>
<div class = "dots">
<button class = "dot" onclick="window.imgslider(this, 1)"></button>
<button class = "dot" onclick="window.imgslider(this, 2)"></button>
<button class = "dot" onclick="window.imgslider(this, 3)"></button>
</div>
View Menu
</div>
</header>
<!--</div>
</div>
</div>-->
<section class = "idkYet">
<div>
<span>hello I am filler content</span>
</div>
</section>
</body>
</html>
Then just track the last button clicked:
var lastDot = null;
window.imgslider = function(elem, x)
{
var bg = document.getElementById("bg");
var dot = document.getElementsByClassName("dot");
var caption = document.getElementById("caption");
switch(x){
case 1:
bg.style.backgroundImage = "-webkit-linear-gradient(rgba(0,0,0,.375), rgba(0,0,0,.375)),url(/img/header.jpg)";
caption.style.marginLeft = "0em";
caption.innerHTML = "Chef's Special Sushi Platter";
break;
case 2:
bg.style.backgroundImage = "-webkit-linear-gradient(rgba(0,0,0,.375), rgba(0,0,0,.375)),url(/img/pokebowl.jpg)";
caption.style.marginLeft = "2em";
caption.innerHTML = "Spring Poke Bowl";
break;
case 3:
bg.style.backgroundImage = "-webkit-linear-gradient(rgba(0,0,0,.375), rgba(0,0,0,.375)),url(/img/ramen.jpg)";
caption.style.marginLeft = "3.75em";
caption.innerHTML = "Miso Ramen";
}
// do dots
if(lastDot){
lastDot.classList.remove("active");
}
elem.classList.add("active");
// store last dot for next click
lastDot = elem;
}
I have a problem with a sidenav which I'm trying to create for one of my projects. My intention is to create a side menu which pushes the content to the right when is opened and when closed the content should move back to the left, sort of a toggle function. For some reason my ternary operator doesn't work as intended.
Here is my snippet:
<!doctype html>
<html lang="en">
<html ng-app="uiBootstrapBlog">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.6.9/angular.min.js"></script>
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.6.9/angular-animate.js"></script>
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.6.9/angular-sanitize.js"></script>
<script src="https://angular-ui.github.io/bootstrap/ui-bootstrap-tpls-2.5.0.js"></script>
<link href="https://netdna.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css" rel="stylesheet">
</head>
<body>
<div ng-controller="navbarCtrl">
<nav class="navbar navbar-inverse navbar-fixed-top">
<div class="container-fluid">
<ul class="nav navbar-nav">
<li style="font-size:30px; cursor:pointer;color:white" ng-click="isCollapsedHorizontal = !isCollapsedHorizontal" ng-model="singleModel" uib-btn-checkbox>☰</li>
</ul>
</div>
</nav>
<div style="position: fixed; width: 230px">
<div class="horizontal-collapse" uib-collapse="isCollapsedHorizontal" horizontal style=" margin-top: 50px !important; min-height: 150px; max-height: 80vh; background: gray; color: black; padding-top: 25px;" >
</div>
</div>
<div style="position: absolute; top: 60px; transition: left .5s;" id="main">grhgerhrehrehre<br>grhgerhrehrehre<br>grhgerhrehrehre<br>grhgerhrehrehre<br>grhgerhrehrehre<br>grhgerhrehrehre<br>grhgerhrehrehre<br>grhgerhrehrehre<br>grhgerhrehrehre<br>grhgerhrehrehre<br>grhgerhrehrehre<br>grhgerhrehrehre<br>grhgerhrehrehre<br>grhgerhrehrehre<br>grhgerhrehrehre<br>grhgerhrehrehre<br>grhgerhrehrehre<br>grhgerhrehrehre<br>grhgerhrehrehre<br>grhgerhrehrehre<br>grhgerhrehrehre<br>grhgerhrehrehre<br>grhgerhrehrehre<br>grhgerhrehrehre<br>grhgerhrehrehre<br>grhgerhrehrehre<br>grhgerhrehrehre<br>grhgerhrehrehre<br>grhgerhrehrehre<br>grhgerhrehrehre<br>grhgerhrehrehre<br>grhgerhrehrehre<br>grhgerhrehrehre<br>grhgerhrehrehre<br>grhgerhrehrehre<br>grhgerhrehrehre<br>grhgerhrehrehre<br>grhgerhrehrehre<br>grhgerhrehrehre<br>grhgerhrehrehre<br>grhgerhrehrehre<br>grhgerhrehrehre<br>grhgerhrehrehre<br>grhgerhrehrehre<br>grhgerhrehrehre<br>grhgerhrehrehre<br>grhgerhrehrehre<br>grhgerhrehrehre<br>grhgerhrehrehre<br>grhgerhrehrehre<br>grhgerhrehrehre<br>grhgerhrehrehre<br>grhgerhrehrehre<br>grhgerhrehrehre<br>grhgerhrehrehre<br>grhgerhrehrehre<br>grhgerhrehrehre<br>grhgerhrehrehre<br>grhgerhrehrehre<br>grhgerhrehrehre<br>grhgerhrehrehre<br>grhgerhrehrehre<br>grhgerhrehrehre<br>grhgerhrehrehre<br>grhgerhrehrehre<br>grhgerhrehrehre<br>grhgerhrehrehre<br>grhgerhrehrehre<br>grhgerhrehrehre<br>grhgerhrehrehre<br>grhgerhrehrehre<br>grhgerhrehrehre<br>grhgerhrehrehre<br>grhgerhrehrehre<br>grhgerhrehrehre<br>grhgerhrehrehre<br>grhgerhrehrehre<br>grhgerhrehrehre<br>grhgerhrehrehre<br>grhgerhrehrehre<br>grhgerhrehrehre<br>grhgerhrehrehre<br>grhgerhrehrehre<br>grhgerhrehrehre<br>grhgerhrehrehre<br>grhgerhrehrehre<br>grhgerhrehrehre<br>grhgerhrehrehre<br>grhgerhrehrehre<br>grhgerhrehrehre<br>grhgerhrehrehre<br>grhgerhrehrehre<br>grhgerhrehrehre<br>grhgerhrehrehre<br>grhgerhrehrehre<br>grhgerhrehrehre<br>grhgerhrehrehre<br>grhgerhrehrehre<br>grhgerhrehrehre<br>grhgerhrehrehre<br>grhgerhrehrehre<br>grhgerhrehrehre<br>grhgerhrehrehre<br>grhgerhrehrehre<br>grhgerhrehrehre<br>grhgerhrehrehre<br>grhgerhrehrehre<br>grhgerhrehrehre<br>grhgerhrehrehre<br>grhgerhrehrehre<br>grhgerhrehrehre<br>grhgerhrehrehre<br>grhgerhrehrehre<br>grhgerhrehrehre<br>grhgerhrehrehre<br>grhgerhrehrehre<br>grhgerhrehrehre<br>grhgerhrehrehre<br>grhgerhrehrehre<br>grhgerhrehrehre<br>grhgerhrehrehre<br>grhgerhrehrehre<br>grhgerhrehrehre<br>grhgerhrehrehre<br>grhgerhrehrehre<br>grhgerhrehrehre<br>grhgerhrehrehre<br>grhgerhrehrehre<br>grhgerhrehrehre<br>grhgerhrehrehre<br>grhgerhrehrehre<br>grhgerhrehrehre<br>grhgerhrehrehre<br>grhgerhrehrehre<br>grhgerhrehrehre<br>grhgerhrehrehre<br>grhgerhrehrehre<br>grhgerhrehrehre<br>grhgerhrehrehre<br>grhgerhrehrehre<br>grhgerhrehrehre<br>grhgerhrehrehre<br>grhgerhrehrehre<br>grhgerhrehrehre<br>grhgerhrehrehre<br></div>
</div>
</body>
</html>
<script>
var uiBootstrapBlog = angular.module('uiBootstrapBlog', ['ngAnimate', 'ngSanitize', 'ui.bootstrap']);
uiBootstrapBlog.controller('navbarCtrl', function($scope) {
$scope.singleModel = false;
var menuSlide = document.getElementById("main");
$scope.singleModel === false ? menuSlide.style.left = "250px" : menuSlide.style.left = "0";
});
</script>
It does not work because the codes gets called only once after the initialisation. Follow these three steps to fix the issue
Define a function and put isCollapsedHorizontal and the last two lines of code inside of it.
Your ternary operator has also an issue. Assign the variable that gets changed to the result of it.
Call the function inside the controller and with the ng-click.
$scope.slideMenu = function() {
$scope.isCollapsedHorizontal = !$scope.isCollapsedHorizontal;
var menuSlide = document.getElementById("main");
menuSlide.style.left = $scope.singleModel ? "250px" : "0";
}
$scope.slideMenu();
<li style="font-size:30px; cursor:pointer;color:white" ng-click="slideMenu()" ng-model="singleModel" uib-btn-checkbox>☰</li>
ul.cars(data-ng-show="$ctrl.hasCars")
li.skill("data-ng-repeat="car in $ctrl.cars")
How can I make my window automatically scroll to the last li when is added each time?
As mentioned in the comment you could use Element.scrollIntoView(), you could use :last-child selector to select the last li.
Here is an example of this in action.
var list = document.querySelector('.list');
var button = document.querySelector('.updateList');
function updateList(){
var number = Math.round(Math.random()*100);
var li = document.createElement('li');
li.textContent = number;
list.appendChild(li);
var lastLi = document.querySelector('.list li:last-child');
lastLi.scrollIntoView();
}
button.addEventListener('click', updateList);
.app{
width: 100vw;
height: 100vh;
}
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width">
<title>JS Bin</title>
</head>
<body>
<button class="updateList">Update List</button>
<div class="app"></div>
<ul class="list">
<li>hello</li>
<li>World</li>
<li>Whats up</li>
</ul>
</body>
</html>
Here is a jsbin of the above code https://jsbin.com/beqovi/edit?html,css,output