Prevent two fixed components from overlapping - javascript

I have been struggling to make an element that I prepend to a page not overlap with the fixed component already existant on the page.
For example, you can execute the following in console on Stackoverflow :
const rootElement = document.createElement("div");
rootElement.id = "chrome-bar";
document.getElementsByTagName("body")[0].style["paddingTop"] = "40px";
document.getElementsByTagName("body")[0].style["position"] = "relative";
document.body.prepend(rootElement); rootElement.innerHTML="Hello World";rootElement.style="position:fixed;z-index:99999;top:0;background-color:black;width:100vw;color:white;"
As you can see, the black bar overrides the header tag, because of its position : fixed style. How could I have both of these bars (the one I create & the SO navbar) fixed and not overlap ? i.e. the behaviour that happens when you insert the same snippert on github (whose nav is not fixed)
Thanks a lot !

This is somewhat of a crude workaround, but you could create a div with a fixed height and displace the existing header element by the same amount.
const rootElement = document.createElement("div");
rootElement.id = "chrome-bar";
document.getElementsByTagName("body")[0].style["paddingTop"] = "40px";
document.getElementsByTagName("body")[0].style["position"] = "relative";
document.body.prepend(rootElement);
rootElement.innerHTML = "Hello World";
let divHeight = "30px"
rootElement.style = `position:fixed;z-index:99999;top:0;background-color:black;width:100vw;height:${divHeight};color:white;`
let header = document.querySelector("body > header")
header.style.setProperty("top", divHeight, "important")

Related

How to stop a scrollable element from being scrolled any further?

I have this scrollable text where the user is able to scroll so that my name is shown. I want to stop the text from being scrolled any further when the element reaches the middle of the user's screen. Is there any way to do that? Attached below is a snippet of the code.
let text = document.getElementById('text');
var textRect = text.getBoundingClientRect();
var bodyRect = document.body.getBoundingClientRect();
var w = window.innerWidth;
const scaler = 1/25
window.addEventListener('scroll', function(){
let value = window.scrollY;
if (value < w/2.65) /*when text is right of center*/{
text.style.marginRight = value * 3*scaler+ 'vw';
}
})
I have made many futile attempts at solving this issue but all have gone in vain. Thank you to anyone that helps me solve this issue.
I have tried using innerwidth to compare my value to the width of the screen and used document.body.getBoundingClientRect() but none of those have worked either

scrolling horizontally on section to create a conveyor belt effect on page scroll

Okay so I have been at this for quite some time. I have an example of what I am trying to do here
I have two rows on a fixed page. When i scroll on the page I want them to each scroll on the opposite direction. where I am failing at is that the rows are not infinite.
Is it so simple as to add children on scroll? When I do that it kind of works I guess but, I am unable to remove the first eight children without causing the whole thing to break. Any leads?
I have some code in this codepen
const row = document.getElementById('row');
const rowReverse = document.getElementById('row-reverse');
window.addEventListener('scroll', () => {{
row.appendChild(row.children[0].cloneNode(true));
rowReverse.style.transform = `translateX(-${window.scrollY}px) rotate(360deg) scaleX(-1)`;
row.style.transform = `translateX(${window.scrollY}px)`;
}});
const children = row.children.length;
const childrenArray = Array.from(row.children);
const lastChild = childrenArray[children - 1].getBoundingClientRect().right;
const windowWidth = window.innerWidth;
if (lastChild < windowWidth) {
childrenArray.forEach((child) => {
row.appendChild(child.cloneNode(true));
rowReverse.appendChild(child.cloneNode(true));
});
}

Cannot apply style to dynamically created elements in javascript

I have the following code:
let dynel = document.createElement('div');
dynel.className = 'foo';
dynel.style.width = '5px';
dynel.style.height = '5px';
dynel.style.backgroundColor = 'blue';
document.body.appendChild(dynel);
This code works as I expect it to, after appending the dynamic element to the document, a 5 x 5 blue box appears. The problem starts when I try to access the element via its className to style it further:
var foo = document.getElementsByClassName('foo');
foo[0].style.top = '50px';
foo[0].style.left = '200px';
This code should position the box but it does nothing, what am I doing wrong? Preferably I'm looking for a pure JS solution so no JQuery.
Thanks in advance :)
Problem
The default value of the property position of a div is static. When you try to set left/right [..] on static element it has no effect on that element.
static : every element has a static position by default, so the
element will stick to the normal page flow. So if there is a
left/right/top/bottom/z-index set then there will be no effect on that
element. relative : an element's original position remains in the flow
of the document, just like the static value.
Solution
You have to set the position property in your created element to absolute, fixed or relative.
let dynel = document.createElement('div');
dynel.className = 'foo';
dynel.style.position = "absolute"
dynel.style.width = '5px';
dynel.style.height = '5px';
dynel.style.backgroundColor = 'blue';
document.body.appendChild(dynel);
var foo = document.getElementsByClassName('foo');
foo[0].style.top = '50px';
foo[0].style.left = '200px';
top, left, right, bottom works on those elements in which position property is not static. But either absolute or relative or fixed.
As per your requirement use any of the 3 values in your CSS and styles will start to apply. Something like this would work (But it depends how you want you implemention of the code)
var foo = document.getElementsByClassName('foo');
foo[0].style.position = "relative";
foo[0].style.top = '50px';
foo[0].style.left = '200px';
NOTE: position:fixed and position:absolute would get your element out of the normal code flow and you will have to adjust accordingly.
You need to ensure that foo[0] has the position: absolute; style set.
I was inspired by #Imran Rafiq Rather to give the details example for each situation:
relative
If you just want to adjust position a little bit relative to its default position, use key word "relative"
Default position is 'static' position
var foo = document.getElementsByClassName('foo');
foo[0].style.position = "relative"; // works almost the same as default or 'static', because 'relative' is relative to it's 'static' position.
foo[0].style.top = '50px';
foo[0].style.left = '200px';
https://codepen.io/hoogw/pen/QWqRdBY
absolute
we usually want to relative to its parent div, should use 'absolute'
var foo = document.getElementsByClassName('foo');
foo[0].style.position = 'absolute'; // relative to its parent div
foo[0].style.top = '50px';
foo[0].style.left = '200px';
https://codepen.io/hoogw/pen/GRMaWKB?editors=1100
fixed
If you want to relative to whole page, use 'fixed'
var foo = document.getElementsByClassName('foo');
foo[0].style.position = 'fixed'; // relative to whole page, whole html body document
foo[0].style.top = '50px';
foo[0].style.left = '200px';
https://codepen.io/hoogw/pen/yLzWMvJ
Here is link to document https://developer.mozilla.org/en-US/docs/Web/CSS/position

need 100% div without setting a fixed height on container div

Here is a link to a JSFiddle http://jsfiddle.net/9NYcn/11/ i put together with what i would like to do, but i need to do this with pure css.
function expand(){
var sect = document.getElementById("sect");
var body = document.getElementById("main");
var panes = document.getElementById("panes");
var newHeight = 40 + "px";
var newHeight2 = 120 + "px";
var topVal = 120 + "px";
sect.style.display = "block";
sect.style.height = newHeight;
body.style.height = newHeight2;
panes.style.top = topVal;
}
In the above function i had to set the "top" property of panes in order to get this to work. i need to get it so that the panes section will work like it currently does without using javascript to change the "top" property of "panes". When the user clicks the "expand" button the div with the class "body" will expand and not stick behind or overlap the "panes" div.
I know im doing a terrible job explaining i apologize for that.
Remove the absolute positioning of .panes: http://jsfiddle.net/rHTM8/
It will make it naturally flow after the middle div.

JavaScript absolute position of element on images

I have created a new div and adding it to all images on the page as follows:
var images = document.getElementsByTagName('img');
for (var i = 0; i < images.length; i++) {
var divLink = document.createElement("div");
divLink.style.position = "absolute"; divLink.style.top = "10px"; divLink.style.right = "10px"; divLink.style.zIndex="1"; divLink.style.fontSize = "20px"; divLink.style.backgroundColor = "black"; divLink.style.color = 'white';
divLink.innerHTML = linkCount;
images[i].parentNode.insertBefore(divLink, images[i] );
}
This is working well for all images except images contained in a <ul>. For these images, each divLink is moved to the right of the <ul> and stacked on top of one another. If I remove the divLink.style.right = "10px"; the divLink moves by default to the left of the image.
How can I position the divLink to the top-right corner of the image, for all images including those in the <ul>.
Use relative position instead of absolute
divLink.style.position = "relative";
There seems no need to give position:absolute to the images.
You can simply append the images without giving the position attribute and move the images using the margin property.
divLink.style.margin-top = "10px";
divLink.style.margin-right= "10px";
If you add poistion:absolute and mention top/left/right/bottom , the elements tends to stack on each other .
There are 2 ways to do this :
1> Do not assign any position.Let it remain "STATIC". Move the "images" using the margin properties.
Eg:
divLink.style.margin-top = "10px";
divLink.style.margin-right= "10px";
OR
2> Make just the position:absolute without mentioning top/left/right/bottom properties, this way they will not stack on each other. Unless you don't want to move the "images" explicitly using top/left, that is of no use.

Categories

Resources