how to animate navbar on window scroll - javascript

I'd like to ask if there is a way to use jQuery animate() method to animate horizontal navbar's top property on window scroll.
Here is code I use:
window.addEventListener("scroll", function() {
if (window.scrollY > 200) {
$('#navbar').css({top:"100px"});
}
else {
$('#navbar').css({top:"0px"});
}
},false);
CSS:
#navbar{
top:0;
position:fixed;
transition: top 0.5s;
}
When you scroll down 200px the navbar changes its top position from 0 to 100px;
This works fine, but if I change methods and put .animate instead of .css,
$('#navbar').animate({top:"100px"});
it stops working. Any ideas why?

You can do this with css transition and how you can achieve this is with jQuery addClass instead of css()
DEMO
$(window).on('scroll', function () {
if ($(this).scrollTop() > 200) {
if (!$('.navbar').hasClass('expand')) {
$('.navbar').addClass('expand');
}
} else {
if ($('.navbar').hasClass('expand')) {
$('.navbar').removeClass('expand');
}
}
});
.navbar {
top: 0;
position: fixed;
transition: top 0.5s;
}
.navbar.expand {
top: 100px;
}

Scroll event listener execute every time when you scroll page on every pixel, and animate starts from begin. This gives unexpected results.
http://jsfiddle.net/29tkxawy/
You should be leave as is (with .css()).
Or like this without css transition:
http://jsfiddle.net/29tkxawy/10/

Related

How to hide menu for mobiles by default? Using Javascript

I have a website with side-bar menu. Menu is by default visible. If i click close-btn. Menu is hidden. That works
I would like make menu by default visible for desktops and by default hidden for mobiles.
.side-bar {
background: #1b1a1b;
backdrop-filter: blur(15px);
width: 250px;
height: 100vh;
position: fixed;
top: 0;
z-index: 50;
left: 0px;
overflow-y: auto;
transition: 0.6s ease;
transition-property: left;
}
.side-bar.non-active {
left: -250px;
}
.side-bar.active {
left: 0px;
}
The window.innerWidth < 850 works but i'm not sure if there is something better. 850px i use for #media queries.
$(document).ready(function () {
//jquery for toggle sub menus
$(".sub-btn").click(function () {
$(this).next(".sub-menu").slideToggle();
$(this).find(".dropdown").toggleClass("rotate");
});
//jquery for expand and collapse the sidebar
if (window.innerWidth > 850) {
$(".close-btn").click(function () {
$(".side-bar").addClass("non-active");
$(".menu-btn").css("visibility", "visible");
});
$(".menu-btn").click(function () {
$(".side-bar").removeClass("non-active");
$(".menu-btn").css("visibility", "hidden");
});
}
else {
$(".side-bar").css("left", -250);
$(".close-btn").click(function () {
$(".side-bar").addClass("active");
$(".menu-btn").css("visibility", "visible");
});
$(".menu-btn").click(function () {
$(".side-bar").removeClass("active");
$(".menu-btn").css("visibility", "hidden");
});
}
});
The issue is propably in $(".side-bar").css("left", -250); because in the DOM i can see it as inline style and after click nothing happen. Only .menu-btn disappers.
Is there another way how to set "reverse" logic for mobiles please? Or maybe just easy fix this i hope little bug?
I tried set oposite style for left: -250px; to left:0; via following logic but without any positiv result..
Use this instead:
if (window.matchMedia('(max-width: 850)').matches) { ... }
else { ... }
This uses css media query in JavaScript without any frameworks.

how to change the color of the navbar after scrolling

I want my navbar to be transparent, but when the user scrolls a bit I want it to change to a solid color and I am using bootstrap for the navbar, I have done the code that is needed with javascript.
I had this javascript in my HTML file, but it doesn't seems to work and I don't really know why
<script>
var myNav = document.getElementById("mynav");
window.onscroll = function() {
use strict";
if (document.body.scrollTop >= 100) {
myNav.classList.add("scroll");
} else {
myNav.classList.remove("scroll");
}
};
</script>
and I have also added the CSS code.
.scroll {
background-color: transparent !important;
transition: all 0.5s ease-in;
}
I don't know why it doesn't work, it is not displaying any errors, I have also manually put the class and it worked so the problem is from the js code and not the CSS.
Use scrollY property of Window object.
See the Snippet below:
var myNav = document.getElementById("mynav");
window.onscroll = function() {
if (window.scrollY >= 100) {
myNav.classList.add("scroll");
} else {
myNav.classList.remove("scroll");
}
};
.scroll {
background-color: transparent !important;
transition: all 0.5s ease-in;
}
.main-container{
height: 1000px;
}
#mynav{
position: fixed;
background-color: gray;
height: 50px;
margin:0 auto;
top: 0;
bottom:0;
line-height: 50px;
padding:5px;
width: 100%;
}
<div class="main-container">
<div class="mynav" id="mynav">
Hello World! this is mynav
</div>
</div>
Try using window.scrollY instead of document.body.scrollTop.
if (window.scrollY >= 100)
You can also use document.documentElement.scrollTop. It's the html element that actually scrolls, not the body. Typically document.body.scrollTop will always be 0.

Append divs from bottom with scroll - Chat application example

I'm looking to append divs from the bottom. At a certain point, the vertical scroll should kick in so you can view divs that were appended earlier on. I'm trying to replicate a typical chat application and how messages come from the bottom. Here's the codepen...
http://codepen.io/jareko999/pen/yaQmgk
Before I put the code, I'll explain a couple of workarounds I've tried thus far. The pen currently has the container absolutely positioned with a bottom of 0. The problem, which is a pain, is that once the height goes beyond the height of the viewport, it won't scroll. This is the problem with the absolute positioning workaround.
Another workaround I've tried is doing a height of 100vh and display of flex with justify-content flex-end so the columns start at the bottom. The problem with this is that the scroll will always start from the top. I believe the solution is a scroll function that I've created to scroll to the bottom every time a new div is added. Would this be the best method? The key here is that I want to be able to scroll up to the older divs but have the newer divs start from the bottom. Think of a typical chat application like slack or messages or similar.
HTML
<button onclick="myFunction()">Hey here's a box</button>
<div id="container">
</div>
CSS
body {
margin: 0;
width: 100%;
}
button {
position: fixed;
z-index: 10;
}
#container {
position: absolute;
bottom: 0;
width: 100%;
}
#box {
width: 100%;
background: tomato;
opacity: 0;
height: 100px;
transition: .2s;
}
#box:last-child {
opacity: 1;
height: 0;
animation: .2s height linear forwards;
}
#keyframes height {
to {
height: 100px;
}
}
#box:nth-last-child(2) {
opacity: .8;
}
#box:nth-last-child(3) {
opacity: .6;
}
#box:nth-last-child(4) {
opacity: .4;
}
#box:nth-last-child(5) {
opacity: .2;
}
JS
function myFunction() {
var box = document.createElement("div");
box.setAttribute("id", "box");
var container = document.getElementById('container');
container.appendChild(box);
// window.scrollTo(0, document.body.scrollHeight || document.documentElement.scrollHeight);
}
Is there a better solution than the function I've created to scroll to the bottom? Much appreciated.
Ok, so after messing around with some JS, I figured it out. I love when that happens...
Here's the codepen...
http://codepen.io/jareko999/pen/yaQmgk
I created a setInterval function for scrolling to the bottom.
var myVar = setInterval(function(){
window.scrollTo(0, document.body.scrollHeight || document.documentElement.scrollHeight);
}, .1);
However, since this interval runs every .1 seconds, I need to kill it in order to scroll around the divs above (like old chat messages), but I want the animation (of the new div coming in) to finish. So, I created a setTimeout function to kill the setInterval function at 200 ms.
setTimeout(function(){
clearInterval(myVar);
}, 200);

When scrolling to top of div hide another div

this is what I have so far:
$("#main").each(function() {this.scrollTop = this.scrollHeight;
if ($(this).scrollTop()>0)
{
$('#navigation').addClass("nav-hide");
}
else
{
$('#navigation').addClass("nav-normal");
}
});
So basically, I am trying to figure out when you scroll to the top of a div it will hide the navigation bar. So you could read the div without the navigation bar over it. Any ideas? Thanks.
Here's my JSFiddle: https://jsfiddle.net/qb15p5g7/3/
You need to use jquery's window scroll function and not each function unless you are going to have more than one section that you need to hide the navigation on there is no reason to use each and I'm assuming that you don't because you are using an id for #main and Id's are supposed to be unique. Also you don't need to add more than one class you can just add the class and remove the class. So if im correct in assuming that you don't have more than one section that you need to hide the nav in multiple instances on your page then your code should look something like this:
$(window).scroll(function() {
if ($(this).scrollTop() >= $('#main').offset().top) {
$('#navigation').addClass("nav-hide");
}else {
$('#navigation').removeClass("nav-hide");
}
});
And you will just add the nav-hide class and then remove it when scrolling back up.
Here is a fiddle of this working JSFiddle Demo
I assume this is what you are looking for if not let me know so I can edit my answer.
The $(window).scroll() method executes on scroll change of the window. You can use it to hide your #navigation id selector
$(window).scroll(function() {
if ($(this).scrollTop() > 100) {
$('#navigation').fadeIn();
} else {
$('#navigation').fadeOut();
}
});​
JSFiddle here
See the jQuery documentation for .scroll() here
function scrollpos() {
if (window.scrollY<document.getElementById('header').clientHeight) {
document.getElementById('navigation').style.display = 'block';
} else {
document.getElementById('navigation').style.display = 'none';
}
}
#navigation {
width: 100%;
height: 50px;
background-color: #586e75;
position: fixed;
z-index: 1000;
transition: transform 200ms ease;
}
header,
section {
height: 100vh;
width: 100%;
position: static;
}
header {
background: #4f4244;
}
section {
background: #222222;
}
.nav-normal {
transform: translateY(0%);
}
.nav-hide {
transform: translateY(-100%);
}
<body onscroll="scrollpos()">
<div id="navigation"></div>
<header id="header"></header>
<section id="main"></section>
</body>
do u need something like this?#Steboney

Adding Flag to javascript (hasClass)

So I have images where when you click they expand (via css). However, I also want it so that when you click, the image will be pushed to the top of the page. From what I've heard is that if I use the toggleClass function then I need to have a flag before I initiate the animation, however, I can't seem to get it to function right.
$("img").on("click", function (){
$(this).toggleClass("selected");
if ($("img").hasClass("selected")) {
found = true;
}
var timeout = setTimeout(function () {
$('html,body').animate({
scrollTop: $('.selected').offset().top - 60
}, 100);
}, 5);
});
You should consider using CSS3 transition rather than monitoring using timers. You set transition to transition the top property. Then have the selected class alter the top by toggling it. The change will cause the animation to kick in. See this example:
HTML:
<div class="bar">weee!</div>
CSS:
.bar{
width: 100px;
height: 100px;
background: red;
position: relative;
transition: top 1s ease 0;
top: 100px;
}
.bar.selected{
top : 0px;
}
JS:
$('.bar').on('click',function(){
$(this).toggleClass('selected');
});

Categories

Resources