JavaScript to change CSS dynamically when scrolling - javascript

I want to change some css properties when scrolling.
This worked with jQuery and I can't make it work using JavaScript.
This is the function that reads and set CSS properties:
function parallel_height_js(){
let scroll_top = window.scrollY;
console.log('scroll top = ',scroll_top)
let header_height = document.getElementsByClassName("sample-header-section")[0].clientHeight;
console.log('Header height = ',header_height)
document.getElementsByClassName("text-section")[0].style.marginTop = header_height;
console.log('text margin top = ',document.getElementsByClassName("text-section")[0].style.marginTop)
document.getElementsByClassName("sample-header")[0].style.height = header_height - scroll_top;
console.log('header height = ',document.getElementsByClassName("sample-header")[0].style.height)
}
Afterwards, I execute the following to execute the function at scrolling or resizing:
parallel_height_js();
window.onscroll = parallel_height_js;
window.onresize = parallel_height_js;
In the browser console I get this from console.log:
scroll top = 8
Header height = 517
text margin top =
header height =
I checked that I am accessing the right elements when trying to set the CSS value, but this CSS value is not changing.

The error was because I didn't add 'px' string when setting new CSS values.
So, the js code would be:
import './style.css'
function parallel_height_js(){
let scroll_top = window.scrollY;
let header_height = document.getElementsByClassName("sample-header-section")[0].clientHeight;
document.getElementsByClassName("text-section")[0].style.marginTop = header_height+'px';
document.getElementsByClassName("sample-header")[0].style.height = (header_height - scroll_top)+'px';
}
parallel_height_js();
window.onscroll = parallel_height_js;
window.onresize = parallel_height_js;
HTML:
<header>
<div class="sample-header">
<div class="...">
<input type="checkbox" id="menu" />
<label for="menu"></label>
<div class="menu-content">
<ul>
<li>Contact </li>
<li>About Us </li>
</ul>
</div>
</div>
<div class="sample-header-section">
<h1>...</h1>
<h2>...</h2>
</div>
</div>
</header>

Related

How to set multiple elements style via getBoundingClientRect()

I am trying to set elements (children of a container with transform) to fixed position relative to the viewport. I'm attempting to find each of them, and assign to a variable via getBoundingClientRect(), then define style properties from that variable.
<div>
<div class="preview-container">
<div>
<!-- Image -->
</div>
</div>
</div>
<div>
<div class="preview-container">
<div>
<!-- Image -->
</div>
</div>
</div>
<!-- more -->
JS v1
$('.preview-container').each(function(el) {
preview = this.getBoundingClientRect();
console.log(preview);
preview.style.position = "fixed";
preview.style.top = "0";
preview.style.left = "0";
});
This works without the three style lines and console displays all of the .preview-container elements correctly. Adding the style lines produces errors about those style properties not being defined:
jQuery.Deferred exception: Cannot set properties of undefined (setting 'position')
Uncaught TypeError: Cannot set properties of undefined (setting 'position')
I don't understand that because preview is working in console.
JS v2
This attempt works as is, but is less complete. console is producing all of the .preview-container elements, but I haven't been able to incorporate getBoundingClientRect():
document.querySelectorAll(".preview-container").forEach(preview => {
preview.style.position = "fixed";
preview.style.top = "0";
preview.style.left = "0";
console.log(preview);
});
I feel like I am closer with JS v1, and am missing something simple with the style properties. How should I proceed?
You have a problem with the name of your variables, in the first one you call it el and you refer as preview. And to get the values of getBoundingClientRect you need to create another variable.
document.querySelectorAll(".preview-container").forEach(preview => {
previewValues = preview.getBoundingClientRect();
preview.style.position = "fixed";
preview.style.top = "0";
preview.style.left = "0";
console.log(preview);
console.log(previewValues);}
)
<div>
<div class="preview-container">
<div>
<!-- Image -->
</div>
</div>
</div>
<div>
<div class="preview-container">
<div>
<!-- Image -->
</div>
</div>
</div>
<!-- more -->
Looking at the interfaces for DOMRect (there are several), it states that updating properties of a DOMRect updates the position of the element it was called on, as in this example:
"use strict";
$('.preview-container').each(function(el) {
var rect = this.getBoundingClientRect();
this.style.position = "fixed";
// this.style.top = "0";
rect.x = 0;
// this.style.left = "0";
rect.y = 0;
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.6.0/jquery.min.js"></script>
<!-- body-html -->
<div>
<div class="preview-container">
<div>
Image 1
</div>
</div>
</div>
<div>
<div class="preview-container">
<div>
Image 2
</div>
</div>
</div>
Note
this has been used to refer to preview divisions in the each argument function, not el.
Changes to position are made by setting properties of rect, not style, as allowed in the standard, but this is uncommon.
Usually positions are set either in CSS, or using element style objects (the this.style lines commented out above), without calling getBoundingClientRect to obtain a DOMRect first.
However when an element descends from an element with a transform property, the transform element behaves as the containing block for fixed elements below as shown here:
$('.preview-container').each(function(el) {
this.style.position = "fixed";
this.style.top = "0";
this.style.left = "0";
});
/* CSS from https://developer.mozilla.org/en-US/docs/Web/CSS/transform */
div.ancestor {
border: solid red;
transform: translate(30px, 20px) rotate(20deg);
width: 140px;
height: 60px;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.6.0/jquery.min.js"></script>
<!-- body-html -->
<div class="ancestor">
<div class="preview-container">
<div>
Image 1
</div>
</div>
</div>
<div class="ancestor">
<div class="preview-container">
<div>
Image 2
</div>
</div>
</div>
If you want to fix preview container positioning relative to the view port, try moving them out from under the transform ancestor by, say, appending them to the body element. If aspects of the transform operation need to be retained on moved preview containers, a suitable CSS transform would need to be separately applied to them after the move.

I have a page with a non-scrollabe left side-bar and a scrollable right container. I want to add a "go to top" button in the container

I have written the code so that it will show up after the page is scrolled 20px. But with this code the button does not show up. The problem here is that when the side-bar and container both are scrolled, the button works fine. I want it to work when only the right container is scrolled
//go to top button
var topBtn = document.getElementById('top');
var contain = document.getElementsByClassName('container').scrollTop;
window.onscroll = function(){
scrollFunction()
};
function scrollFunction(){
if (document.contain > 20){
topBtn.style.display = 'block';
}
else{
topBtn.style.display = 'none';
}
}
function goToTop(){
document.contain = 0;
document.documentElement.scrollTop = 0;
}
topBtn.addEventListener('click', goToTop);
<div class="wrapper">
<nav role="navigation" id="nav">
<img class="profile-img" src="images/profile-photo-new.jpg" alt="" />
About
Experience
Education
Skills
Interests
Certificates
</nav>
<div class="container">
<div id="about" class="mtb about-fixed-nav">
<h1 class="heading about-head">
<span>Pratit</span>
Bangdiwala
</h1>
Top
</div>
</div>
<script src="custom.js"></script>
</body>
</html>
No need Javascript
Use this
Top
Use the Id of top element of your page as "href" value
Like "nav"

How to calculate the `children's` height pefectly

I am calulating the childrens height, to add the scrollbar to the container. but it's not come as perfect. any one help me to calculate the childrens height perfectly?
here is my js :
var p= "</p>Some testing text</p>";
var getAllHeight = function (content) {
var allHeight = 0;
$('#container').children().not('.content').each(function(){
allHeight += $(this).outerHeight(true);
});
return allHeight;
}
var addHeight = function () {
var content = $('.content');
var allHeight = getAllHeight(content);
var rest = $('#container').innerHeight() - allHeight;
if(content.outerHeight() > rest) {
content.css('height', (content.outerHeight() - allHeight ));
}
console.log(allHeight, content.height(), content.outerHeight(),content.innerHeight())
};
$('button').click(function(){
$('.content').append(p);
addHeight();
});
<div id="container">
<div>
<h2>Heading</h2>
</div>
<div>
<h2>Heading</h2>
</div>
<div class="content">
</div>
<div class="footer">
Footer
</div>
<div class="button"><button>Add</button></div>
</div>
JSfiddle
This is CSS issue due to collapsing margins (read "Parent and first/last child" case) on div>h2 structure. Since div containers don't have any padding, margin or border, their margins collapse to accommodate inner margin. Simple fix is to set some padding on them or border or set h2 to inline-block.
Another issue is that when there is not enough space you should set content height to rest.
if (content.outerHeight() > rest) {
content.css('height', rest);
}
Demo: http://jsfiddle.net/doesfmnm/5/

jQuery scrollTop and parallax effect: Browser window jitters when scrolling at the very bottom

I have a little script that is creating a parallax effect. Therefore I created a data attribute with the speed velocity and a data-type to select the parallax elements. At the very same time, one of the elements fades out when scrolling down.
The script works fine, but unfortunately, when scrolling to the bottom of the site (and "overscroll" it), the site jitters like hell. It seems to be the part with the yPos and scrollTop method.
Do you have any ideas what the problem is?
Here's the markup:
<section class="slider">
<img src="images/hafen.jpg" class="slide" data-type="parallax" data-speed="3">
<div class="claim" data-type="parallax" data-speed="6">
<h1>SOME TEXT</h1>
</div>
<div class="arrow-down" data-type="parallax" data-speed="3">
<img src="images/arrow-down.png" alt="">
</div>
</section>
<section class="content" data-type="parallax" data-speed="1">
<div class="wrapper">
<img src="images/content.png" alt="">
</div>
<section>
That's my script:
$(window).scroll(function() {
var box;
$("[data-type=\"parallax\"]").each(function() {
var $bgobj, position, yPos;
$bgobj = $(this);
yPos = -($window.scrollTop() / $bgobj.data("speed"));
position = parseInt(yPos);
return $bgobj.css({
marginTop: position
});
});
box = $(".claim");
return box.css({
"opacity": 1 - $window.scrollTop() / 400
});
});
Seems like you are missing ( and ) around window here:
yPos = -($window.scrollTop() / $bgobj.data("speed"));
Should be:
yPos = -($(window).scrollTop() / $bgobj.data("speed"));
And you <section> isn't closed at the very end. Should be:
...
</section>
Not sure what your expected result should look like with proper CSS, but this seems to be working with the above changes:
http://jsfiddle.net/4Zmh8/
$(function () {
$(window).scroll(function () {
var box;
$("[data-type=\"parallax\"]").each(function () {
var $bgobj, position, yPos;
$bgobj = $(this);
yPos = -($(window).scrollTop() / $bgobj.data("speed"));
position = parseInt(yPos);
return $bgobj.css({
marginTop: position
});
});
box = $(".claim");
return box.css({
"opacity": 1 - $window.scrollTop() / 400
});
});
});

Jquery equal Heights

I don't know what am I doing wrong.. but I have 3 columns where I want to apply equal heights
here is my html
<div id="wrapper">
<div class="LeftBG"></div>
<div id="MainBlock">THIS IS A TEST</div>
<div class="RightBG"></div>
<!-- END CONTENT BLOCK -->
</div>
and here is my function and just doesn't work....
var highestCol = Math.max(
$('.LeftBG').height(),
$('.RightBG').height());
$('#MainBlock').height(highestCol);
To see what I am doing click here
Change your code to this to set all three blocks to the same height:
var highestCol = Math.max(
$('.RightBG').height(),
$('.LeftBG').height());
$('#MainBlock, .RightBG, .LeftBG').height(highestCol);
See it here: http://jsfiddle.net/jfriend00/Rv4fr/
What you did fixes the middle column, now apply it to the other classes as well...
var highestCol = Math.max(
$('.RightBG').height(),
$('.LeftBG').height());
$('#MainBlock').height(highestCol);
$('.RightBG').height(highestCol);
$('.LeftBG').height(highestCol);

Categories

Resources