Reputation: 297
I have a vue page with two divs. The Select-Div has a list of elements. If I click on an element from the list the Scroll-Div should scroll to the corresponding id element inside (preferably to the center of that element) which has the long description of the list element's details.
The problem that I'm having is that if I use scrollIntoView then the whole page is scrolling into the center also - so both the Scroll-Div is scrolling into its place but also the main page's scroll too.
Also note: inside the Scroll-Div there is a recursive component so I can only use ids and not refs.
My goTo() function on the main page:
goTo(id) {
const element = document.getElementById(`Id-${id}`);
if (element) {
element.scrollIntoView({
block: "center",
behavior: "smooth",
});
}
},
This gets the emited id from the Select-Div and selects the corresponding html id from the Scroll-Div.
Upvotes: 1
Views: 1951
Reputation: 2236
It seems like scrollBy
is a good API for this.
https://developer.mozilla.org/en-US/docs/Web/API/Window/scrollBy
A code example in Vue 2 could look like this
<template>
<div class="select-component">
<div class="container">
<div class="scroll-div" ref="scrollDiv">
<p id="a">A lorem ipsum</p>
<p id="b">B lorem ipsum</p>
<p id="c">C lorem ipsum</p>
</div>
<div class="select-div">
<button @click="goto('a')">Goto a</button>
<button @click="goto('b')">Goto b</button>
<button @click="goto('c')">Goto c</button>
</div>
</div>
</div>
</template>
<script>
export default {
methods: {
goto(id) {
let scrollDiv = this.$refs.scrollDiv;
let el = scrollDiv.querySelector(`#${id}`);
if (el) {
let scrollDivRect = scrollDiv.getBoundingClientRect();
let idRect = el.getBoundingClientRect();
let y = scrollDivRect.y;
let y1 = idRect.y;
let offset = y1 - y;
scrollDiv.scrollBy({
top: offset,
behavior: "smooth",
});
}
},
},
};
</script>
Demo
Upvotes: 2