fix scrolling for markdown content, which is loaded asynchronous

The code to find and scroll to the anchor is now moved from the
ScrollToTop component to the MarkdownView. The anchor with the id from
location hash, is searched after the MarkdownView and all its children
finished rendering.
This commit is contained in:
Sebastian Sdorra
2019-05-21 10:22:53 +02:00
parent 6f962ff4ce
commit 033c213cf2
2 changed files with 34 additions and 18 deletions

View File

@@ -4,12 +4,17 @@ import SyntaxHighlighter from "./SyntaxHighlighter";
import Markdown from "react-markdown/with-html";
import {binder} from "@scm-manager/ui-extensions";
import MarkdownHeadingRenderer from "./MarkdownHeadingRenderer";
import { withRouter } from "react-router-dom";
type Props = {
content: string,
renderContext?: Object,
renderers?: Object,
enableAnchorHeadings: boolean
enableAnchorHeadings: boolean,
// context props
location: any
};
class MarkdownView extends React.Component<Props> {
@@ -18,10 +23,27 @@ class MarkdownView extends React.Component<Props> {
enableAnchorHeadings: false
};
contentRef: ?HTMLDivElement;
constructor(props: Props) {
super(props);
}
componentDidUpdate() {
// we have to use componentDidUpdate, because we have to wait until all
// children are rendered and componentDidMount is called before the
// markdown content was rendered.
const hash = this.props.location.hash;
if (this.contentRef && hash) {
// we query only child elements, to avoid strange scrolling with multiple
// markdown elements on one page.
const element = this.contentRef.querySelector(hash);
if (element && element.scrollIntoView) {
element.scrollIntoView();
}
}
}
render() {
const {content, renderers, renderContext, enableAnchorHeadings} = this.props;
@@ -45,15 +67,17 @@ class MarkdownView extends React.Component<Props> {
}
return (
<Markdown
className="content"
skipHtml={true}
escapeHtml={true}
source={content}
renderers={rendererList}
/>
<div ref={el => (this.contentRef = el)}>
<Markdown
className="content"
skipHtml={true}
escapeHtml={true}
source={content}
renderers={rendererList}
/>
</div>
);
}
}
export default MarkdownView;
export default withRouter(MarkdownView);

View File

@@ -11,15 +11,7 @@ type Props = {
class ScrollToTop extends React.Component<Props> {
componentDidUpdate(prevProps) {
if (this.props.location.pathname !== prevProps.location.pathname) {
const hash = this.props.location.hash;
if (hash) {
const element = document.getElementById(hash.substring(1));
if (element && element.scrollIntoView) {
element.scrollIntoView();
}
} else {
window.scrollTo(0, 0);
}
window.scrollTo(0, 0);
}
}