mirror of
https://github.com/ant-design/ant-design.git
synced 2025-01-18 22:36:31 +08:00
Anchor position with offsetTop bug (#4817)
+ close #4706 + `<Anchor offset={x} />` will calculate target position correctly.
This commit is contained in:
parent
5d2513ce91
commit
9711c6bbf6
@ -9,6 +9,7 @@ export interface AnchorLinkProps {
|
||||
prefixCls?: string;
|
||||
children?: any;
|
||||
title?: React.ReactNode;
|
||||
offsetTop: number;
|
||||
bounds: number;
|
||||
target?: () => HTMLElement | Window;
|
||||
affix?: boolean;
|
||||
@ -31,9 +32,9 @@ export default class AnchorLink extends React.Component<AnchorLinkProps, any> {
|
||||
private _component: Element;
|
||||
|
||||
setActiveAnchor() {
|
||||
const { bounds, href, affix } = this.props;
|
||||
const { bounds, offsetTop, href, affix } = this.props;
|
||||
const { anchorHelper } = this.context;
|
||||
const active = affix && anchorHelper && anchorHelper.getCurrentAnchor(bounds) === href;
|
||||
const active = affix && anchorHelper && anchorHelper.getCurrentAnchor(offsetTop, bounds) === href;
|
||||
if (active && anchorHelper) {
|
||||
anchorHelper.setActiveAnchor(this._component);
|
||||
}
|
||||
@ -55,6 +56,7 @@ export default class AnchorLink extends React.Component<AnchorLinkProps, any> {
|
||||
onClick: this.props.onClick,
|
||||
prefixCls: this.props.prefixCls,
|
||||
affix: this.props.affix,
|
||||
offsetTop: this.props.offsetTop,
|
||||
});
|
||||
}
|
||||
return child;
|
||||
@ -73,14 +75,14 @@ export default class AnchorLink extends React.Component<AnchorLinkProps, any> {
|
||||
} else {
|
||||
e.stopPreventDefault();
|
||||
const scrollToFn = anchorHelper ? anchorHelper.scrollTo : scrollTo;
|
||||
scrollToFn(href);
|
||||
scrollToFn(href, this.props.offsetTop);
|
||||
}
|
||||
}
|
||||
|
||||
render() {
|
||||
const { prefixCls, href, children, title, bounds, affix } = this.props;
|
||||
const { prefixCls, href, children, title, bounds, offsetTop, affix } = this.props;
|
||||
const { anchorHelper } = this.context;
|
||||
const active = affix && anchorHelper && anchorHelper.getCurrentAnchor(bounds) === href;
|
||||
const active = affix && anchorHelper && anchorHelper.getCurrentAnchor(offsetTop, bounds) === href;
|
||||
const cls = classNames({
|
||||
[`${prefixCls}-link`]: true,
|
||||
[`${prefixCls}-link-active`]: active,
|
||||
|
@ -43,14 +43,14 @@ export type Section = {
|
||||
section: any;
|
||||
};
|
||||
|
||||
export function scrollTo(href, target = getDefaultTarget, callback = () => {}) {
|
||||
export function scrollTo(href, offsetTop = 0, target = getDefaultTarget, callback = () => {}) {
|
||||
const scrollTop = getScroll(target(), true);
|
||||
const targetElement = document.getElementById(href.substring(1));
|
||||
if (!targetElement) {
|
||||
return;
|
||||
}
|
||||
const offsetTop = getOffsetTop(targetElement);
|
||||
const targetScrollTop = scrollTop + offsetTop;
|
||||
const eleOffsetTop = getOffsetTop(targetElement);
|
||||
const targetScrollTop = scrollTop + eleOffsetTop - offsetTop;
|
||||
const startTime = Date.now();
|
||||
const frameFunc = () => {
|
||||
const timestamp = Date.now();
|
||||
@ -91,7 +91,7 @@ class AnchorHelper {
|
||||
this.currentAnchor = component;
|
||||
}
|
||||
|
||||
getCurrentAnchor(bounds = 5) {
|
||||
getCurrentAnchor(offsetTop: number = 0, bounds = 5) {
|
||||
let activeAnchor = '';
|
||||
if (typeof document === 'undefined') {
|
||||
return activeAnchor;
|
||||
@ -100,9 +100,9 @@ class AnchorHelper {
|
||||
const linksPositions = (this.links
|
||||
.map(section => {
|
||||
const target = document.getElementById(section.substring(1));
|
||||
if (target && getOffsetTop(target) < bounds) {
|
||||
if (target && getOffsetTop(target) < offsetTop + bounds) {
|
||||
const top = getOffsetTop(target);
|
||||
if (top <= bounds) {
|
||||
if (top <= offsetTop + bounds) {
|
||||
return {
|
||||
section,
|
||||
top,
|
||||
@ -121,8 +121,8 @@ class AnchorHelper {
|
||||
return '';
|
||||
}
|
||||
|
||||
scrollTo(href, target = getDefaultTarget, callback = () => {}) {
|
||||
scrollTo(href, target, callback);
|
||||
scrollTo(href, offsetTop, target = getDefaultTarget, callback = () => {}) {
|
||||
scrollTo(href, offsetTop, target, callback);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -47,7 +47,7 @@ export default class Anchor extends React.Component<AnchorProps, any> {
|
||||
|
||||
handleScroll = () => {
|
||||
this.setState({
|
||||
activeAnchor: this.anchorHelper.getCurrentAnchor(this.props.bounds),
|
||||
activeAnchor: this.anchorHelper.getCurrentAnchor(this.props.offsetTop, this.props.bounds),
|
||||
});
|
||||
}
|
||||
|
||||
@ -85,7 +85,7 @@ export default class Anchor extends React.Component<AnchorProps, any> {
|
||||
clickAnchorLink = (href, component) => {
|
||||
this._avoidInk = true;
|
||||
this.refs.ink.style.top = `${component.offsetTop + component.clientHeight / 2 - 4.5}px`;
|
||||
this.anchorHelper.scrollTo(href, getDefaultTarget, () => {
|
||||
this.anchorHelper.scrollTo(href, this.props.offsetTop, getDefaultTarget, () => {
|
||||
this._avoidInk = false;
|
||||
});
|
||||
}
|
||||
@ -99,6 +99,7 @@ export default class Anchor extends React.Component<AnchorProps, any> {
|
||||
prefixCls: this.props.prefixCls,
|
||||
bounds: this.props.bounds,
|
||||
affix: this.props.affix,
|
||||
offsetTop: this.props.offsetTop,
|
||||
});
|
||||
}
|
||||
return child;
|
||||
|
Loading…
Reference in New Issue
Block a user