Hide an element when scroll to specific class - javascript

I Used this JQuery code to have a sticky "Go to top" button:
//sticky back-to-top button
(function (t) {
t(window).bind("scroll", function () {
500 < t(this).scrollTop()
? t(".back-to-top").fadeIn(400)
: t(".back-to-top").fadeOut(400);
}),
t(".back-to-top").click(function () {
t("html, body").animate({ scrollTop: "0px" }, 500);
});
})(jQuery);
this code works correctly.
but i want when this sticky button reaches a specific class called "go-top", disappears. sorry for my bad english.

You can use interception observer so when the target element with said class is in view, it triggers the callback to hide the button.
Example: The code might not be exact but it is meant to point in the direction to follow.
let options = {
root: document.querySelector('.go-top'),
rootMargin: '0px',
threshold: 1.0
}
let prevRatio = 0.0;
let observer = new IntersectionObserver(callback, options);
let target = document.querySelector('#back-to-top-button');
observer.observe(target);
function handleIntersect(entries, observer) {
entries.forEach((entry) => {
if (entry.intersectionRatio > prevRatio) {
entry.target.style.display = "none";
} else {
entry.target.style.backgroundColor = "block";
}
prevRatio = entry.intersectionRatio;
});
}
Let me know how it goes...
You can switch the root to null but this makes the button disappear as soon as the element with the class is in the viewport

Related

check if class exists on that page javascript

I have an index page and a dashboard, on the index I'm using typewriter and particlesjs on the index only, and on the dashboard I have a sidebar.
If I have all the code as-is, I get errors as the page is still looking for typewriter and particlesjs on all pages.
So I have attempted to wrap each section around an if so the plan is if that class or id exists on that page it will only render that JS. So I've created the following code.
edited code below based on groovy_guy's answer
document.querySelector('nav .toggle').addEventListener('click', e => {
document.querySelector('nav .hidden').classList.toggle('show')
});
let checkTypewriter = document.getElementById('typewriter');
if (checkTypewriter.length > 0) {
new Typewriter('#typewriter', {
strings: ['Website Developer', 'Freelancer' , 'System Admin'],
autoStart: true,
loop: true
});
}
let checkParticlesjs = document.getElementsByClassName('particlesjs');
if (checkParticlesjs.length > 0) {
let particles = Particles.init({
selector: '.particlesjs',
color: ['#48F2E3', '#48F2E3', '#48F2E3'],
connectParticles: true,
maxParticles: 200
});
}
let checkSidebar = document.getElementsByClassName('sidebar');
if (checkSidebar.length > 0) {
user_wants_collapse = false;
// Fetch all the details element.
const details = document.querySelectorAll("details");
// Add the onclick listeners.
details.forEach((targetDetail) => {
targetDetail.addEventListener("click", () => {
// Close all the details that are not targetDetail.
details.forEach((detail) => {
if (detail !== targetDetail) {
detail.removeAttribute("open");
};
});
});
});
document.querySelector('section').addEventListener('click', (ev) => {
// close any open details elements that this click is outside of
let target = ev.target;
let detailsClickedWithin = null;
while (target && target.tagName != 'DETAILS') {
target = target.parentNode;
};
if (target && target.tagName == 'DETAILS') {
detailsClickedWithin = target;
};
Array.from(document.getElementsByTagName('details')).filter(
(details) => details.open && details != detailsClickedWithin
).forEach(details => details.open = false);
// if the sidebar collapse is true and is re-expanded by clicking a menu item then clicking on the body should re-close it
if (user_wants_collapse == true && (document.querySelectorAll('.sidebar details'))) {
document.querySelector('body').classList.add('is--expand');
};
});
// when the sidebar menu is clicked this sets the user_wants_collapse var to true or false and toggles is--expand class on body
document.querySelector('.sidebar .menu-link').addEventListener('click', () => {
document.querySelector('body').classList.toggle('is--expand');
user_wants_collapse = !user_wants_collapse
document.querySelector('.sidebar').classList.toggle('is--expand');
// show all text
document.querySelectorAll('.sidebar .title').forEach((el) => {
el.classList.toggle('hidden');
});
// changing sidebar menu items and menu collapse icons
const icon = document.querySelector('.menu-link-arrows span');
if (icon.classList.contains('fa-angle-double-left')) {
icon.classList.remove('fa-angle-double-left');
icon.classList.add('fa-angle-double-right');
} else {
icon.classList.remove('fa-angle-double-right');
icon.classList.add('fa-angle-double-left');
}
});
// making sure the sidebar menu items re-expands the sidebar on click
let x = document.querySelectorAll('.sidebar details');
let i;
for (i = 1; i < x.length; i++) {
x[i].addEventListener('click', () => {
// changing sidebar menu items and menu collapse icons
// change menu items and menu collapse icons
const icon = document.querySelector('.sidebar-drop-parent-arrow span');
if (icon.classList.contains('fa-chevron-down')) {
icon.classList.remove('fa-chevron-down');
icon.classList.add('fa-chevron-up');
} else {
icon.classList.remove('fa-chevron-up');
icon.classList.add('fa-chevron-down');
}
if (document.querySelector('body').classList.contains('is--expand')) {
document.querySelector('body').classList.remove('is--expand');
};
});
};
};
when loading the JS I'm not getting any console errors but I'm not seeing any result of the JS.
Why don't you use querySelector()? I think that's more uniform across your codebase. Besides, I see that you only care about one element and not a list of elements, so this method is ideal since it gets the first element that encounters.
const checkTypewriter = document.querySelector('#typewriter')
if (checkTypewriter) {
// Element with an ID 'typewriter' exist in the DOM.
}
const checkParticlesjs = document.querySelector('.particlesjs')
if (checkParticlesjs) {
// Element with a class named "particlesjs" exist in the DOM.
}
Also, make sure to check if an element exist before attaching an event listener:
const toggleNav = document.querySelector('nav .toggle')
if (toggleNav) {
toggleNav.addEventListener('click', (e) => {
document.querySelector('nav .hidden').classList.toggle('show')
});
}
For Javascript:
var checkTypewriter = document.getElementsByClassName('typewriter');
if (checkTypewriter.length > 0) {
// Here write your code
}
var checkParticlesjs = document.getElementsByClassName('particlesjs');
if (checkParticlesjs.length > 0) {
// Here write your specific code
}
For JQuery:
if ($("#typewriter")[0]){
// Here write your code
}
if ($(".particlesjs")[0]){
// Here write your specific code
}
This is how you can check if your classes exist,

Side navigation menu responsive class to hide on window resize

Hey stackoverflow community!
I have a small issue regarding this JS logic to add a class name to my body tag to hide the side navigation menu upon window resizing. Let me try to explain the issue as clearly as I can. Currently I'm using a UI template by creativetime called Argon. The page when loaded on a full scaled width looks like this:
When I resize the window after the page has loaded it looks like this:
But when I refresh the page, the side navigation is no longer there as how it should be, which is like this:
After refreshing the page, resizing the window thereafter makes the side navigation to hide as it should. The sidenav just doesn't go hidden on first page load for some reason.
The JS for this is as follows:
var Layout = (function() {
function pinSidenav() {
$('.sidenav-toggler').addClass('active');
$('.sidenav-toggler').data('action', 'sidenav-unpin');
$('body').removeClass('g-sidenav-hidden').addClass('g-sidenav-show g-sidenav-pinned');
$('body').append('<div class="backdrop d-xl-none" data-action="sidenav-unpin" data-target='+$('#sidenav-main').data('target')+' />');
// Store the sidenav state in a cookie session
Cookies.set('sidenav-state', 'pinned');
}
function unpinSidenav() {
$('.sidenav-toggler').removeClass('active');
$('.sidenav-toggler').data('action', 'sidenav-pin');
$('body').removeClass('g-sidenav-pinned').addClass('g-sidenav-hidden');
$('body').find('.backdrop').remove();
// Store the sidenav state in a cookie session
Cookies.set('sidenav-state', 'unpinned');
}
// Set sidenav state from cookie
var $sidenavState = Cookies.get('sidenav-state') ? Cookies.get('sidenav-state') : 'pinned';
if($(window).width() > 1200) {
if($sidenavState == 'pinned') {
pinSidenav()
}
if(Cookies.get('sidenav-state') == 'unpinned') {
unpinSidenav()
}
$(window).resize(function() {
if( $('body').hasClass('g-sidenav-show') && !$('body').hasClass('g-sidenav-pinned')) {
$('body').removeClass('g-sidenav-show').addClass('g-sidenav-hidden');
}
})
}
if($(window).width() < 1200){
$('body').removeClass('g-sidenav-hide').addClass('g-sidenav-hidden');
$('body').removeClass('g-sidenav-show');
$(window).resize(function() {
if( $('body').hasClass('g-sidenav-show') && !$('body').hasClass('g-sidenav-pinned')) {
$('body').removeClass('g-sidenav-show').addClass('g-sidenav-hidden');
}
})
}
$("body").on("click", "[data-action]", function(e) {
e.preventDefault();
var $this = $(this);
var action = $this.data('action');
var target = $this.data('target');
// Manage actions
switch (action) {
case 'search-show':
target = $this.data('target');
$('body').removeClass('g-navbar-search-show').addClass('g-navbar-search-showing');
setTimeout(function() {
$('body').removeClass('g-navbar-search-showing').addClass('g-navbar-search-show');
}, 150);
setTimeout(function() {
$('body').addClass('g-navbar-search-shown');
}, 300)
break;
case 'search-close':
target = $this.data('target');
$('body').removeClass('g-navbar-search-shown');
setTimeout(function() {
$('body').removeClass('g-navbar-search-show').addClass('g-navbar-search-hiding');
}, 150);
setTimeout(function() {
$('body').removeClass('g-navbar-search-hiding').addClass('g-navbar-search-hidden');
}, 300);
setTimeout(function() {
$('body').removeClass('g-navbar-search-hidden');
}, 500);
break;
}
})
// Add sidenav modifier classes on mouse events
$('.sidenav').on('mouseenter', function() {
if(! $('body').hasClass('g-sidenav-pinned')) {
$('body').removeClass('g-sidenav-hide').removeClass('g-sidenav-hidden').addClass('g-sidenav-show');
}
})
$('.sidenav').on('mouseleave', function() {
if(! $('body').hasClass('g-sidenav-pinned')) {
$('body').removeClass('g-sidenav-show').addClass('g-sidenav-hide');
setTimeout(function() {
$('body').removeClass('g-sidenav-hide').addClass('g-sidenav-hidden');
}, 300);
}
})
// Make the body full screen size if it has not enough content inside
$(window).on('load resize', function() {
if($('body').height() < 800) {
$('body').css('min-height', '100vh');
$('#footer-main').addClass('footer-auto-bottom')
}
})
})();
Working JS Fiddle: https://jsfiddle.net/Vaulient/kthw39gs/6/

How to remove scroll event listener?

I am trying to remove scroll event listener when I scroll to some element. What I am trying to do is call a click event when some elements are in a viewport. The problem is that the click event keeps calling all the time or after first call not at all. (Sorry - difficult to explain) and I would like to remove the scroll event to stop calling the click function.
My code:
window.addEventListener('scroll', () => {
window.onscroll = slideMenu;
// offsetTop - the distance of the current element relative to the top;
if (window.scrollY > elementTarget.offsetTop) {
const scrolledPx = (window.scrollY - elementTarget.offsetTop);
// going forward one step
if (scrolledPx < viewportHeight) {
// console.log('section one');
const link = document.getElementById('2');
if (link.stopclik === undefined) {
link.click();
link.stopclik = true;
}
}
// SECOND STEP
if (viewportHeight < scrolledPx && (viewportHeight * 2) > scrolledPx) {
console.log('section two');
// Initial state
let scrollPos = 0;
window.addEventListener('scroll', () => {
if ((document.body.getBoundingClientRect()).top > scrollPos) { // UP
const link1 = document.getElementById('1');
link1.stopclik = undefined;
if (link1.stopclik === undefined) {
link1.click();
link1.stopclik = true;
}
} else {
console.log('down');
}
// saves the new position for iteration.
scrollPos = (document.body.getBoundingClientRect()).top;
});
}
if ((viewportHeight * 2) < scrolledPx && (viewportHeight * 3) > scrolledPx) {
console.log('section three');
}
const moveInPercent = scrolledPx / base;
const move = -1 * (moveInPercent);
innerWrapper.style.transform = `translate(${move}%)`;
}
});
You can only remove event listeners on external functions. You cannot remove event listeners on anonymous functions, like you have used.
Replace this code
window.addEventListener('scroll', () => { ... };
and do this instead
window.addEventListener('scroll', someFunction);
Then move your function logic into the function
function someFunction() {
// add logic here
}
You can then remove the click listener when some condition is met i.e. when the element is in the viewport
window.removeEventListener('scroll', someFunction);
Instead of listening to scroll event you should try using Intersection Observer (IO) Listening to scroll event and calculating the position of elements on each scroll can be bad for performance. With IO you can use a callback function whenever two elements on the page are intersecting with each other or intersecting with the viewport.
To use IO you first have to specify the options for IO. Since you want to check if your element is in view, leave the root element out.
let options = {
rootMargin: '0px',
threshold: 1.0
}
let observer = new IntersectionObserver(callback, options);
Then you specify which elements you want to watch:
let target = slideMenu; //document.querySelector('#oneElement') or document.querySelectorAll('.multiple-elements')
observer.observe(target); // if you have multiple elements, loop through them to add observer
Lastly you have to define what should happen once the element is in the viewport:
let callback = (entries, observer) => {
entries.forEach(entry => {
// Each entry describes an intersection change for one observed
// target element:
});
};
You can also unobserve an element if you don't need the observer anymore.
Check this polyfill from w3c to support older browsers.
Here is my scenario/code, call removeEventListener as return() in the useEffect hook.
const detectPageScroll = () => {
if (window.pageYOffset > YOFFSET && showDrawer) {
// do something
}
};
React.useEffect(() => {
if (showDrawer) {
window.addEventListener("scroll", detectPageScroll);
}
return () => {
window.removeEventListener("scroll", detectPageScroll);
};
}, [showDrawer]);

How to break animation and run it again?

I have a page with some anchors and links which lead on this anchors. I can click on the link and the anchor's background-color will become some color. With help of animation I make this backgound-color dissapear in 10 sec - first I make background-color white than I remove class and styles from element to reuse it.
But when I click on the link and go to the anchor which animation haven't finished, the color is not the same as the color on start of animation, it continue becoming more transpanent.
I want to click the same link again (for the anchor which hasn't finished dissapearing) and animation on this anchor have to stop and run again with full color of background. How can I do it?
The example of code:
$("a").each(function () {
$(this).click(function () {
const anchorName = this.href.slice(this.href.indexOf('#'));
goToAnchor(decodeURIComponent(anchorName));
});
});
const goToAnchor = (anchorId) => {
const anchor = document.getElementById(anchorId.replace('#', ''));
const nextElem = $(anchor).parent().text() !== '' ? $(anchor).parent() : $(anchor).parent().next();
$(nextElem).addClass('focus-on-anchor');
$(nextElem).clearQueue();
(function (elem) {
$(elem).animate({
backgroundColor: 'rgb(255,255,255)'
}, 10000, function () {
$(this).removeAttr('class style');
});
}(nextElem));
}
https://jsfiddle.net/fiorsaoirse/j247atLc/13/
All I had to do is to add checking on having 'style' in element before running the animation:
$("a").each(function () {
$(this).click(function () {
const anchorName = this.href.slice(this.href.indexOf('#'));
goToAnchor(decodeURIComponent(anchorName));
});
});
const goToAnchor = (anchorId) => {
const anchor = document.getElementById(anchorId.replace('#', ''));
const nextElem = $(anchor).parent().text() !== '' ? $(anchor).parent() : $(anchor).parent().next();
$(nextElem).addClass('focus-on-anchor');
$(nextElem).stop().clearQueue();
if ($(nextElem).is('[style]')) {
// In case when animation hasn't stopped yet
$(nextElem).removeAttr('style');
}
makeElemDisappear($(nextElem));
}
const makeElemDisappear = (elem) => {
$(elem).animate({
backgroundColor: 'rgb(255,255,255)'
}, 10000, function () {
$(this).removeAttr('class style');
});
}

How to know scroll to element is done in Javascript?

I am using Javascript method Element.scrollIntoView()
https://developer.mozilla.org/en-US/docs/Web/API/Element/scrollIntoView
Is there any way I can get to know when the scroll is over. Say there was an animation, or I have set {behavior: smooth}.
I am assuming scrolling is async and want to know if there is any callback like mechanism to it.
There is no scrollEnd event, but you can listen for the scroll event and check if it is still scrolling the window:
var scrollTimeout;
addEventListener('scroll', function(e) {
clearTimeout(scrollTimeout);
scrollTimeout = setTimeout(function() {
console.log('Scroll ended');
}, 100);
});
2022 Update:
The CSS specs recently included the overscroll and scrollend proposal, this proposal adds a few CSS overscroll attributes, and more importantly to us, a scrollend event.
Browsers are still working on implementing it. (It's already available in Chromium under the Web Platforms Experiments flag.)
We can feature-detect it by simply looking for
if (window.onscrollend !== undefined) {
// we have a scrollend event
}
While waiting for implementations everywhere, the remaining of this answer is still useful if you want to build a polyfill:
For this "smooth" behavior, all the specs say[said] is
When a user agent is to perform a smooth scroll of a scrolling box box to position, it must update the scroll position of box in a user-agent-defined fashion over a user-agent-defined amount of time.
(emphasis mine)
So not only is there no single event that will fire once it's completed, but we can't even assume any stabilized behavior between different browsers.
And indeed, current Firefox and Chrome already differ in their behavior:
Firefox seems to have a fixed duration set, and whatever the distance to scroll is, it will do it in this fixed duration ( ~500ms )
Chrome on the other hand will use a speed, that is, the duration of the operation will vary based on the distance to scroll, with an hard-limit of 3s.
So this already disqualifies all the timeout based solutions for this problem.
Now, one of the answers here has proposed to use an IntersectionObserver, which is not a too bad solution, but which is not too portable, and doesn't take the inline and block options into account.
So the best might actually be to check regularly if we did stop scrolling. To do this in a non-invasive way, we can start an requestAnimationFrame powered loop, so that our checks are performed only once per frame.
Here one such implementation, which will return a Promise that will get resolved once the scroll operation has finished.
Note: This code misses a way to check if the operation succeeded, since if an other scroll operation happens on the page, all current ones are cancelled, but I'll leave this as an exercise for the reader.
const buttons = [ ...document.querySelectorAll( 'button' ) ];
document.addEventListener( 'click', ({ target }) => {
// handle delegated event
target = target.closest('button');
if( !target ) { return; }
// find where to go next
const next_index = (buttons.indexOf(target) + 1) % buttons.length;
const next_btn = buttons[next_index];
const block_type = target.dataset.block;
// make it red
document.body.classList.add( 'scrolling' );
smoothScroll( next_btn, { block: block_type })
.then( () => {
// remove the red
document.body.classList.remove( 'scrolling' );
} )
});
/*
*
* Promised based scrollIntoView( { behavior: 'smooth' } )
* #param { Element } elem
** ::An Element on which we'll call scrollIntoView
* #param { object } [options]
** ::An optional scrollIntoViewOptions dictionary
* #return { Promise } (void)
** ::Resolves when the scrolling ends
*
*/
function smoothScroll( elem, options ) {
return new Promise( (resolve) => {
if( !( elem instanceof Element ) ) {
throw new TypeError( 'Argument 1 must be an Element' );
}
let same = 0; // a counter
let lastPos = null; // last known Y position
// pass the user defined options along with our default
const scrollOptions = Object.assign( { behavior: 'smooth' }, options );
// let's begin
elem.scrollIntoView( scrollOptions );
requestAnimationFrame( check );
// this function will be called every painting frame
// for the duration of the smooth scroll operation
function check() {
// check our current position
const newPos = elem.getBoundingClientRect().top;
if( newPos === lastPos ) { // same as previous
if(same ++ > 2) { // if it's more than two frames
/* #todo: verify it succeeded
* if(isAtCorrectPosition(elem, options) {
* resolve();
* } else {
* reject();
* }
* return;
*/
return resolve(); // we've come to an halt
}
}
else {
same = 0; // reset our counter
lastPos = newPos; // remember our current position
}
// check again next painting frame
requestAnimationFrame(check);
}
});
}
p {
height: 400vh;
width: 5px;
background: repeat 0 0 / 5px 10px
linear-gradient(to bottom, black 50%, white 50%);
}
body.scrolling {
background: red;
}
<button data-block="center">scroll to next button <code>block:center</code></button>
<p></p>
<button data-block="start">scroll to next button <code>block:start</code></button>
<p></p>
<button data-block="nearest">scroll to next button <code>block:nearest</code></button>
<p></p>
<button>scroll to top</button>
You can use IntersectionObserver, check if element .isIntersecting at IntersectionObserver callback function
const element = document.getElementById("box");
const intersectionObserver = new IntersectionObserver((entries) => {
let [entry] = entries;
if (entry.isIntersecting) {
setTimeout(() => alert(`${entry.target.id} is visible`), 100)
}
});
// start observing
intersectionObserver.observe(element);
element.scrollIntoView({behavior: "smooth"});
body {
height: calc(100vh * 2);
}
#box {
position: relative;
top:500px;
}
<div id="box">
box
</div>
I stumbled across this question as I wanted to focus a particular input after the scrolling is done (so that I keep the smooth scrolling).
If you have the same usecase as me, you don't actually need to wait for the scroll to be finished to focus your input, you can simply disable the scrolling of focus.
Here is how it's done:
window.scrollTo({ top: 0, behavior: "smooth" });
myInput.focus({ preventScroll: true });
cf: https://github.com/w3c/csswg-drafts/issues/3744#issuecomment-685683932
Btw this particular issue (of waiting for scroll to finish before executing an action) is discussed in CSSWG GitHub here: https://github.com/w3c/csswg-drafts/issues/3744
Solution that work for me with rxjs
lang: Typescript
scrollToElementRef(
element: HTMLElement,
options?: ScrollIntoViewOptions,
emitFinish = false,
): void | Promise<boolean> {
element.scrollIntoView(options);
if (emitFinish) {
return fromEvent(window, 'scroll')
.pipe(debounceTime(100), first(), mapTo(true)).toPromise();
}
}
Usage:
const element = document.getElementById('ELEM_ID');
scrollToElementRef(elment, {behavior: 'smooth'}, true).then(() => {
// scroll finished do something
})
These answers above leave the event handler in place even after the scrolling is done (so that if the user scrolls, their method keeps getting called). They also don't notify you if there's no scrolling required. Here's a slightly better answer:
$("#mybtn").click(function() {
$('html, body').animate({
scrollTop: $("div").offset().top
}, 2000);
$("div").html("Scrolling...");
callWhenScrollCompleted(() => {
$("div").html("Scrolling is completed!");
});
});
// Wait for scrolling to stop.
function callWhenScrollCompleted(callback, checkTimeout = 200, parentElement = $(window)) {
const scrollTimeoutFunction = () => {
// Scrolling is complete
parentElement.off("scroll");
callback();
};
let scrollTimeout = setTimeout(scrollTimeoutFunction, checkTimeout);
parentElement.on("scroll", () => {
clearTimeout(scrollTimeout);
scrollTimeout = setTimeout(scrollTimeoutFunction, checkTimeout);
});
}
body { height: 2000px; }
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<button id="mybtn">Scroll to Text</button>
<br><br><br><br><br><br><br><br>
<div>example text</div>
i'm not an expert in javascript but i made this with jQuery. i hope it helps
$("#mybtn").click(function() {
$('html, body').animate({
scrollTop: $("div").offset().top
}, 2000);
});
$( window ).scroll(function() {
$("div").html("scrolling");
if($(window).scrollTop() == $("div").offset().top) {
$("div").html("Ended");
}
})
body { height: 2000px; }
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<button id="mybtn">Scroll to Text</button>
<br><br><br><br><br><br><br><br>
<div>example text</div>
I recently needed callback method of element.scrollIntoView(). So tried to use the Krzysztof Podlaski's answer.
But I could not use it as is. I modified a little.
import { fromEvent, lastValueFrom } from 'rxjs';
import { debounceTime, first, mapTo } from 'rxjs/operators';
/**
* This function allows to get a callback for the scrolling end
*/
const scrollToElementRef = (parentEle, childEle, options) => {
// If parentEle.scrollTop is 0, the parentEle element does not emit 'scroll' event. So below is needed.
if (parentEle.scrollTop === 0) return Promise.resolve(1);
childEle.scrollIntoView(options);
return lastValueFrom(
fromEvent(parentEle, 'scroll').pipe(
debounceTime(100),
first(),
mapTo(true)
)
);
};
How to use
scrollToElementRef(
scrollableContainerEle,
childrenEle,
{
behavior: 'smooth',
block: 'end',
inline: 'nearest',
}
).then(() => {
// Do whatever you want ;)
});

Categories

Resources