Why is not my element scrolled into view?
useEffect(() => {
const elements = document.getElementsByClassName('some-class-name');
const [element] = elements;
if (element) {
window.scrollTo(0, 0);
element.scrollIntoView({ inline: 'center' });
}
}, [aProp]);
It did work before, but now it does not work. I am using Chrome. Should not the container with horizontal scroll scroll the element into view? The reason I have the window.scrollTo(0, 0) is because I want the window to scroll to the top as well.
Related
I'm trying to simulate Tesla's web app landing page scroll behavior using React.js and react-scroll
Assume we have 2 sections, the hero image is section 1, and within a small scroll from the user, an event is triggered it scrolls down to the next section (section 2)
My question is how could I trigger the scroll event to scroll to section 2 when the user is scrolling down while he is on section 1, similarly to the Tesla landing page.
I have achieved it using listener on offsetY and a condition if it is equivalent to 100px if (offsetY === 100), the window will be scrolled to section 2. but that only could be achieved in equivalence to 100. in other words, the window will be scrolled if and only if it meets 100px relative to the document.
any thoughts or recommendations would be useful.
function App() {
const [offsetY, setOffSetY] = useState(0);
const handleScroll = (e) => {
setOffSetY(window.pageYOffset)
};
useEffect(() => {
window.addEventListener("scroll", handleScroll);
return () => window.removeEventListener("scroll", handleScroll);
}, [])
useEffect(() => { // fires when the user scroll up or down, i.e. when the offsetY changes
if (offsetY === 100) { // scroll to section 2 when the offsety is equal to 100px
scroller.scrollTo("section2", {
delay: 100,
duration: 200,
smooth: true
})
}
}, [offsetY]);
return (
<React.Fragment>
<div id="section1" style={{height:"500px", width:"100%", color:"black"}}>
</div>
<div id="section2" style={{height:"500px", width:"100%", color:"red"}}>
</div>
</React.Fragment>
);
}
export default App;
I have an Image Gallery Slider that uses ScrollIntoView() for its thumbnail, but every time I scroll up or down the page and the newest thumbnail is selected, it brings the entire page location back to where the thumbnail sits. Is there a way to disable this scrollIntoView() feature? The project is: https://codepen.io/abcretrograde/pen/povVxVq
function updateImage() {
const thumbs = document.querySelectorAll(
"#jsSlideshow .js-slideshow__thumb-image"
);
clearInterval(autoUpdate);
autoUpdate = setInterval(() => {
incImage();
}, slideSpeed);
const newOffset = getImagePos(imageWidthArray, whichImage);
slideshow.style.setProperty("--offset", newOffset + "px");
thumbs.forEach((thumb) => {
thumb.classList.remove("js-slideshow__thumb-image--selected");
});
thumbs[whichImage].classList.add("js-slideshow__thumb-image--selected");
thumbs[whichImage].scrollIntoView({
behavior: "auto",
block: 'center',
inline: "center",
});
}
The block property - scrollIntoView(options) - defines vertical alignment.
Have you tried changing center to nearest?
thumbs[whichImage].scrollIntoView({
behavior: "auto",
block: "nearest",
inline: "center"
});
I'm trying to get element position while scrolling in a horizontal web page. I tried to use
main scrolling:
$('html, body, *').mousewheel(function(e, delta) {
this.scrollLeft -= (delta*60);
});
then:
$(window).scroll(function() {
alert('Anything');
});
But that doesn't work at all. I tried using mousewheel plugin
$('.internal.th').on('mousewheel',function(event) {
console.log(event.deltaX, event.deltaY, event.deltaFactor);
});
But it keeps displaying the same position -0 -1 100 no matter how much i scroll
I tried
$('.internal.th').on('scroll', function() {
var val = $(this).scrollLeft()
if (val >= 100) alert('Hello')
})
but it doesn't do anything at all
The idea is getting some item position from the left related to the window to manage another element rotation so I want to keep tracking the main item positing while scrolling horizontally not vertically
jQuery provides APIs
offset
position
you can use those
Below is a sample with both vertical and horizontal scrollbars
$(document).ready(function(){
document.addEventListener('scroll', function (event) {
console.log(event.target);
console.log($("#p3").position());
console.log($("#p3").offset());
console.log($("#p3").position().top - $("body").scrollTop());
console.log($("#p3").position().left - $("body").scrollLeft());
}, true);
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<p>dasdasd</p>
<p>dasdasd</p>
<p>dasdasd</p><p>dasdasd</p><p>dasdasd</p><p>dasdasd</p><p>dasdasd</p><p>dasdasd</p><p>dasdasd</p><p>dasdasd</p><p>dasdasd</p>
<p style="width: 2500px;display:inline-block">dasdasd<div ></div></p>
<p>dasdasd</p><p>dasdasd</p><p>dasdasd</p><p>dasdasd</p><p>dasdasd</p><p>dasdasd</p><p>dasdasd</p><p>dasdasd</p><p>dasdasd</p><p>dasdasd</p><p>dasdasd</p><p>dasdasd</p><p>dasdasd</p><p>dasdasd</p><p>dasdasd</p><p>dasdasd</p><p>dasdasd</p><p>dasdasd</p><p>dasdasd</p><p>dasdasd</p><p>dasdasd</p><p>dasdasd</p><p>dasdasd</p><p>dasdasd</p><p>dasdasd</p><p>dasdasd</p><p>dasdasd</p><p>dasdasd</p><p>dasdasd</p><p>dasdasd</p><p>dasdasd</p><p>dasdasd</p><p>dasdasd</p><p>dasdasd</p><p>dasdasd</p><p>dasdasd</p><p>dasdasd</p><p>dasdasd</p><p>dasdasd</p><p>dasdasd</p><p>dasdasd</p><p>dasdasd</p><p>dasdasd</p><p>dasdasd</p><p>dasdasd</p><p>dasdasd</p><p>dasdasd</p><p>dasdasd</p><p>dasdasd</p><p>dasdasd</p><p>dasdasd</p><p>dasdasd</p><p>dasdasd</p><p>dasdasd</p><p>dasdasd</p><p>dasdasd</p><p id="p3">dasdasd</p><p>dasdasd</p><p>dasdasd</p><p>dasdasd</p><p>dasdasd</p><p>dasdasd</p><p>dasdasd</p><p>dasdasd</p><p>dasdasd</p><p>dasdasd</p><p>dasdasd</p><p>dasdasd</p><p>dasdasd</p><p>dasdasd</p><p>dasdasd</p><p>dasdasd</p><p>dasdasd</p><p>dasdasd</p><p>dasdasd</p><p>dasdasd</p><p>dasdasd</p><p>dasdasd</p><p>dasdasd</p><p>dasdasd</p><p>dasdasd</p><p>dasdasd</p><p>dasdasd</p><p>dasdasd</p><p>dasdasd</p><p>dasdasd</p><p>dasdasd</p><p>dasdasd</p><p>dasdasd</p><p>dasdasd</p><p>dasdasd</p><p>dasdasd</p><p>dasdasd</p><p>dasdasd</p><p>dasdasd</p><p>dasdasd</p><p>dasdasd</p><p>dasdasd</p><p>dasdasd</p><p>dasdasd</p><p>dasdasd</p><p>dasdasd</p><p>dasdasd</p><p>dasdasd</p><p>dasdasd</p><p>dasdasd</p><p>dasdasd</p><p>dasdasd</p><p>dasdasd</p><p>dasdasd</p><p>dasdasd</p><p>dasdasd</p><p>dasdasd</p><p>dasdasd</p><p>dasdasd</p><p>dasdasd</p><p>dasdasd</p><p>dasdasd</p><p>dasdasd</p><p>dasdasd</p><p>dasdasd</p><p>dasdasd</p><p>dasdasd</p><p>dasdasd</p><p>dasdasd</p><p>dasdasd</p><p>dasdasd</p><p>dasdasd</p><p>dasdasd</p><p>dasdasd</p><p>dasdasd</p><p>dasdasd</p><p>dasdasd</p><p>dasdasd</p><p>dasdasd</p><p>dasdasd</p><p>dasdasd</p><p>dasdasd</p><p>dasdasd</p><p>dasdasd</p><p>dasdasd</p><p>dasdasd</p><p>dasdasd</p><p>dasdasd</p><p>dasdasd</p><p>dasdasd</p><p>dasdasd</p><p>dasdasd</p><p>dasdasd</p><p>dasdasd</p><p>dasdasd</p><p>dasdasd</p><p>dasdasd</p><p>dasdasd</p><p>dasdasd</p><p>dasdasd</p><p>dasdasd</p><p>dasdasd</p><p>dasdasd</p><p>dasdasd</p><p>dasdasd</p><p>dasdasd</p><p>dasdasd</p><p>dasdasd</p><p>dasdasd</p><p>dasdasd</p><p>dasdasd</p><p>dasdasd</p><p>dasdasd</p><p>dasdasd</p><p>dasdasd</p><p>dasdasd</p><p>dasdasd</p><p>dasdasd</p><p>dasdasd</p><p>dasdasd</p><p>dasdasd</p><p>dasdasd</p><p>dasdasd</p><p>dasdasd</p><p>dasdasd</p><p>dasdasd</p><p>dasdasd</p><p>dasdasd</p><p>dasdasd</p><p>dasdasd</p><p>dasdasd</p><p>dasdasd</p><p>dasdasd</p><p>dasdasd</p><p>dasdasd</p><p>dasdasd</p><p>dasdasd</p><p>dasdasd</p><p>dasdasd</p><p>dasdasd</p><p>dasdasd</p><p>dasdasd</p>
Important: position and offset is relative to parent tag's position and offset
I am working on Accelerated mobile page(AMP). Here, on window scroll I want to get the top position of current scrolled viewport.
I have tried the below solutions:
window.addEventListener('scroll', function() {
let ele = document.getElementById('amp-main-container');;
console.log(ele.top)
});
OR
window.addEventListener('scroll', function() {
let ele = document.getElementById('amp-main-container');;
console.log(ele.scrollTop)
})
The amp-main-container is the parent folder of the structure
The console.log prints undefined on scroll.
I have also tried:
window.addEventListener('scroll', function() {
let ele = document.getElementById('amp-main-container');
var viewportOffset = ele.getBoundingClientRect();
console.log(viewportOffset.top)
});
The above solution shows ele.getBoundingClientRect is not a function error.
I need to find the the viewport scrollTop position in AMP on scroll. Thank you.
I know how to make this scroll effect to an element having some class/id. What I don't get is to make the scroll stop at 20px above this element. I've seen examples that do it with document.getElementById() . like this:
function scrollToJustAbove(element, margin=20) {
let dims = element.getBoundingClientRect();
window.scrollTo(window.scrollX, dims.top - margin);
}
But, in my case I also need a smooth transition that is what I want (like my link in plnrk). How can I do it?
this is my code:
https://plnkr.co/edit/3NX4FK5QrjiTwYgK5vwj?p=preview
setTimeout(() => {
const classElement = document.getElementsByClassName("myclass");
if(classElement.length > 0){
classElement[0].scrollIntoView({ block: 'start', behavior: 'smooth'});
}
}, 100);
Use window.scrollTo() instead of element.scrollIntoView()
The scrollTo method is Polymorphic. Apart from the params you already know, it instead also takes just an object (dictionary) in which you can specify the scroll behavior, like so:
<script>
function scrollToJustAbove(element, margin=20) {
let dims = element.getBoundingClientRect();
window.scrollTo({
top: dims.top - margin,
behavior: 'smooth'
});
}
setTimeout(() => {
const classElement = document.getElementsByClassName("myclass");
if(classElement.length > 0){
scrollToJustAbove(classElement[0]);
}
}, 100);
</script>
Working Example: https://plnkr.co/edit/UevhAN4NmTCdw65dzuPe?p=preview