i need some help about finding elements position.
im working on an e-book reader, also its all Html with css.
All html sectioned page by page, and i have to find an element like this
<span name="Note" style="background-color:rgb(255,255,204)">Example</span>
Everyone suggests code like this;
function position(elem) {
var left = 0,
top = 0;
do {
left += elem.offsetLeft;
top += elem.offsetTop;
} while ( elem = elem.offsetParent );
return [ left, top ];
}position(document.getElementsByName('Note')[0]);
but it does not work for me; I need element's real position in scroll with JavaScript.
var note = document.getElementsByName('Note')[0];
var screenPosition = note.getBoundingClientRect();
The ClientRect returned by getBoundingClientRect() has values for .top, .left, .right, .bottom, .width, and .height.
These are pixel positions on the visible window; as you scroll the page the .top and .bottom values will change, and may even become negative as the item scrolls off the top of the view.
Note that—unlike the solution accumulating offsetLeft/offsetTop—this solution properly accounts for borders and padding on the body and html elements in all browsers (Firefox).
See this test case: http://jsfiddle.net/QxYDe/4/ (scroll the page and watch the values change).
Also supported by Internet Explorer.
function position(elem) {
var left = 0,
top = 0;
do {
left += elem.offsetLeft-elem.scrollLeft;
top += elem.offsetTop-elem.scrollTop;
} while ( elem = elem.offsetParent );
return [ left, top ];
}
var elem = document.getElementById('id');
position(elem);
Subtract the scroll positions.
My guess is that you need the note to stay fixed to the top left corner at all times? Even when scrolled?
You can do this with CSS only! :)
HTML:
<div id="Note" name="Note">Example</div>
CSS:
div #Note {
background-color:rgb(255,255,204)
left: 0px;
position: absolute;
top: 0px;
z-index: 999;
}
#media screen {
body > div #Note {
position: fixed;
}
}
EDIT:
With several notes (not tested):
HTML:
<div id="Note1">Example</div>
<div id="Note2">Example</div>
<div id="Note3">Example</div>
<div id="Note4">Example</div>
CSS:
div #Note1 {
background-color:rgb(255,255,204)
left: 0px;
height: 20px;
position: absolute;
top: 0px;
z-index: 999;
}
div #Note2 {
background-color:rgb(255,255,204)
left: 0px;
height: 20px;
position: absolute;
top: 20px;
z-index: 999;
}
div #Note3 {
background-color:rgb(255,255,204)
left: 0px;
height: 20px;
position: absolute;
top: 40px;
z-index: 999;
}
div #Note4 {
background-color:rgb(255,255,204)
left: 0px;
height: 20px;
position: absolute;
top: 60px;
z-index: 999;
}
#media screen {
body > div #Note1 {
position: fixed;
}
body > div #Note2 {
position: fixed;
}
body > div #Note3 {
position: fixed;
}
body > div #Note4 {
position: fixed;
}
}
Solution to find an element position for scroll:
const target = document.querySelector('[name="Note"]')
window.scrollTo({
top: Math.round(target.getBoundingClientRect().top + document.documentElement.scrollTop),
behavior: 'smooth',
})
Or just use scrollIntoView:
document.querySelector('[name="Note"]').scrollIntoView({
behavior: 'smooth',
})
First you need to get the height of entire document. Height of the whole document, with the scrolled out part: link
let scrollHeight = Math.max(
document.body.scrollHeight, document.documentElement.scrollHeight,
document.body.offsetHeight, document.documentElement.offsetHeight,
document.body.clientHeight, document.documentElement.clientHeight
);
After you can use to get element's scrollTop position:
const element = document.getElementsByName('Note');
element.scrollTop
Or you can go to element on view (scrollIntoView)
I'm not sure what you want to do after get the scrollTop position.
Solution:
<script>function showDiv() {
var div = document.getElementById('comdiv');
var button = document.getElementById('button');
if (div.style.display !== "none") {
div.style.display = "none";
button.value = "Add Comments";
}
else {
button.value = "Hide Comments";
div.style.display = "block";
}
var note = document.getElementsByName("comment")[0];
var screenPosition = note.getBoundingClientRect();
window.scrollTo(screenPosition);
}</script>
<form name="form" id="form" action="" method="post">
<textarea name="comment" id="comment" placeholder="Write Comment, Max: 140 characters" rows="4" class="width-50" onblur="checkMe()" ></textarea>
<input type="text" class="input-small width-33" name="name" id="name" placeholder="Name" autofocus class="width-33" onblur="checkMe()" />
<button type="submit" name="submit" id="submitbutton" class="btn btn-green btn-outline" disabled="disabled">Post Comment</button>
</form>
In ANGULAR:
import { ViewChild, AfterViewInit } from '#angular/core';
...
export class NewTrendingComponent implements AfterViewInit {
#ViewChild('theElementInQuestion') public trendyElement!: ElementRef;
ngAfterViewInit(): void {
// log the top pixel value of the element in question
console.log(this.trendyElement.nativeElement.offsetTop)
}
}
...
<div #theElementInQuestion> this is the element you are looking for... </div>
...
Note: if you are using structural directives like ngIf, you want to look into when exactly the element will render (usually with / after after ViewInit if | async). Or look into using the {static: true} option.
#ViewChild('theElementInQuestion', {static: true}) public trendyElement!: ElementRef;
Related
window.addEventListener("scroll",()=>{
const header = document.querySelector("header");
header.classList.toggle("sticky", window.scrollY > 0);
})
I know about .toggle() method but not so clearly. Would some one please explain about toggle() and window.scrollY?
Scroll Down. scrollY property of the Window interface returns the number of pixels that the document is currently scrolled vertically.
window.addEventListener("scroll", (event) => {
document.querySelector("h1").textContent = this.scrollY;
document.querySelector("h2").textContent = ("sticky", window.scrollY > 0);
})
body {
width: 100vw;
height: 400vh;
}
h1 {
position: fixed;
top: 0;
}
h2 {
position: fixed;
top: 20%;
}
<h1>0</h1>
<h2></h2>
I want to move the white box to the right by 50% while scrolling until it reaches the red section. The distance to the red section is 1000px in the example.
The code below moves the box to the right as I scroll down, and I'm just using a random number 10 to slow down the movement but I can't get my head around to make it move evenly for every scroll event until the box reaches the red section and move 50% to the right.
var xPos = 0;
function getXPos(target, windowPos) {
var amount = windowPos - target;
xPos = amount / 10;
return xPos;
}
$(window).scroll(function() {
var windowPos = $(window).scrollTop();
var sectionOne = $('section.one').offset().top;
var sectionTwo = $('section.two').offset().top;
var box = $('.box');
if (windowPos > sectionOne && windowPos < sectionTwo) {
box.css({
"transform": 'translateX(' + getXPos(sectionOne, windowPos) + '%)'
});
}
});
body {
margin: 0;
}
.box {
background: white;
position: sticky;
top: 0;
width: 300px;
height: 300px;
}
section.one {
height: 1000px;
background: blue;
}
section.two {
height: 1000px;
background: red;
}
<section class="one">
<div class="box"></div>
</section>
<section class="two"></section>
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.5.1/jquery.min.js"></script>
There is also another issue with scroll that if I scroll too fast, the box won't move as much.
Here is the fiddle for demonstration.
https://jsfiddle.net/sungsoonz/0Lspo2d9/
So I used the logic of making a progress bar for whole page but for your section with class "one". So when you scroll the section 100% of it's height the "left" css property on the div with class "box" becomes at value of "100%". But as I understood we need to stop moving when we reach section with class "two" with div with class "box". So {left: 100%} will become when we have scrolled whole section with class "box" minus the visible height of div with class "box". Then it is easily calculated to move only for 50% of width of section with class "one" (-width of div with class "box" width / 2 to center it). Hope I described my solution clearly (xd). Hope it helps
The code:
one = document.querySelector(".one")
two = document.querySelector(".two")
box = document.querySelector(".box")
$(window).on('scroll', function (){
if (window.scrollY >= (one.scrollHeight - box.offsetHeight)) {
$('.box').css('left', `calc(50% - ${(box.offsetWidth / 2)}px`);
return
}
$scrolledFrom = $(document).scrollTop();
$documentHeight = $(document).height() - ($(".two").height() + box.offsetHeight);
$leftOffset = ($scrolledFrom / $documentHeight) * 100;
$('.box').css('left', `calc(${($leftOffset / 2)}% - ${(box.offsetWidth / 2)}px`);
console.log ()
});
body {
margin: 0;
}
.box {
background: white;
position: sticky;
top: 0;
left: 0;
width: 300px;
height: 300px;
}
section.one {
height: 1000px;
background: blue;
}
section.two {
height: 1000px;
background: red;
}
<section class="one">
<div class="box"></div>
</section>
<section class="two"></section>
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.5.1/jquery.min.js"></script>
this is my getoffset js code to get div width and left
var objRedPacketDivStyle = document.getElementById("styRedPacketAppear");
var objOffset = objRedPacketDivStyle.offset();
var intWidth = objOffset.offsetWidth;
var objWidthStart = objOffset.offset.left;
var objWidthEnd = objWidthStart + intWidth;
alert(objWidthStart + objWidthEnd);
and here is my div and css
<div class="styRedPacketAppear" id="styRedPacketAppear"></div>
#styRedPacketAppear {
position: fixed;
top: 0;
left: 0;
width: 100%;
z-index: 98;
pointer-events: none;
}
This isn't working as .offset() is a jQuery method. Since you don't have jquery you need to use vanilla javascript to achieve this.
You can use:
element.offsetWidth: "returns the layout width of an element as an integer." - MDN
element.offsetLeft: "returns the number of pixels that the upper left corner of the current element is offset to the left within the HTMLElement.offsetParent node." - MDN
Using these two properties will resolve your issue:
var objRedPacketDivStyle = document.getElementById("styRedPacketAppear");
// Remove this: var objOffset = objRedPacketDivStyle.position.offset();
var intWidth = objRedPacketDivStyle.offsetWidth;
var objWidthStart = objRedPacketDivStyle.offsetLeft;
var objWidthEnd = objWidthStart + intWidth;
alert(objWidthStart + objWidthEnd);
#styRedPacketAppear {
position: fixed;
top: 0;
left: 0;
width: 100%;
z-index: 98;
pointer-events: none;
}
<div class="styRedPacketAppear" id="styRedPacketAppear"></div>
The offsetTop property returns the top position (in pixels) relative to the top of the offsetParent element.
The returned value includes:
-the top position, and margin of the element
-the top padding, scrollbar and border of the offsetParent element.
#test {
top: 100px;
margin: 10px;
padding: 10px;
width: 300px;
position: fixed;
border: 5px solid black
}
var testDiv = document.getElementById("test");
document.getElementById("demo").innerHTML = testDiv.offsetTop;
Result-offsetTop is: 110
I'm trying to stick a section to the top when it hits the top of the browser on scroll down, but I'd like to unstick it when the user scrolls back up and the previous section is back in view.
I'm detecting distance from top to section I'd like to stick, but once its at the top how do we detect user scrolling back up and previous section comes back into view.
My Codepen: https://codepen.io/omarel/pen/LeEjax
Snippet
$(window).on('scroll', function() {
var scrollTop = $(window).scrollTop();
sectionone = $('section.one').offset().top;
sectiontwo = $('section.two').offset().top;
sectiontwodistance = (sectiontwo - scrollTop);
sectiononedistance = (sectionone - scrollTop);
console.log(sectiononedistance);
if (sectiontwodistance < 1) {
$('section.two').addClass('fix');
}
});
html,
body {
width: 100%;
height: 100%;
}
section {
height: 100%;
border: 5px solid red;
position: absolute;
width: 100%;
}
section.one {
z-index: 1;
top: 0%;
}
section.two {
border: 5px solid green;
z-index: 2;
top: 100%;
}
section.three {
z-index: 3;
top: 200%;
}
section.fix {
position: fixed;
top: 0;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<section class="one">
1
</section>
<section class="two">
2
</section>
<section class="three">
3
</section>
I would update your jQuery to the snippet below. It checks the position of section one against the height of the window and if less than, or equal to it removes the .fix class.
$(window).on('scroll', function() {
var scrollTop = $(window).scrollTop();
sectionone = $('section.one').offset().top;
sectiontwo = $('section.two').offset().top;
sectiontwodistance = (sectiontwo - scrollTop);
sectiononedistance = (sectionone - scrollTop);
console.log(sectiononedistance);
if (sectiontwodistance < 1) {
$('section.two').addClass('fix');
}
if (Math.abs(sectiononedistance) <= $(window).height()) {
$('section.two').removeClass('fix');
}
});
I going to create a scroll and stick div which has to stick on the top of the page but while scrolling down the div next to stickdiv automatically stick to the div before to sticky div
var left = document.getElementsByClassName("stickdiv");
for (var i = 0; i < left.length; i++) {
var stop = (left[0].offsetTop);
window.onscroll = function(e) {
var scrollTop = (window.pageYOffset !== undefined) ? window.pageYOffset : (document.documentElement || document.body.parentNode || document.body).scrollTop;
// left.offsetTop;
if (scrollTop >= stop) {
// get array item by index
left[0].classList.add('stick'); //adding a class name
} else {
// get array item by index
left[0].classList.remove('stick');
}
}
}
.stickdiv {
height: 50vh!important;
width: 100vh!important;
background-color: green!important;
}
.stick {
position: fixed;
top: 0;
margin: 0 0
}
#right {
float: right;
width: 100px;
height: 1000px;
background: red;
}
.des {
height: 300px;
width: 100%;
background-color: #000;
}
<div class="des"></div>
<div class="stickdiv"></div>
<div id="right"></div>
Example : green color div is the sticky div but after scrollingdown , red is also going to stick , I've tried position absolute in css but not working how to fix it
Here is the code to make green sticky when scrolling.
$ = document.querySelectorAll.bind(document);
// how far is the green div from the top of the page?
var initStickyTop = $(".stickdiv")[0].getBoundingClientRect().top + pageYOffset;
// clone the green div
var clone = $(".stickdiv")[0].cloneNode(true);
// hide it first
clone.style.display = "none";
// add it to dom
document.body.appendChild(clone);
addEventListener("scroll",stick=function() {
// if user scroll past the sticky div
if (initStickyTop < pageYOffset) {
// hide the green div but the div still take up the same space as before so scroll position is not changed
$(".stickdiv")[0].style.opacity = "0";
// make the clone sticky
clone.classList.add('stick');
// show the clone
clone.style.opacity="1";
clone.style.display = "block";
} else {
// make the clone not sticky anymore
clone.classList.remove("stick");
// hide it
clone.style.display = "none";
// show the green div
$(".stickdiv")[0].style.opacity="1";
};
});
// when resize, recalculate the position of the green div
addEventListener("resize", function() {
initStickyTop = $(".stickdiv")[0].getBoundingClientRect().top + pageYOffset;
stick();
});
.stickdiv {
height: 50vh!important;
width: 100vh!important;
background-color: green!important;
}
.stick {
position: fixed;
top: 0;
margin: 0 0
}
#right {
float: right;
width: 100px;
height: 1000px;
background: red;
}
.des {
height: 300px;
width: 100%;
background-color: #000;
}
<div class="des"></div>
<div class="stickdiv"></div>
<div id="right"></div>
JS FIDDLE
you might want to remove the stickdiv class and add it accordingly
if (scrollTop >= stop) {
// get array item by index
left[0].classList.add('stick'); //adding a class name
left[0].classList.remove('stickdiv');
} else {
// get array item by index
left[0].classList.remove('stick');
left[0].classList.add('stickdiv');
}