I want to build an indexed letters. When I click the letter (for example A,B,C). It should be scrolling to the belongs title. I used scrollIntoView here. Everythings okey except "block:start". When I want to the scrolling to title of start, whole page scrolling with container.
Here my gif about issue
Here my html & css & javascript code.
const scrollTo = id => {
let ref = document.getElementById(id)
if (ref /* + other conditions */) {
ref.scrollIntoView({
behavior: "smooth",
block: "start",
inline: "start",
})
}
}
<div className="glossary">
<div className="glossary-items grid">
<div className="d-flex ">
<div className="glossary-letters ">
<ul>
{letter.map(item => (
<li onClick={() => scrollTo(item)}>
<a> {item}</a>
</li>
))}
</ul>
</div>
<div className="glossary-titles">
<ul>
{glossary.map((item, index) => (
<div key={item.group}>
<li id={item.group}>{item.group}</li>
{item.children.map((item2, i) => (
<li key={i}>
<Link
activeClassName="glossary-titles-active"
to={`/en/sozluk/${item2.first_name + item2.id}`}
>
{item2.first_name}
</Link>
</li>
))}
</div>
))}
</ul>
</div>
</div>
<div className="glossary-content ml-5">
<Router>
<Glossary path="en/sozluk/:id" />
</Router>
</div>
</div>
</div>
There is related question to that
You could use scrollTo
function of the parent element to scroll to specific child element.
Example
const { useState, useEffect, useRef } = React;
const App = () => {
const [list, setList] = useState([]);
const [keywords, setKeywords] = useState([]);
const refs = useRef(null);
const parentRef = useRef(null);
useEffect(() => {
const newList = Array(25).fill(0).map((pr, index) => String.fromCharCode(65 + index));
const newKeywords = newList.flatMap(pr => [pr, ...newList.map(npr => pr + npr)]);
refs.current = newList.reduce((acc, letter) => {
acc[letter] = React.createRef();
return acc;
}, {});
setList(newList);
setKeywords(newKeywords);
}, [])
const onClick = ({target: {dataset: {letter}}}) => {
const element = refs.current[letter].current;
const parent = parentRef.current;
const onScroll = () => {
const relativeTop = window.scrollY > parent.offsetTop ? window.scrollY : parent.offsetTop
parent.scrollTo({
behavior: "smooth",
top: element.offsetTop - relativeTop
});
}
window.removeEventListener("scroll", onScroll);
window.addEventListener("scroll", onScroll);
onScroll();
/*
element.scrollIntoView({
behavior: "smooth",
block: "start",
inline: "start",
})
*/
}
const tryAssignRef = (letter) => {
return list.indexOf(letter) > -1 ? {ref: refs.current[letter]} : {};
}
/// ...{ref: {refs.current['A']}}
return <div className="container">
<div className="header">
</div>
<div className="body">
<div className="left">
<div className="letters">{list.map(pr => <div className="letter" onClick={onClick} data-letter={pr} key={pr}>{pr}</div>)}</div>
<div ref={parentRef} className="keywords">{keywords.map(pr => <div {...tryAssignRef(pr)} key={pr}>{pr}</div>)}</div>
</div>
<div className="right">
</div>
</div>
</div>
}
ReactDOM.render(
<App />,
document.getElementById('root')
);
.container, .body, .left {
display: flex;
}
.container {
flex-direction: column;
}
.header {
flex: 0 0 100px;
border: 1px solid black;
}
.body {
height: 1000px;
}
.left {
flex: 1;
}
.right {
flex: 2;
}
.left {
justify-content: space-between;
}
.letter {
padding: 2px 0;
cursor: pointer;
}
.letters, .keywords {
padding: 0 10px;
}
.keywords {
overflow-y: scroll;
}
<script src="https://unpkg.com/react/umd/react.development.js"></script>
<script src="https://unpkg.com/react-dom/umd/react-dom.development.js"></script>
<script src="https://unpkg.com/babel-standalone@6/babel.min.js"></script>
<div id="root"></div>