JavaScript on scroll to shrink logo AND menu bar - javascript

I'm working on a WordPress site, I have used the following JavaScript code to shrink the logo on scroll:
logo has id #logoid
CSS
.logoclass {width:100%;
transition: width 0.5s linear;}
.scroll {margin-top:-10px;
width:55%;
transition: width 0.5s linear;}
Javascript
<script type="text/javascript">
window.onscroll = () => {
const nav = document.querySelector('#logoid');
if(this.scrollY <= 250) nav.className = 'logoclass'; else nav.className =
'scroll';};
</script>
Now this works fine to simply shrink the image and restore size.
Now I have two problems:
Since I'm using WordPress plugins, there are many attributes applied
to the logo internally and are not in my .logoclass or in the
.scroll so these attributes get removed once I scroll and do not
get applied again. Is there a way to :
a) On scroll down ONLY change size while keeping other attributes
intact
b) On scroll up revert to initial settings completely (remove new
class)
My second question is, I want to also modify the menu bar size on scroll, but I cannot use the same code twice because it seems to only accept the code written last. Possibly because windows.onscroll gets added twice. Any way to incorporate both?

For #1, you should use the classList property to add or remove classes.
For #2, you should be able to add whatever changes you want in the same if statement.
window.onscroll = () => {
const nav = document.querySelector('#logoid');
const menu = document.querySelector('#menubar');
if (this.scrollY <= 250) {
nav.classList.remove('scroll');
menu.classList.remove('someclass');
} else {
nav.classList.add('scroll');
menu.classList.add('someclass');
}
};
.logoclass {
width: 100%;
transition: width 0.5s linear;
}
.scroll {
margin-top: -10px;
width: 55%;
transition: width 0.5s linear;
}
body {
height: 1000px;
}
#logoid {
position: absolute;
top: 0px;
background: red;
height: 25px;
}
<div id="logoid" class="logoclass"></div>
<div id="menubar" class="menuclass"></div>

If you add a global scroll class to your body tag you won't have to change your JavaScript if you want to change more things on scroll, only your CSS.
window.onscroll = () => {
const body = document.querySelector('body');
if (this.scrollY <= 250) {
body.classList.remove('scroll');
} else {
body.classList.add('scroll');
}
};
.logoclass {
width: 100%;
transition: width 0.5s linear;
}
.scroll .logoclass, .scroll .menuclass {
margin-top: -10px;
width: 55%;
transition: width 0.5s linear;
}
body {
height: 1000px;
}
#logoid {
position: absolute;
top: 0px;
background: red;
height: 25px;
}
<div id="logoid" class="logoclass"></div>
<div id="menubar" class="menuclass"></div>
If you wan't to run multiple functions on scroll you should use addEventListener.
window.addEventListener('scroll', function() {
doSomething();
});
window.addEventListener('scroll', function() {
doSomeOtherThing();
});

Related

css/ js: How to display on click on a button the rest of the paragraph text while being responsive?

I'm trying to display the rest of my text with an animation on the height when you click on a button, I managed to do it but the problem is that I can't find a way to make it responsive.. Basically I display a height: 30px and an overflow: hidden.
And I toggle on a class that contains a height: 300px , it looks good in the mobile version but if I increase the resolution of the page the height will become too small.
I thought there might be a way to adapt the height with the width of the screen, or maybe there is another way to hide part of the text?
Below is the code:
Scss:
.about__body{
#include displayFlex($direction: column, $align-item: center);
gap: 20px;
&-content {
height: 60px;
overflow: hidden;
transition: all 400ms ease-in-out;
}
}
.about__body-content-show {
transition: all 400ms ease-in-out;
height: auto;
}
JS:
let btnAbout = document.getElementById("btn--about")
let contentAbout = document.querySelector(".about__body-content")
const onClickShow = () => {
btnAbout.addEventListener('click', (e) => {
e.preventDefault()
contentAbout.classList.toggle('about__body-content-show')
})
}
onClickShow()
You basically can use JS to achieve this and make your container same height as your content
document.getElementById('expand').addEventListener('click', function() {
document.querySelector('.content-holder').style.height = document.querySelector('.content').offsetHeight + 'px';
document.querySelector('.content-holder').classList.toggle('collapsed');
});
a working fiddle: https://jsfiddle.net/sdjhetq1/

How to get a css transition to not start until scrolled into a specific div

I am running into some issues trying to get a css transition/sequence to start once I scroll over its parent div. I have done this with javascript functions, just never a css transition.
Right now my image will not even show, let alone start at the sequence.If I comment out the javascript the sequence plays as normal.
How can I get the css transitions to start when I get into the parent div section1?
I put a jsfiddle of this in the comments as it is easier to see this.
/*$("#think").hide();
//init scrolling event heandler
$(document).scroll(function() {
var docScroll = $(document).scrollTop(),
boxCntOfset = $("#section1").offset().top - 100;
//when rich top of boxex than fire
if (docScroll >= boxCntOfset) {
$("#think").fadeIn(200)
} else {
$("#think").fadeOut(200)
}
})*/
//Scroll for think images
/*$("#think").hide();
$(function() {
var oTop = $('##section1').offset().top - window.innerHeight;
$(window).scroll(function() {
var pTop = $('body').scrollTop();
console.log(pTop + ' - ' + oTop);
if (pTop > oTop) {
$("#think").fadeIn(200)
}
});
});*/
#red {
width: 100%;
height: 700px;
background:red;
}
#section1 {
width: 100%;
height: 600px;
background:blue;
}
#think {
/*opacity: 0;*/
margin-left: 200px;
width: auto;
height: 500px;
-webkit-animation-name: think;
animation-name: think;
-webkit-animation-duration: 8s;
animation-duration: 8s;
-webkit-animation-direction: normal;
animation-direction: normal;
-webkit-animation-fill-mode: forwards;
animation-fill-mode: forwards;
/*min-height: 500px; min-width: 500px;*/
background-repeat: no-repeat;
/*background-size: 100% auto;*/
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>
<div id="red"></div>
<div class="section" id="section1">
<div id="section1-right-container">
<div id="think"></div>
</div>
</div>
You can use the jquery.visible plugin to easily determine if the element is in the viewport: http://www.jsdelivr.com/projects/jquery.visible
Next you will need to determine if is visible in a window scroll function and add a css class that holds the animations:
$(window).on("scroll", function(){
// Determine if the element is in the viewport
if($('.body-main').visible(true)) {
$('.body-main').addClass("think");
}
});
JSfiddle Example: https://jsfiddle.net/Zachary1748/tqh00p9n/
You can use IntersectionObserver object like I show below so when your div element comes into view you can add a class or remove a class:
const observer = new IntersectionObserver(elements => {
elements.forEach( entry => {
// if the element is present
if(entry.isIntersecting){
removableClass.classList.add('class-to-add');
return;
}
// if not then remove the class
removableClass.classList.remove('class-to-remove');
})
})
And to observe the division:
observer.observe(document.querySelector('.any-class'));
And remember that if you want to do some transition then always put the class which shows the content and then remove it afterwards because even if the JS fails to load your content it would still be displayed.

Animating height property :: HTML + CSS + JavaScript

I have noticed this 'issue' lately when trying some stuff.
Say I want to create a drop-down menu or an accordion.
This is my HTML:
<div class="wrapper" onclick="toggle()">
I want to be animated!
<div class="content">
Was I revealed in a timely fashion?
</div>
</div>
Stylesheets:
.wrapper {
background: red;
color: white;
height: auto;
padding: 12px;
transition: 2s height;
}
.content {
display: none;
}
.content.visible {
display: block;
}
JavaScript:
function toggle () {
var content = document.getElementsByClassName('content')[0];
var test = content.classList.contains('visible');
test ? content.classList.remove('visible') :
content.classList.add('visible');
}
I am trying to achieve a nice, smooth animation when we toggle the state of the content. Obviously this does not work. Anyone can explain to me why it does not work and how to fix it? Many thanks.
Link to the JSFiddle.
First things first, some CSS properties CANNOT be transitioned, display is one of them, additionally only discrete values can be transitioned, so height: auto cannot as well.
In your case the problem is with height: auto, while there are a few hacks for doing this, if you are just showing and hiding stuff, why not add, and use jQuery's toggle instead?
$(".content").toggle("slow");
jsFiddle
--EDIT (without jQuery)--
Because it's the auto that is giving us problems, we can use javascript to replace auto with a value in pixels and then use the css transition normally, if your content doesn't have a scroll, we can easily take that value from the scrollHeight property:
function toggle () {
var content = document.getElementsByClassName('content')[0];
var test = content.classList.contains('visible');
console.log(test);
if (test) {
content.classList.remove('visible')
content.style.height = "0px";
} else {
content.classList.add('visible');
content.style.height = content.scrollHeight + "px";
}
}
Css
.wrapper {
background: red;
color: white;
height: auto;
padding: 12px;
transition: 2s height;
}
.content {
height: 0px;
display: block;
transition: 2s height;
overflow: hidden;
} /* totally removed .content.visible */
jsFiddle

I can't get my navigation to change on scroll

I know it is a repeat question, but I am trying to get my navigation bar to change styling using JavaScript/jQuery/CSS by making jQuery add and remove classes depending on the position of the scrollbar, yet with no prevail. I am a huge noob with jQuery. Could someone tell me if these is something wrong with my code. I have searched for hours and I can't find and error. Here is a working example: http://codepen.io/anon/pen/QbWOJv
And here is my code:
// on scroll,
$(window).on('scroll',function(){
// we round here to reduce a little workload
stop = Math.round($(window).scrollTop());
if (stop > 50) {
$('.nav').addClass('passed-main');
} else {
$('.nav').removeClass('passed-main');
}
.nav
{
background-color: #000000;
opacity: 0.3;
width: 100%;
height: 40px;
position: fixed;
top: 0;
z-index: 2000;
transition: all 0.3s;
}
.nav.past-main
{
background-color: #ffffff;
opacity: 1;
}
<div class="nav">
</div>
Perhaps the example is something that you want to achieve, and when you try it with your code above, it's not working.
Here's the problem with your code in the snippet:
You forgot to close the function
// on scroll,
$(window).on('scroll',function(){
// we round here to reduce a little workload
stop = Math.round($(window).scrollTop());
if (stop > 50) {
$('.nav').addClass('passed-main');
} else {
$('.nav').removeClass('passed-main');
}
}); // You forgot to close the function here
You add/remove class passed-main while in your CSS you're using class selector .nav.past-main
Your window doesn't have any scrollbar, so you need to add this to the CSS to test if it works
body {
height: 1500px;
}
You forgot to include the jQuery in the Snippet.
Here's the working updated snippet
// on scroll,
$(window).on('scroll', function () {
// we round here to reduce a little workload
stop = Math.round($(window).scrollTop());
if (stop > 50) {
$('.nav').addClass('past-main');
} else {
$('.nav').removeClass('past-main');
}
});
.nav {
background-color: #000000;
opacity: 0.3;
width: 100%;
height: 40px;
position: fixed;
top: 0;
z-index: 2000;
transition: all 0.3s;
}
.nav.past-main {
background-color: #ffffff;
opacity: 1;
}
body {
height: 1500px;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.10.1/jquery.min.js"></script>
<div class="nav"></div>

Dock a div to left of window and clicking again to original position

I have a web page that has three section i.e. Header , Mid, Footer.
In Mid div it is again divided into two parts i.e. leftdiv and rightdiv. Leftdiv has vertical menu and right div is for content holder for the respective page.
Now i want to dock leftdiv to left of the window screen on button click and when user again click of the same button the leftdiv should set as original position.
ex: if left and right div area has respectively 30 : 70 % area of main div. when i click on button the left and right div area should like 10:90 % and clicking again both div gets their original ratio.
var checker = new Boolean();
checker = true;
if (checker = true) {
$("#Test").click(function() {
$('.left-wrap').animate({
left: "10%"
}, 400);
checker = false;
});
}
if (checker != true) {
$("#Test").click(function() {
$('.left-wrap').animate({
left: "30%"
}, 400);
checker = true;
});
}
Any help will be appreciated.Thanks in advance
Since you tagged jquery in your question:
HTML code
<div class="toggle left">
Menu
</div>
<div class="toggle right">
Page contents
</div>
<button id="switch">Big monster!</button>
CSS code
div.toggle {
float: left;
padding: 20px;
box-sizing: border-box;
}
div.left {
width: 30%;
background-color: #f00;
}
div.right {
width: 70%;
background-color: #0f0;
}
div.left.switch {
width: 10%;
}
div.right.switch {
width: 90%;
}
Javascript code
$(document).ready(function () {
$('#switch').on('click', function () {
$('div.toggle').toggleClass('switch');
});
});
See it in action: http://jsfiddle.net/9xr46zqt/
EDIT
To animate, use CSS transition property on the divs:
div.toggle {
transition: width 0.25s ease-in-out;
}
See updated fiddle with animation: http://jsfiddle.net/9xr46zqt/1/
If course, you can specify anything in both the .switch and non-switched classes. If you want to animate those as well, list their properties in the transition, like: transition: width, left, color 0.25s ease-in-out, or use transition: all 0.25s ease-in-out.

Categories