Vue 3 - Always scroll to specific position on page when component appears - javascript

I have a basic form component and that shows up once I click a button (router is not used). I want the scroll position of the form to scroll down a bit (ex. y-axis of 40) once the form shows up, but I'm not entirely sure how to achieve this. There are various examples about this, but I couldn't get any of them to work. Can someone kindly advice a solution for this, please? I also started using vue 3.
<template>
<div class="appointment-wrapper" :class="[showForm ? 'appointment' : 'appointment-success']">
// Scroll down to a certain point
// ....
<form #submit.prevent="validateForm" novalidate>
// ....
</form>
</div>
</div>
</template>

If you need to scroll to an element position
document.getElementById(el).scrollIntoView();
Or if you need to scroll by the axis
window.scrollTo(0, 1000)

you can use window.scrollTo(0, 40) if the condition is true after you clicked the button.
Vue.createApp({
data() {
return {
showForm: true
}
},
mounted() {
if (this.showForm) window.scrollTo(0, 400) // only demo value - use 40
}
}).mount('#options-api')
#options-api {
height: 1000px;
}
<script src="https://unpkg.com/vue#next"></script>
<div id="options-api">
<h1>hidden title</h1>
</div>

Related

How to change shared state in Alpine.js?

I'm trying to hide multiple elements inside the DOM by changing shared state when window is resized.
<body class="font-body relative" x-data="{hideOnMobile:false}">
<section class="mt-5" :class={'section' : !hideOnMobile , 'hidden' : hideOnMobile}">
...
</section>
</body>
And when i try to
window.onresize = function (event) {
let data = document.querySelector('[x-data]');
if (window.innerWidth > 639) {
return data.__x.$data.hideOnMobile = true;
}
};
It should change the state ** hideOnMobile** to true but it doesn't somehow any idea?
Have you tried using #resize.window? (ie. adding the resize listener using Alpine.js) it should make your code simpler than using window.onresize + trying to update Alpine.js __x.$data internal.
<body
class="font-body relative"
x-data="{hideOnMobile:false}"
#resize.window="hideOnMobile = window.innerWidth > 639"
>
<section class="mt-5" :class={'section' : !hideOnMobile , 'hidden' : hideOnMobile}">
...
</section>
</body>
You have no space before x-data attribute. Try to change this line:
<body class="font-body relative"x-data="{hideOnMobile:false}">
to this:
<body class="font-body relative" x-data="{hideOnMobile:false}">
Looks like this is used as an example in the AlpineJS readme. Check this out:
.window modifier Example:
<div x-on:resize.window="isOpen = window.outerWidth > 768 ? false : open"></div>
Adding .window to an event listener will install the listener on the
global window object instead of the DOM node on which it is declared.
This is useful for when you want to modify component state when
something changes with the window, like the resize event. In this
example, when the window grows larger than 768 pixels wide, we will
close the modal/dropdown, otherwise maintain the same state.

Check if user scrolled beyond certain amount

I need show button backtotop only if user has scrolled beyond > 250. How I can do it?
My code:
<template>
<div>
<button v-if="checkScroll" class="goTop" #click="backToTop">
<i class="fa fa-angle-up" aria-hidden="true"></i>
</button>
</div>
</template>
<script>
export default {
methods: {
computed: {
checkScroll() {
if ($(document).scrollTop() > 250) {
return true;
} else {
return false;
}
}
},
backToTop() {
this.$scrollTo('html');
},
}
}
</script>
My code is not working. Errors I do not get. Button is hidden.
Also don't forget to destroy the event:
new Vue({
el: "#app",
data() {
return {
scroll: null
}
},
methods: {
handleScroll(e) {
this.scroll = window.scrollY || window.scrollTop
}
},
created() {
window.addEventListener('scroll', this.handleScroll);
},
destroyed() {
window.removeEventListener('scroll', this.handleScroll);
}
})
html {
height: 3000px; /* some random height for demonstration purpose */
}
button {
position: fixed;
}
<script src="https://cdn.jsdelivr.net/npm/vue#2.6.2/dist/vue.js"></script>
<!-- scroll to see the button -->
<div id="app">
<button v-show="scroll > 250">foobar</button>
</div>
Use the onScroll event in Javascript to detect when the user scrolls down/up and use scrollTop() to automatically move to the top of the page when the button is clicked.
Make sure it is position:fixed;.
For more info, check out these:
onScroll
scrollTop()
To show/hide the button just change it's size using HTML DOM methods. For example:
document.getElementsByClassName("goTop")[0].width = 30;
codepen.io has great sketches for in demand features like this all for free. here is a scroll to top functionality page you can tweak to fit your needs hopefully https://codepen.io/rolandtoth/pen/eMamVK
.scrolltop-wrap {
$size: 3rem;
$offsetBottom: 2rem;
$offsetHorizontal: 2rem;
$scrollToRevealDistance: 12rem; // scroll offset to reveal scroll-to-top link
It's all scss instead of javascript. Here is a scss to css generator you can use, https://www.cssportal.com/scss-to-css/

React.js keep scroll at bottom

I have a div that grows in height as an animation. Instead of growing outside of the viewable area (and user having to scroll down), I'd like the window to automatically scroll with the div height. Locking the scroll position at the bottom of the page would work.
!!This is in React!!
I've tried millions of google/SO answers, none work/ arent specific enough.
code https://github.com/coryb08/corydbaker npm install && npm start
You provided very little information, but since we know it's in React, you could use JavaScript to make sure your div is scrolled all the way to the bottom at all all times.
class FullMenu extends Component {
constructor() {
super()
this.state = {
class: "",
div: ""
}
this.scrollToBottom = this.scrollToBottom.bind(this);
}
componentDidMount() {
setInterval(this.scrollToBottom, 20);
}
scrollToBottom() {
var scrollingElement = (document.scrollingElement || document.body); /* you could provide your scrolling element with react ref */
scrollingElement.scrollTop = scrollingElement.scrollHeight;
}
render() {
return (
<div id="FullMenu">
{this.state.div}
<div id="triangleDiv">
<img
className={this.state.class}
onClick={() => {
this.setState({ class: "bounce" })
let that = this
setTimeout(function() {
that.setState({
class: "",
div: <div className="menuDiv" />
})
}, 1000)
}}
src={triangle}
id="triangle"
/>
</div>
</div>
)
}
}
Note that above solution keeps the window scrolled at all times. If you wanted to scroll it only during animation, then you should use react's CSSTransitionGroup and use clearInterval to stop this behavior in transitionEnd lifecycle hook.
You can use CSS alone
all you have to do is set the div styling
display: flex;
flex-direction: column-reverse
this should flip the div scroll and position it at the bottom

Chat type - scroll to bottom - angular 2

Need to scroll to bottom automatically once messages are being added in a chat.
Tried AfterViewChecked method of implementing this, as suggessted in
[angular2 scroll to bottom (chat style) - It works fine as it makes the scroll move to bottom. But when we try scrolling up as soon as we add a message in the chat, it is not allowing and it again pushes the view to the bottom of the chat
Please suggest a workaround on this.
The below code worked for me for my angular 4 chat application
My component.html
<div class="feedBody" #scrollMe (scroll)="onScroll()" >
<div class="feedList">
</div>
</div>
My component.css
.feedBody {
height: 235px;
overflow-y: auto;
}
My component.ts
scrollToBottom():void{
if (this.disableScrollDown) {
return
}
try {
this.myScrollContainer.nativeElement.scrollTop = this.myScrollContainer.nativeElement.scrollHeight;
} catch(err) { }
}
onScroll(){
let element = this.myScrollContainer.nativeElement;
let atBottom = (element.scrollTop+200) >= (element.scrollHeight - element.offsetHeight);
if (atBottom) {
this.disableScrollDown = false
} else {
this.disableScrollDown = true
}
}
I was using element.scrollTop+200 because I wanted a behaviour where I should not compulsorily present at the bottom of the screen but can be a little top by 200px.
Hope it works for you.

Scroll Javascript functions for different parent divs

I have a simple javascript scroll function that fixes my sidebar navigation and works fine on it's own, but I need to adjust it so different page types have different scroll events. Example: pages with banners need to have the fixed sidebar at a different scroll point that pages without a sidebar.
The indicator of a different page will be that the sidebar for a page without a banner will have a parent div that a page with a banner will not have. I am using a wordpress theme so my customization on this is limited.
Below is my example HTML and JS, but you can also see it at : http://jsfiddle.net/61L4ac2j/
HTML:
<div id="mk-page-id-1" class="theme-page-wrapper mk-main-wrapper">
<aside id="mk-sidebar" class="mk-builtin test">
<div class="sidebar-wrapper" style="min-height:600px;">
Page without banner example
</div>
</aside>
</div>
<div id="mk-page-id-2" class="theme-page-wrapper">
</div>
<div class="theme-page-wrapper">
<aside id="mk-sidebar" class="mk-builtin">
<div class="sidebar-wrapper" style="min-height:600px;">
Page with banner example
</div>
</aside>
</div>
JS:
$(function() {
var div = $(".sidebar-wrapper");
$(window).scroll(function() {
var scroll = $(window).scrollTop();
if (($("sidebar-wrapper").parent().parent("mk-main-wrapper")) & (scroll > 147)) {
div.css( "background", "yellow" );
} else if (scroll > 263) {
div.css( "background", "green" );
} else {
div.css( "background", "blue" );
}
});
});
For simplification purposes, I used background color, but my actual JS will use "addclass". See JS below:
$(function() {
var div = $(".sidebar-wrapper");
$(window).scroll(function() {
var scroll = $(window).scrollTop();
if ($("sidebar-wrapper").parent().parent("mk-main-wrapper") & scroll > 147) {
div.addClass("fixed-product-nav");
} else if (scroll > 263) {
div.addClass("fixed-product-nav");
} else {
div.removeClass("fixed-product-nav");
}
});
});
The issue is I cannot get the first IF Statement true, which you can see at the JSFiddle. It looks like something with the parent elements.
I feel like I'm close and just missing something.
Thanks!
jQuery objects will always be truthy. You need to check the length to see if it is greater than zero.
You also do not have a class selector, it is missing the .
Also & is not correct, it needs to be &&
$("sidebar-wrapper").parent().parent("mk-main-wrapper") & scroll > 147
to
$(".sidebar-wrapper").closest(".mk-main-wrapper").length && scroll > 147

Categories

Resources