Smooth transition between display none and flex jQuery - javascript

I am creating a little menu on a side, with HTML, CSS and Javascript, and I want it to fade in when the user scrolled under the header. This was working perfectly well until I tried to improve the responsive part of my website design.
I changed the menu from display: block; to display: flex; since screen size can change and I want all the lines of my menu to always fill the whole menu. I just changed my code a little bit in the .js script like so:
$(document).scroll(function() {
var y = $(this).scrollTop();
if (y > 600) {
$('#menu').css('display','flex');
} else {
$('#menu').css('display','none');
}
}
The problem is that the transition is not smooth anymore. I used fadeIn() and fadeOut() methods from jQuery to do so with display: block;, but I don't have the same fading effect with the direct .css method.
I already tried those things:
Add a transition: 1s; in my #menu id in CSS. Didn't fix it.
#menu {
z-index : 3;
position : fixed;
display: none;
flex-direction : column;
justify-content : space-around;
width : 15%;
height : 50%;
right : 1.5%;
top : 20%;
font-size : 24px;
transition : 3s;
}
Keep the .fadeIn() and .fadeOut() methods, and add the .css changes after those. Didn't fix it.
$(document).scroll(function() {
var y = $(this).scrollTop();
if (y > 600) {
$('#menu').fadeIn();
$('#menu').css('display','flex');
} else {
$('#menu').fadeOut();
}
}
I don't know what else I could try. I searched for various solutions, but most of them are talking about the .css method itself, not the fading effect I am looking for.

i haven't tested,but you try to 'flag' that makes (document).scroll run once.
because your code, case y =700 then do $(document).scroll run, case y=701, case y=702???
var flag=false;
$(document).scroll(function() {
var y = $(this).scrollTop();
if (y > 600 && flag==false) {
$('#menu').fadeIn();
$('#menu').css('display','flex');
flag=true;
} else if(y<=600 && flag==true) {
flag=false;
$('#menu').fadeOut();
}
}

Related

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);

Can't hide fixed menu using media queries

I have a horizontal menu that sticks to the top of web browser after you scroll past it. To make it happen i'm using javascript (jquery). Now i want to hide that menu and show mobile menu at certain resolution, but when i give "display: none" to menu classes, it only hides original menu.
If i set .original or .menu to "display:none" it hides original static menu, and fixed menu sticks to the top of web browser immediately (you don't have to scroll).
Setting .cloned to "display:none" doesn't do anything.
How to get rid of that fixed menu ?
Script:
<script>
// Create a clone of the menu, right next to original.
$('.menu').addClass('original').clone().insertAfter('.menu').addClass('cloned').css('position','fixed').css('top','0').css('margin-top','0').css('z-index','500').removeClass('original').hide();
scrollIntervalID = setInterval(stickIt, 10);
function stickIt() {
var orgElementPos = $('.original').offset();
orgElementTop = orgElementPos.top;
if ($(window).scrollTop() >= (orgElementTop)) {
// scrolled past the original position; now only show the cloned, sticky element.
// Cloned element should always have same left position and width as original element.
orgElement = $('.original');
coordsOrgElement = orgElement.offset();
leftOrgElement = coordsOrgElement.left;
widthOrgElement = orgElement.css('width');
$('.cloned').css('left',leftOrgElement+'px').css('top',0).css('width',widthOrgElement).show();
$('.original').css('visibility','hidden');
} else {
// not scrolled past the menu; only show the original menu.
$('.cloned').hide();
$('.original').css('visibility','visible');
}
}
</script>
CSS:
#media screen and (max-width:960px){
.cloned {
display: none;
}
.original {
display: none;
}
.menu {
display: none;
}
#navi {
display: none;
}
#content {
width: 90%;
}
}
EDIT:
jsfiddle: https://jsfiddle.net/765kadoj/3/
The reason it is happening is because your javascript is overriding your css after it has been set. You have two options:
You need to write some javascript to change the css to display: none for the .cloned class when the screen is smaller than 960px.
You can use the !important override, which would look like this:
.cloned { display: none !important; }
However, I would strongly suggest using option 1, since the !important override typically isn't the best practice. For more information on !important, see this article.

Sticky navigation bar - not working

Question
I want the navBar to stick conditionally on scroll. However there are bugs I can not quite diagnose, as I am new to jQuery. What is preventing the nav bar from sticking conditionally on scroll?
The jQuery in the jsfiddle below will not run correctly, and after trying for awhile to make it work, I cannot seem to make it run. I've looked at other examples of this but I'd rather not change the jQuery entirely until I know the reason that my code does not work. I will not link the HTML as it full of Lorem Ipsum test text body. It is found in the JSFiddle link.
What is the error in the javascript that isn't making the navBar apply the sticky class?
Javascript
var navTop = $(".nav").offset().top;
var stickyNav = function(){
if ($(window).scrollTop() >= navTop){
$(".nav").addClass(".sticky")
} else {
$(".nav").removeClass(".sticky")
}
};
stickyNav();
$(window).scroll(function(){
stickyNav();
};
CSS
* {
margin: 0;
box-sizing: border-box;
}
.mainHeader {
width: 100%;
height: 20%;
background-color: rgb(62, 65, 66);
text-align: center;
font-family: "Helvetica Nue";
}
.navigation {
width 100%;
height 10%;
background-color: rgb(89, 127, 143);
position: relative;
}
.sticky {
position: fixed;
}
https://jsfiddle.net/11u1bj5j/
You have some bugs in your js code. Firstly, .nav should be nav since your <nav> element has a class of navigation. So, we'll grab it by the tag name instead. Secondly, .addClass() and .removeClass() don't need the period before the class name.
Here's the updated javascript:
var navTop = $("nav").offset().top;
var stickyNav = function(){
if ($(window).scrollTop() >= navTop){
$("nav").addClass("sticky");
} else {
$("nav").removeClass("sticky");
}
};
stickyNav();
$(window).scroll(function(){
stickyNav();
});
Here's an updated fiddle.
first of all you are adding/removing classes wrongly with jquery should be
.addClass("sticky") / .removeClass("sticky")
same with nav selection, there were some other small css problems too
here is working jsfiddle

Show a hidden div when the user scrolls down the page

I have a navbar that sticks to the top of the page when you scroll past it.
When this navbar is fixed to the top of the page, I would like a logo to appear.
The logo is inside the div #navlogo.
I currently have #navlogo set to display: none. I am thinking that when you scroll past 100px its display will need be set to display block or something similar.
I have tried a few things but i'm not very good at java and had no luck.
You can check out the JSFIDDLE here
This is the script I'm using to set my navbar to fixed
$(window).scroll(function() {
var nav = $('#custom-bootstrap-menu');
var body = $('body');
var top = 100;
if ($(window).scrollTop() >= top) {
nav.addClass('navbar-fixed-top');
body.addClass('padding-fifty');
} else {
nav.removeClass('navbar-fixed-top');
body.removeClass('padding-fifty');
}
});
and a little css
#logo {
height: 100px;
}
.padding-fifty {
padding-top: 50px;
}
#navlogo {
display: none;
}
As you can see it sets the nav to fixed, and compensates the page offset by adding 50px. I need something here that will set #navlogo to visible. Can anyone offer some assistance?
Thanks so much for your help!
You can set the css display property in your Javascript:
var logo = $('div#navlogo');
logo.css('display', 'block');
For example: https://jsfiddle.net/gx25ospo/3/
Try adding this style to your CSS at last:
.navbar-fixed-top #navlogo {
display:block;
}
Try this https://jsfiddle.net/gx25ospo/4/
.navbar-brand {
display: none;
}
.visible {
display: block;
}
JS
if ($(window).scrollTop() >= top) {
nav.addClass('navbar-fixed-top');
body.addClass('padding-fifty');
$('.navbar-brand').addClass('visible');
} else {
nav.removeClass('navbar-fixed-top');
body.removeClass('padding-fifty');
$('.navbar-brand').removeClass('visible');
}

how to stop header from scrolling at some point and make it fixed

I have a header, in which i put my h1 and h2 headings at top. The problem is that header scrolls along the scroll bar which is of course normal but i want to fixed it at some point when all the headings on header scroll away. At this point I want header to stop and stays fixed.
I already tried fixed position but of course it fixed heading as well which exactly I don't want.
I also tried this JavaScript but no luck.
JavaScript
$(window).scroll(function() {
var _height = 120 - (120 * $(this).scrollTop() / $('body').height());
if (_height >= 80) {
$('.header_container').height(_height);
}
});
and here qre my HTML and CSS codes respectively.
HTML
<div class="header_container" id="header_container">
<div id="header_titles">
<h1 class="homepage-heading">Browse</h1>
<h2 class="homepage-heading-subtle">GENRES & MOODS</h2>
</div>
</div>
CSS
#header_container {
background-color: black;
width: 100%;
height: 120px;
top: 0;
left: 0;
right: 0;
}
#header_titles {
position: absolute;
width: 100%;
font-size: 35px;
text-align: center;
padding-top: 10px;
}
So, let me see if I get this...you want your header to be scrolled normally with the page until a certain point where it becomes fixed?
EDIT
Ok, well, you could determine the element on the page that you want the position to be triggered at. Like, the top of a certain paragraph, and use that position in your condition.
var condition = $(element).offset().top;
if($(window).scrollTop > condition) { //add a fixedClassName } else { remove the fixedClassName }
and have header.fixedClassName have those proprieties ( with position fix, top 0 and width: 100% to your header etc). Be sure to add and remove a class on the body that gives it padding-top with the height of your displaced header.
Used some similar effect here http://goodmen.se/ after a point the logo shows up in the header, then there's a background change. You do something similar with your position.
EDIT 2
Here's an example fiddle http://jsfiddle.net/Corsico/vpskd8hd/
So you want a sticky header?
In your javascript create a code:
var $header_container = $('#header_container');
var header_height = $header_container.outerHeight(true);
if($(window).scrollTop() < header_height){
$header_container.removeClass('sticky');
} else{
$header_container.addClass('sticky');
}
$(window).on('scroll', function(){
if($(window).scrollTop()< header_height){
$header_container.removeClass('sticky');
} else{
$header_container.addClass('sticky');
}
});
This will add a sticky class to your header, and then you can set the header to be fixed:
.sticky{
position:fixed;
top:0;
left:0;
width:100%;
display:block;
}
This should do it. When you scroll pass the height of the header, you'll get the 'sticky' class, if not, you'll remove the sticky class...

Categories

Resources