äžéšã«åºå®ããããŸãŸã®åºå®ããããŒãæã€ã°ãªãããäœæããå¿ èŠããããŠãŒã¹ã±ãŒã¹ããããŸãã åå¿ä»®æ³åã§ã¯ãããã¯2ã€ã®ã°ãªããã³ã³ããŒãã³ãïŒ1ã€ã¯ããããŒçšããã1ã€ã¯ã°ãªããæ¬äœçšïŒãäœæããã¹ã¯ããŒã«äœçœ®ãåæããŠãããããŒã°ãªããã®æ°Žå¹³ã¹ã¯ããŒã«ãã¡ã€ã³ã°ãªãããšåæããããã«ããããšã§å®çŸã§ããŸãã
ãã³ãã«ãµã€ãºãšæŠå¿µã®è€éãã®äž¡æ¹ã®èŠ³ç¹ãããReact-windowã軜éã«ä¿ã¡ãåå¥ã®ããã±ãŒãžãšããŠè¿œå æ©èœãæ§ç¯ããããšããŠããããšãç§ã¯ç¥ã£ãŠããŸãã ããã¯ç§ãåæããæ¹åã§ãã react-virtualizedã®ScrollSyncã³ã³ããŒãã³ããæœåºããããreact-windowã§åäœããããã«é©åãããããšãã§ãããšæããŸãã ãã ããããããããã«ã¯ãreact-windowã¯scrollLeftãšscrollTopã®å°éå ·ãåãå ¥ããŠãããããŒã°ãªããã®ã¹ã¯ããŒã«ãªãã»ãããçŽæ¥ç®¡çã§ããããã«ããå¿ èŠããããŸãã
ããã¯ããªããåãã§ãµããŒããããŠãŒã¹ã±ãŒã¹ã§ããïŒ ããã§ãªãå Žåã¯ããããèªåã§å®è£ ããããã«ã©ã®æ¹åã«é²ãã¹ããã«ã€ããŠã¢ããã€ã¹ããããŸããïŒ
ãã®ã©ã€ãã©ãªã«åãçµãã§ããã ãããããšãããããŸãã æ°å¹Žéreact-virtualizedã䜿çšããŠãã人ãšããŠãreact-windowã䜿ãå§ããã®ãç°¡åã§ãæåã«ããä»å ¥ãããŸããªããŠãããã©ãŒãã³ã¹ãåªããŠããããšã«æè¬ããŠããŸãã
ãŸãã芪åãªèšèãšæ£ã®ãã£ãŒãããã¯ã«æè¬ããŸãã ãããŸã§ã®ãšãããreact-windowãããŸãæ©èœããŠãããšèããŠããããã§ãïŒ
ScrollSyncã®ãããªã³ã³ããŒãã³ããreact-windowã«äŸåããã¹ã¿ã³ãã¢ãã³ããã±ãŒãžãšããŠãªãªãŒã¹ãããå¯èœæ§ãããããšã«åæããŸããããŠã£ã³ããŠåŠçã®ã³ã¢ã§ã¯ãªãããããã®ãããžã§ã¯ãã«è¿œå ããããããŸããã
ã¹ã¯ããŒã«å°éå ·ã«ã€ããŠã®ããªãã®ç¹å®ã®è³ªåã«é¢ããŠã¯ãããã¯ç§ããããžã§ã¯ãã«å ããããšæãå€æŽã§ã¯ãããŸãããreact-virtualizedã§äœ¿çšããåŸãããã€ãã®é倧ãªæ¬ ç¹ãããããšã«æ°ã¥ããŸããã èå³ãããã°ãç§ã¯å®éã«Reactããã°ã«ããã«ã€ããŠæžããŸããïŒ
https://reactjs.org/blog/2018/06/07/you-probably-dont-need-掟ç-state.htmlïŒanti -pattern-erasing-state-when-props-change
react-windowãæäŸããåœä»€åã¹ã¯ããŒã«APIã䜿çšããŠãåæ§ã®åæåäœãå®çŸã§ããŸãã å°éå ·ãæž¡ãã®ã§ã¯ãªããã³ãããã©ã€ããµã€ã¯ã«ãããããã®ã¡ãœãããåŒã³åºãå¿ èŠããããŸãã
ããŸãããã°ãããã¯çã«ããªã£ãŠããŸãããããã§ãªãå Žåã¯ãã©ããŒã¢ããã®è³ªåãããŠãã ããïŒ
ããã¯å®å šã«çã«ããªã£ãŠããŸãã ææ¡ãããããšãïŒ ç§ã¯ãããæ©èœãããŸããããããŠããã¯å®éã«ã»ããã¢ããããã®ãéåžžã«ç°¡åã§ãã éåžžã«ç°¡åãªã®ã§ãã¹ã¿ã³ãã¢ãã³ããã±ãŒãžãä¿èšŒããããšã¯ã§ããŸããã ãã¶ãããã¥ã¡ã³ãã®äŸã§ãããããã¯ç§ãæãããªãã®åŒã³åºãã§ãã å°æ¥ãã®åé¡ã«ééããå Žåã«åããŠãäœæ¥äžã®ã³ãŒããµã³ãããã¯ã¹ã®äŸãžã®ãªã³ã¯ãããã«æ®ããŠãããŸãã
https://codesandbox.io/s/y3pyp85zm1
TLDR-ããããŒã°ãªããã«refãé 眮ãããããããã£ã°ãªããã«é 眮ããŸãã
onScroll={({ scrollLeft }) => this.headerGrid.current.scrollTo({ scrollLeft })}
ãªã³ã¯ãããããšãïŒ ããã¯ãšãŠãææ ®æ·±ãããšã§ãã
2018幎11æ8æ¥æšææ¥ãååŸ1æ9åReagan Keeler < [email protected]ã¯æ¬¡ã®ããã«æžããŠããŸãã
ããã¯å®å šã«çã«ããªã£ãŠããŸãã ææ¡ãããããšãïŒ ç§ã¯ãããåãããŸããã
å®éãã»ããã¢ããã¯éåžžã«ç°¡åã§ãã ãšãŠãç°¡åãªã®ã§çµ¶å¯Ÿã«ããªã
ã¹ã¿ã³ãã¢ãã³ããã±ãŒãžãä¿èšŒããŸãã ãã¶ãããã¥ã¡ã³ãã®äŸã§ãããããã¯ããªãã§ã
ç§ãæãã«é»è©±ããŠãã ããã äœæ¥äžã®ã³ãŒããµã³ãããã¯ã¹ã®äŸãžã®ãªã³ã¯ãããã«æ®ããŸã
å°æ¥ãä»ã®èª°ãããã®åé¡ã«ééããå Žåã«åããŠãhttps://codesandbox.io/s/y3pyp85zm1
TLDR-ããããŒã°ãªããã«refãé 眮ãããããããã£ã°ãªããã«é 眮ããŸãã
onScroll = {ïŒ{scrollLeft}ïŒ=> this.headerGrid.current.scrollToïŒ{scrollLeft}ïŒ}
â
é/éç¶æ ãå€æŽããããããããåãåã£ãŠããŸãã
ãã®ã¡ãŒã«ã«çŽæ¥è¿ä¿¡ããGitHubã§è¡šç€ºããŠãã ãã
https://github.com/bvaughn/react-window/issues/86#issuecomment-437156749 ã
ãŸãã¯ã¹ã¬ããããã¥ãŒãããŸã
https://github.com/notifications/unsubscribe-auth/AABznTUunzEIs6bVQfVsz7T21L2-Pkkoks5utJ17gaJpZM4YVMd7
ã
ããã«åºãããã人ã«ã¯ããã®ã©ã€ãã©ãªã«ç§»è¡ããã°ããã®react-virtualized
ã¹ã¯ããŒã«åæãããäž/å³/äž/å·Šã®ããªãŒãºããã¹ãŒããŒã°ãªããããããŸããã äžèšã®ãœãªã¥ãŒã·ã§ã³ã¯ãä»ã®ã©ã€ãã©ãªã§ScrollSync
ã䜿çšããããããå°ãªããšãããã©ãŒãã³ã¹ãåªããŠãããšã¯èšããŸããããããã»ã©èŠçã§ã¯ãããŸããã
ãŸããæ°ããuseRef
åå¿ããã¯ïŒhttps://reactjs.org/docs/hooks-reference.html#userefïŒãšéåžžã«ãããã¢ã«ãªããŸãã
const topRef = useRef();
const rightRef = useRef();
const bottomRef = useRef();
const leftRef = useRef();
...
<Grid
onScroll={({ scrollLeft, scrollTop }) => {
if (leftRef.current) {
leftRef.current.scrollTo({ scrollTop });
}
if (rightRef.current) {
rightRef.current.scrollTo({ scrollTop });
}
if (topRef.current) {
topRef.current.scrollTo({ scrollLeft });
}
if (bottomRef.current) {
bottomRef.current.scrollTo({ scrollLeft });
}
}}
...
/>
è¯ãïŒ @ranneydãå ±æããŠãããŠããããšãïŒ
ãŸããæ°ãã
useRef
åå¿ããã¯ïŒhttps://reactjs.org/docs/hooks-reference.html#userefïŒãšéåžžã«ãããã¢ã«ãªããŸãã
ããããšã@ranneyd
å®äŸãå ±æããããšã¯å¯èœã§ããããïŒ
@ranneydããããšã
ã¹ã¯ããŒã«ããŒã®é ãããªãŒããŒãããŒã«ãããã°ãªããã®çµããè¿ãã§äœçœ®ããããŸãã
ãããä¿®æ£ããæ¹æ³ã«ã€ããŠäœãææ¡ã¯ãããŸããïŒ
åãã£ãŠæè¬ããŸã
@carlosagsmendesããã¯ã¹ã¯ããŒã«ããŒã®ããã§ãã å·ŠåŽã§ã¯ãé«ãããé«ãããã¹ã¯ããŒã«ããŒã®ãµã€ãºãåŒãããã®ã«ããŸãã ããã€ã¹éã§äžè²«æ§ãä¿ã€ããã«ãCSSã䜿çšããŠã¹ã¯ããŒã«ããŒã®ãµã€ãºãæåã§ããŒãã³ãŒãã£ã³ã°ããŸããã ã³ã³ãã³ããéåžžã«åçã§ãã¹ã¯ããŒã«ããŒãããå Žåãšãªãå Žåãããå Žåã¯ããnum items * size items <widthïŒãããã®å€ã¯ãã¹ãŠããã«ããã¯ãã§ãïŒãã®ããã«ããŠãããã«å¿ããŠé«ããå€æŽããŸãã
ããã€ã¹éã§äžè²«æ§ãä¿ã€ããã«ãCSSã䜿çšããŠã¹ã¯ããŒã«ããŒã®ãµã€ãºãæåã§ããŒãã³ãŒãã£ã³ã°ããŸããã
FWIW dom-helpersããã±ãŒãžã«ã¯ãçŸåšã®ããã€ã¹ã®å¹
ã瀺ã䟿å©ãªscrollbarSize
é¢æ°ããããŸãã ããŒãã³ãŒãã£ã³ã°ãããåªããŠããå¯èœæ§ããããŸãã
@bvaughnã¯ãïŒ ç§ã¯ããã«ã€ããŠèšåããã®ãå¿ããŸããã ããããããã¯ç§ãã¡ã«ãšã£ãŠã¯ããŸããããŸããã§ããã åé¡ã¯ããã§ã«ããŒãã³ãŒããããã¹ã¯ããŒã«ããŒãå®è¡ããŠããŠããããæ··ä¹±ããŠããããšã ãšæããŸãã
ããããšãã ãã£ãŠã¿ãŸãïŒ
ããã¯æ°Žå¹³VariableSizeListã§æ©èœããŸããïŒ è©ŠããŸãããããã©ãŠã¶ãããªãŒãºããŸãã
onScroll={({ scrollLeft }) => this.headerGrid.current.scrollTo({ scrollLeft })}
ããã¯VariableSizeGridã§ããŸãæ©èœããŸãããç§ã®ããããŒã¯ã¹ã¯ããŒã«ã§å°ãé ããŠããŸãã
@ajaymoreãªã®ã§ãããããŒã®é ãã«ã€ããŠèª¬æããŸããMacã§ã¹ã¯ããŒã«ãã€ãŒã«ã䜿çšãããšãã¹ã¯ããŒã«åæã
ãããããäºå®ïŒãã©ãŠã¶ã§ã¹ã¯ããŒã«ããŒãæåã§äœ¿çšããå ŽåïŒå°ããªãã®ããã©ãã°ããŠæãªããã®æ¹æ³ã§ã¹ã¯ããŒã«ãããªã©ïŒãå®å šã«æ£åžžã«æ©èœããŸãã è£éæ©èœã¯ãã¹ã¯ããŒã«ãã€ãŒã«/ãã©ãã¯ãããã®ã¹ã¯ã€ãã«çµã¿èŸŒãŸããŠããŸã
@ajaymoreãªã®ã§ãããããŒã®é ãã«ã€ããŠèª¬æããŸããMacã§ã¹ã¯ããŒã«ãã€ãŒã«ã䜿çšãããšãã¹ã¯ããŒã«åæã
ãããããäºå®ïŒãã©ãŠã¶ã§ã¹ã¯ããŒã«ããŒãæåã§äœ¿çšããå ŽåïŒå°ããªãã®ããã©ãã°ããŠæãªããã®æ¹æ³ã§ã¹ã¯ããŒã«ãããªã©ïŒãå®å šã«æ£åžžã«æ©èœããŸãã è£éæ©èœã¯ãã¹ã¯ããŒã«ãã€ãŒã«/ãã©ãã¯ãããã®ã¹ã¯ã€ãã«çµã¿èŸŒãŸããŠããŸã
@ranneydãã®ãããªè¿ éãªå¯Ÿå¿ãããããšãããããŸãã ç§ã¯ãããå¶éã§ããããšã«åæããŸãã ã»ãšãã©ã®ããã€ã¹ã§åé¡ãªãåäœããã®ã§ã倧ããªåé¡ã«ã¯ãªããŸããã
@bvaughn position: sticky
ã§éãã ããšããããŸããïŒ ãã°ããèŠãŠããŸãããããã©ãŠã¶ã®ãµããŒããå°ãªãããšã¯ç¥ã£ãŠããŸããããµããŒããããŠãããã©ãŠã¶ã§ããã掻çšããæ¹æ³ãããã®ã§ã¯ãªãããšæããŸã...
@ajaymoreãšåãåé¡ãããé ããªããŸãïŒåè¿°ã®ããã«ãæåã¹ã¯ããŒã«ã§ã¯æ£åžžã«æ©èœããŸãïŒã ç§ã¯PCã§Chromeã䜿ã£ãŠãã¹ãããŠããã®ã§ãããã¯Macã ãã®åé¡ã§ã¯ãªãããã§ã...誰ãããã®åé¡ããªããšãããŠåé¿ããããšã«æåããŸãããïŒ
@alonrbar WindowsPCã§ãåãåé¡ãçºçããŸãã
ç§ã¯å®éã«ç§ã®ããã«åãåé¿çãèŠã€ããŸããã
äžè¬çãªèãæ¹ã¯ãå
ã®ã°ãªãããé衚瀺ã«ããŠonScrollã€ãã³ããçã¿ãããã䜿çšããŠå
ã®ã°ãªãããšãã®ä»ã®å¿
èŠãªã°ãªãããæåã§ã¹ã¯ããŒã«ãããã·ã£ããŠã°ãªããããäœæããããšã§ãã ããã©ãŒãã³ã¹ã¯å°ãäœäžããŸããããã¹ãŠã®ã°ãªãããé©åã«åæããããŸãŸã«ãªãããããã¬ãŒããªããèæ
®ããå¿
èŠããããŸãã
ã³ãŒãã¯æ¬¡ã®ããã«ãªããŸãã
import styled from '@emotion/styled';
import * as React from 'react';
import { VariableSizeGrid, VariableSizeGridProps } from 'react-window';
import { SizeUtils } from '../utils';
export interface SyncableGridProps extends VariableSizeGridProps {
mainGridRef: React.Ref<VariableSizeGrid>;
shadowGridRef: React.Ref<VariableSizeGrid>;
hideVerticalScrollbar?: boolean;
}
export class SyncableGrid extends React.PureComponent<SyncableGridProps> {
public render() {
const { height, width } = this.props;
const {
onScroll,
mainGridRef: mainGridRef1,
shadowGridRef: shadowGridRef1,
...mainProps
} = this.props;
const {
children,
style,
overscanRowsCount,
overscanColumnsCount,
overscanCount,
useIsScrolling,
onItemsRendered,
mainGridRef: mainGridRef2,
shadowGridRef: shadowGridRef2,
innerRef,
outerRef,
...shadowProps
} = this.props;
return (
<SyncWrapper
style={{
height,
width
}}
>
<MainGrid
{...mainProps}
style={Object.assign({}, style, {
overflowY: 'scroll'
})}
ref={mainGridRef1}
/>
<GridShadow
{...shadowProps}
style={{
position: 'absolute',
top: 0,
left: 0
}}
ref={shadowGridRef1}
>
{() => null}
</GridShadow>
</SyncWrapper>
);
}
}
// ---------------- //
// styles //
// ---------------- //
const SyncWrapper = styled.div`
position: relative;
overflow: hidden;
`;
export interface MainGridProps extends VariableSizeGridProps {
hideVerticalScrollbar?: boolean;
}
export const MainGrid = styled(VariableSizeGrid) <MainGridProps>`
overflow-y: scroll;
box-sizing: content-box;
${props => {
if (!props.hideVerticalScrollbar)
return '';
const paddingDir = (props.theme.dir === 'rtl' ? 'padding-left' : 'padding-right');
return `${paddingDir}: ${SizeUtils.scrollbarWidth}px;`;
}}
`;
export const GridShadow = styled(MainGrid)`
opacity: 0;
`;
次ã«ãå¥ã®ãã¡ã€ã«ã§ïŒ
<SyncableGrid
mainGridRef={this.firstGridMain}
shadowGridRef={this.firstGridShadow}
onScroll={this.handleFirstGridScroll}
// other props omitted for bravity...
>
// children omitted for bravity...
</SyncableGrid>
<SyncableGrid
mainGridRef={this.secondGridMain}
shadowGridRef={this.secondGridShadow}
onScroll={this.handleSecondGridScroll}
// other props omitted for bravity...
>
// children omitted for bravity...
</SyncableGrid>
private handleFirstGridScroll = (e: GridOnScrollProps) => {
const { scrollTop, scrollLeft } = e;
// synchronize self
if (this.firstGridMain.current) {
this.firstGridMain.current.scrollTo({ scrollTop, scrollLeft });
}
// synchronize other grid
if (this.secondGridMain.current) {
this.secondGridMain.current.scrollTo({ scrollTop, scrollLeft });
this.secondGridShadow.current.scrollTo({ scrollTop, scrollLeft });
}
}
@alonrbarããã¯é åçã§ãïŒ ããã«è©ŠããŠã¿ãŸãã
ã·ã£ããŠã°ãªãããå®éã®ã°ãªããã®äžã«ããããã«èŠããŸããã ãããããªãããå®éã®ã°ãªãããã®ã¯ãªãã¯ã€ãã³ãã¯æ©èœããŸãããïŒ ã¯ãªãã¯ã€ãã³ã+ x / y座æšã䜿ã£ãŠå°ãããããŒãªããšãããŠãã©ãããããããããã¡ã€ã³ã°ãªããã«é©çšã§ãããšæããŸãã
ãŸãã @ barbalex reïŒWindowsã§ã倱æããŸã
å®ã¯ã¯ããŒã ãã©ãã°ãããããŸããã chromeïŒ// flagsã«äœãããããã©ããã確èªã
ãã®åé¡ã¯ç¢ºãã«ããã©ãŠã¶ã®ã¢ãã¡ãŒã·ã§ã³ãã¬ãŒã ãããéãã¹ã¯ããŒã«ããã¹ã ãŒãºãã«ãªãããšã«é¢é£ããŠããããã§ãã æžå¿µãããå Žåã¯ãçŽç²ã«ããã©ãŒãã³ã¹/ã©ã°ã®åé¡ã§ãããéåžžã«åºæ¬çãªã¹ã¯ããŒã«åæã®å®è£ ïŒ1ã€ã®divã®ã¹ã¯ããŒã«ã§å¥ã®divã®ã¹ã¯ããŒã«äœçœ®ãèšå®ããïŒãäœæããŠãåãåé¡ãçºçãããã©ããã確èªããŠãã ããã ãã¶ããç¯äººãšããŠã®Reactãæé€ããããã«ãçŽç²ãªããã©JSã§ãããè¡ãããšãããããŸã
ãã@ranneydããªãã¯æ£ããã§ãããã¯ã¯ãªãã¯ã€ãã³ãããããã¯ããŸã...ããã«ã€ããŠããå°ãèããå¿ èŠããããŸã...
chromeïŒ// flagsã®ã¹ã¬ããã¹ã¯ããŒã«æ©èœã¯å€§ããªåœ±é¿ãäžããŠãããšæããŸãããªãã«ãããšãããŠã¹ãã€ãŒã«ã§ã®ã¹ã¯ããŒã«ãã¹ã¯ããŒã«ããŒã§ã®ã¹ã¯ããŒã«ãšã»ãŒåããããã¹ã ãŒãºã«ãªããŸãã
@alonrbarããã¯ã©ã
ã¡ã€ã³ã°ãªããã«ã¹ã¯ããŒã«ãã³ãã©ãŒãè¿œå ããŸãã ãã®äžã§ãå®éã®ã¹ã¯ããŒã«ãé²ãããã«e.preventDefault();
ãªã©ãå®è¡ããŸãã 次ã«ãã€ãã³ããèŠãŠãã¹ã¯ããŒã«ãããéãææ¡ããŸããããã«ãããä»ã®åæããããã®ã移åããŸãããããã䜿çšããŠãåãèŠçŽ ãæåã§ã¹ã¯ããŒã«ããŸãã ãããã£ãŠãAãã¹ã¯ããŒã«ããŠãããã®æ
å ±ã䜿çšããŠBãã¹ã¯ããŒã«ãã代ããã«ãAã®ã¹ã¯ããŒã«ãã€ã³ã¿ãŒã»ããããŠãã£ã³ã»ã«ããããã䜿çšããŠBãšAèªäœãã¹ã¯ããŒã«ããŸãã ããã¯ããŸãããã§ããããïŒ
ç§ã¯ã³ã³ãã¥ãŒã¿ãŒã§ãã¹ãããŠããããã§ã¯ãããŸããã ããªãããããŒã§ãããç§ã¯åãããšãã§ããŸããã @bvaughnã®èãïŒ
@alonrbarããããŠãŒã¶ãŒã«ãããè¡ãããã«äŸé ŒããŠãæ©èœããŸããã è©ŠããŠã¿ããå Žåã¯ãçŽæ¥ãªã³ã¯ãäžããããšãã§ããŸãïŒ chromeïŒ// flags /ïŒdisable -threaded-scrolling
@alonrbarãããããã¯è¯ããããŸãããããã§ã«äžç·ã«ãããã³ã°ããŠããã°ãªããã«é©çšããã ããªãã
ã¹ã¯ããŒã«ãã€ãŒã«ã ãã§ãããïŒ ç¢å°ããŒããããå®çŸããŸããïŒ
ããã¯ããã§åãå ¥ããããåçããã®æç²ã§ãïŒ https ïŒ
function disableScroll() {
if (window.addEventListener) // older FF
window.addEventListener('DOMMouseScroll', preventDefault, false);
document.addEventListener('wheel', preventDefault, {passive: false}); // Disable scrolling in Chrome
window.onwheel = preventDefault; // modern standard
window.onmousewheel = document.onmousewheel = preventDefault; // older browsers, IE
window.ontouchmove = preventDefault; // mobile
document.onkeydown = preventDefaultForScrollKeys;
}
ã芧ã®ãšãããåŠçããå¿ èŠã®ããã€ãã³ããããã€ããããããããããšã§èµ·ããããçµæãæ€èšããå¿ èŠããããŸãã
ä»ã®ãšãããããã解決ããããã«ãã以äžæéãè²»ããããšãã§ããªããããéä»®æ³ãœãªã¥ãŒã·ã§ã³ã䜿çšããããšã«ããŸããïŒãããå®ç§ã§ã¯ãããŸããããç§ã®ãŠãŒã¹ã±ãŒã¹ã«ã¯é©ããŠããŸãïŒã ç§ã䜿çšããŠããã³ãŒãã¯ããã«ãããŸãïŒ react-window
ãã©ããããã®
@alonrbarããç§ã¯SOãœãªã¥ãŒã·ã§ã³ãããªã
ããããããªãã®è§£æ±ºçã¯éåžžã«èå³æ·±ããšæããŸãã ç§ã¯ãããèªåã§è©ŠããŠãä»®æ³åãããããŒãã«ã§æ©èœãããããšãã§ãããã©ããã確èªããŸãã
@alonrbarãªã®ã§ãå®éã«çµ¶å¯Ÿããžã·ã§ãã³ã°ã䜿çšããéä»®æ³åå®è£
ãäœæããŸããã ã¹ã¯ããŒã«ããã®ã¯å€åŽã®ã³ã³ããã ãã§ãã ã¹ã¯ããŒã«ãããšãå
éšèŠçŽ ã絶察é
眮ããããã«äœ¿çšãããå·Šäžã®å€ãæŽæ°ãããŸãã ã ãããç§ãèŠã€ããscrollTo
ãscrollTop = ...
ã¯ãç§ã«å€ãã®æ²ãã¿ãåŒãèµ·ãããŠããŸããã§ããã ãã®äžãã¹ã¯ããŒã«ããŒã¯åžžã«ã°ãªããå
šäœã®å€åŽã«ãããŸãã
ç§ãäœã£ããã®ãã®ã¯ããã¹ãŠã®é¢ã«ãåçµãããããããŒããåçã«æã€ããšãã§ããŸãã ããã¯éåžžã«å€§ãŸããªäŸ/ pocã§ãã
æããã«ãæ·±å»ãªåé¡ã§ããä»®æ³åãæ¬ ããŠããŸãã æ®å¿µãªããããã®ã©ã€ãã©ãªããã°ãªãããã©ããã§ãããã©ããã¯ããããŸããããã®ã©ã€ãã©ãªã¯åºæ¬çã«ã¹ã¯ããŒã«ã§å®è¡ãããå éšã°ãªããã®ã¹ã¯ããŒã«ãäžèŠã«ãªãããã§ãã 次ã®ã¹ããããäœãããããªãã
https://codesandbox.io/embed/non-virtual-scroll-synced-table-ot467
ãã®libãä¿é²ããã®ãšåãä»®æ³åããžãã¯ãããã«é©çšã§ãããšæããŸãã
@ranneydéåžžã«ã¯ãŒã«ãªå®è£ ïŒ
ç§ã¯åçã°ãªããæ§æã奜ãã§ã:)
ããããæãéèŠãªã®ã¯ãã¹ã¯ããŒã«ã®ä»£ããã«çµ¶å¯Ÿäœçœ®ã䜿çšãããšããèããããã®åé¡ã解決ããããã®éµãšãªãå¯èœæ§ãããããšã§ãã å¥ã®divãå°å ¥ãæ°ããå¯èœæ§ãéããããšæããŸãã
react-window
ã®render
ã¡ãœããã«ããã¯ã§ããå Žåã¯ã459è¡ç®ä»¥éãå®è£
ã«çœ®ãæããããšãã§ããå ŽåããããŸãã 次ã«ãonscrollã€ãã³ããããã¯ããŠãå¿
èŠã«å¿ããŠãã®å¹æãç¡å¹ã«ããããšãã§ããŸãïŒã¹ã¯ããŒã«ããŒã¯åžžã«ç§»åããŸãããã³ã³ãã³ããå¶åŸ¡ããŠå€æŽãããªãããã«ããããšãã§ããŸãïŒã
@alonrbarãªã®ã§ãå®éã«ä»®æ³åã¢ã«ãŽãªãºã ãåå®è£ ããŸããã ããã»ã©è¯ãã¯ãããŸãããããã®ã°ãªãããå®éã®ä»®æ³åã«å°éãããšãã«ãœãŒã¹ã³ãŒããèŠããšãåºæ¬çã«åãã¢ã«ãŽãªãºã ã§ãã ãã ããããã©ãŒãã³ã¹ã¯å®éã«ã¯ãŸãšãã§ãã ã©ã°ãªãã§200x200ã°ãªããã«å°éã§ããã»ãã®å°ãã ãã§500x500ã°ãªããã«å°éã§ããŸãã äžåžããã以äžããã«åãçµãã§ãããããããªããææ¡ããããã«ã¬ã³ããªã³ã°ã¡ãœããã®å®è£ ãè©Šã¿ãŸããããã¯ããããå®éã«ã¯ããªãç°¡åã§ãã
ç§ãäœã£ãã°ãªããã«èå³ãããã°ãã©ããã«æçš¿ã§ããŸãã ããªãããããåãããã®ã©ã€ãã©ãªã«æ¥ç¶ãããå Žåã¯ãç§ã®ã²ã¹ãã«ãªããŸãð
@ranneydã¯ãããªããäœã£ãä»®æ³åãœãªã¥ãŒã·ã§ã³ãèŠããã§ãã ç§ãããã䜿ããã©ããã¯ããããŸããããããã¯ç¢ºãã«é¢çœãã§ããã:)
ãŸããç§ã¯ä»æ¥ããªãã®ã³ãŒãã䜿çšããŠãç§ãææ¡ããããã«renderã¡ãœãããžã®å€æŽãå®è£
ããããšããŸããããã³ãŒããèªã¿çŽããåŸãããªããæã£ãããã«ã¹ã¯ããŒã«ãå®éã«åæããŠããªãããšã«æ°ä»ããŸããã ã€ãŸããã¹ã¯ããŒã«ããŒãšonscroll
ã€ãã³ãã¯ãå®éã®ã³ã³ãã³ãã¹ã¯ããŒã«ãšåãé¢ããªããšããããšã§ãã ç§ã¯ããªãã®ã¢ã€ãã¢ãããã«äžæ©é²ããŠãçã«åãé¢ãããã¹ã¯ããŒã«ãå®è£
ããŸããïŒ
https://codesandbox.io/embed/absolute-position-scrolling-1u7vj
ã³ãŒããèŠããšã top
left
ããããã£ãšContent
ã³ã³ããŒãã³ãããåé€ãããšãã¹ã¯ããŒã«ããŒããã£ãŠãã³ã³ãã³ããã¹ã¯ããŒã«ãããªãããšãããããŸãã
ãã®å®è£
ã䜿çšããŠã onscroll
ã€ãã³ããç¡èŠããè€æ°ã®ã°ãªãããæåã§åæããããšãå¯èœã«ãªã£ããšæããŸãã ãããããã¡ããããã¯ããå°ãäœæ¥ãå¿
èŠãªã®ã§ã次åãŸã§åŸ
ããªããã°ãªããŸãã...
ãã®è°è«ã«èå³ãæã£ãã®ã§ã2ã€ã®ã¹ã¯ããŒã«åæreact-window Grid
ãreact-virtualized MultiGrid
ãšæ¯èŒãããããžã§ã¯ããã»ããã¢ããããŠãperfãã©ã®ããã«æ¯èŒãããããç解ã§ããããã«ããŸããã ïŒ
https://github.com/bvaughn/react-window-vs-react-virtualized-synced-grids
ããããã®äœ¿ãæ¹ãã§ããã ã䌌ããã®ã«ããããã«å¿ãããŸããã ããã€ãã®æåã®èŠ³å¯ïŒ
onScroll
ïŒã³ãããäžã«åŒã³åºãããïŒã§ã¯ãªããããã€ãã£ããïŒReactïŒã¹ã¯ããŒã«ã€ãã³ããã³ãã©ãŒïŒReactã®ãããæŽæ°å
ã§åŒã³åºãããïŒã®åãæž¡ãããµããŒãããããã«ã Grid
ã«ããããäœæããŸããã段éïŒã ããã¯ãããŒã«ã«ã§ãã¹ããããšãã«ããªãææãªå€æŽã®ããã«èŠããŸããããã¯ãåå¥ã®ã«ã¹ã±ãŒãã¬ã³ããªã³ã°ãåé¿ãããããããã©ã«ãã®onScroll
ã¿ã€ãã³ã°ãå€æŽããã ããããããŸããã@bvaughn divA- > onScroll-> setState->
ç®æšã¯åžžã«JavaScriptãå¯èœãªéãé«éã«ããŠãã¹ã¯ããŒã«ã管çããã¹ã¬ããã«è¿œãã€ãããšã§ãã
ç§ã¯ç¢ºãã«åå¿ç¶æ ãåé¿ãããonScrollãã³ãã©ãŒå ã§ref.scrollTopãèšå®ããŸãã
æ確ã«ããããã«ãããã¯ç§ã®ã¬ããè¡ã£ãŠããããšã§ããããŸããã ã¢ã¯ãã£ãã°ãªãããšåãïŒReactã§ã©ãããããïŒã€ãã³ããã³ãã©ãŒã®ããã·ãã°ãªããã§ã¹ã¯ããŒã«ãªãã»ãããèšå®ããŠããã ããªã®ã§ãReactã¯æŽæ°ãåäžã®render + commitã«ãããåŠçããŸãã æ£çŽã«èšããšãããã¯ãããã倧ããªéãã«ã¯ãªããŸããã
@ranneydãš@bvaughnããããŸã§ã®ç§ã®èŠ³å¯ãããªããšå ±æããŠããŸãïŒ
å€ãã®å®è£ ã¯ãã¹ã¯ããããã©ãŠã¶ã§ååã«æ©èœããŸãããç§ã®äž»ãªäœ¿çšäŸã¯å®éã«ã¯ã¢ãã€ã«ããã€ã¹ã§ãããããã©ãŒãã³ã¹ã«å€§ããªéããèŠãããŸãã
2ã€ã®åçŽãªéä»®æ³ã°ãªããã®åæã¯éåžžã«ããŸãæ©èœããŸãïŒ100ïŒ
å®ç§ã§ã¯ãããŸããããã¢ãã€ã«ã§ãååã«è¿ãã§ãïŒã ããã¯ç§ã®çŽ æŽã§ãããªããæ©èœããŠããå®è£
ã§ãããå®éã«åäœããããšã確èªããããã®ãã¹ãã±ãŒã¹ã§ãïŒ yarn storybook
ïŒã
ãå¶åŸ¡ããããã¹ã¯ããŒã«ã䜿çšãããšïŒãã®ã³ã¡ã³ãã§ææ¡https ïŒ
ããã§ãããå¶åŸ¡ããããæŠç¥ããåäžã®ä»®æ³ãªã¹ãã§ãã®åé¡ã解決ããããã«äœããã®åœ¢ã§æ©èœãããã©ããã確èªããããšæããŸãã
2人ããã§ã«ææ¡ããããã«ã _callPropsCallbacks
ã_onScroll
ãã³ãã©ãŒã«çŽæ¥ç§»åãããšãåæã®é
延ãæå°éã«æããããšãã§ããã®ã§ã¯ãªãããšèããŠããŸããã ç·šé-ä»è©ŠããŠã¿ãŸããããå®éã«ã¯åœ¹ã«ç«ã¡ãŸããð
ãããã«ãããIMHOã¯ä»®æ³åããžãã¯ãã³ã³ããŒãã³ãã®æ®ãã®éšåïŒããããããã¯ã§ãããïŒããåé¢ããããšããå§ãããŸããããããã°ãã¬ã³ããªã³ã°ãšã¹ã¯ããŒã«ã®èŠçŽ ãå¥ã ã«åŠçããç°¡åã«æ¯èŒã§ããå®è¡æã«ããã«åºã¥ããŠåãæ¿ããããšãã§ããŸããã³ã³ããŒãã³ãã®å°éå ·ã ãŸãããã®ããžãã¯ããšã¯ã¹ããŒãããŠããŠãŒã¶ãŒãåãããžãã¯ã«åºã¥ããŠã«ã¹ã¿ã ã³ã³ããŒãã³ãïŒãã®ã³ã¡ã³ãã®@ranneydãœãªã¥ãŒã·ã§ã³ãªã©ïŒãå®è£ ã§ããããã«ããŸãã
èãïŒ
@alonrbar絶察枬äœãè¡ãç§ã®ãœãªã¥ãŒã·ã§ã³ã¯ãã¹ã¯ããŒã«ãå®è¡ããã°ââãªããã§ã¯ãªããããçŽ300x300ãŸã§ã¯éåžžã«ããŸãæ©èœããå°ãé
ããªããŸãïŒ100ïŒ
ã®æéåæãç¶æããã¹ã¯ããŒã«ã¯å°ãé
ããŸãïŒã ãã倧ããªãµã€ãºã§ã¯ãããã¯å€§ããªé
åãåŠç/ãããã³ã°ããŠããã ãã ãšæããŸãã ããã€ãã®æé©åããããšæããŸã
ããããç§ã¯ãããè¡ãããšãã§ããŸããããããç§ã®ããªãåçŽãªä»®æ³åã®å®è£
ã»ã©ã¹ã¯ããŒã«åæãšé¢ä¿ããããšå®å
šã«ç¢ºä¿¡ããŠããããã§ã¯ãããŸããã ããšãã°ãããå€ãã®ãã£ãã·ã¥ãå®è¡ã§ããŸãããŸããã¬ã³ããªã³ã°é¢æ°ã®åŒã³åºãããŸã£ããåé¿ããããã«ãã»ã«ãä»®æ³åããå¿
èŠããããã©ãããèšç®ã§ããŸãïŒãããŠããããããããããé©åã«ãã£ãã·ã¥ããŸãïŒã
ç§ã¯ã¢ãã€ã«ã§äœããã¹ãããŠããŸããã å°ãè©ŠããŠã¿ãããã®ã³ãŒããããã€ãæäŸããŸãã
ç§ã¯æ¬åœã«@bvaughnãã¹ããèŠããã§ãã 圌ã¯ããã€ãã£ãã¹ã¯ããŒã«ã«çŽæ¥ããã¯ãããšä¿®æ£ããããšèšããŸãããããã§ã¯ãªããšèšããŸãã èªåã§èŠããã§ãã
ä»®æ³åããžãã¯ãããã¯ãŸãã¯ç¬ç«ããé¢æ°ã«åã蟌ãéããããžãã¯ã¯æ¬è³ªçã«ãã¥ãŒã«æ¥ç¶ãããŠãããããããªã泚æãå¿ èŠã§ãã ãŸããããã©ãŒãã³ã¹ã®èª¿æŽã®å€ãã«ã¯ã1ã€ã®ããã¯ãŸãã¯é¢æ°ã«ã«ãã»ã«åããã®ãé£ããããŸãã¯å°ãªããšãåãããã©ãŒãã³ã¹ãåŸãããçšåºŠãŸã§ããã£ãã·ã¥ãšã¡ã¢åãå«ãŸããŠããããã§ãã ããããç§ã¯èªåãæã£ãŠãããã®ãèŠãŠãã©ãã ãã®ããžãã¯ãåŒãåºãããšãã§ããããèŠãŠãããŸãã
PSïŒ
ããããããŸããããªããšç§ãæã£ã1ã€ã®ããšã¯ãéé£ã®ãããªããš+ cssé·ç§»ãè¡ãããšã§ãã 100ããªç§ããšã«1ã€ã®ã¹ã¯ããŒã«ã€ãã³ãã®ã¿ãå®è¡ããåããã¢ãã¡ãŒã·ã§ã³åãããšãèŠæ ããè¯ããªãå¯èœæ§ããããŸãã ãŸããå¿çæ§ã倧å¹
ã«äœäžããŠããããã«èŠããå ŽåããããŸãã ããã¯ãWorld of Warcraftã®ããæ¹ãšäŒŒãŠããŸãïŒã©ã°ãåŸ
ã¡æéãé·ãå Žåã¯ããã£ã©ã¯ã¿ãŒãçŽç·ã§åãããå®éã«è¡ã£ãå Žæã®æ
å ±ãååŸãããä¿®æ£ããŸãïŒã
ç§ã¯æ¬åœã«@bvaughnãã¹ããèŠããã§ãã 圌ã¯ããã€ãã£ãã¹ã¯ããŒã«ã«çŽæ¥ããã¯ãããšä¿®æ£ããããšèšããŸãããããã§ã¯ãªããšèšããŸãã èªåã§èŠããã§ãã
ïŒsmileïŒäœåãªäžèŠãªã¬ã³ããªã³ã°ãšDOMãã¥ãŒããŒã·ã§ã³ãåé¿ãããšèšã£ãã ãã§ãã å®éã®ããã©ãŒãã³ã¹ã«ã©ã®çšåºŠã®åœ±é¿ãããã®ãââã¯ç§ã«ã¯ããããŸããã ãšã¯ãããå šäœçã«ååããªå€åã®ããã«èŠããŸãã
@alonrbar @bvaughnå®éã«ã³ãŒããææžåããå¿ èŠããããŸãããææ°ããŒãžã§ã³ã¯æ¬¡ã®ãšããã§ãã
@alonrbar @bvaughnã ããããããç§ãä»çºèŠãã楜ããããšã§ãïŒ
ç§ã®ãœãªã¥ãŒã·ã§ã³ã¯ãMacBookç»é¢ã®Chrome75ã§ã¯æ©èœããŸããã ç§ã®ååãã¯ãã ãæŽæ°ããŠããªãã£ããšããããã¯æ©èœããŸããã 圌ããå€éšã¢ãã¿ãŒã䜿çšããå Žåãããã¯æ©èœããŸãã 圌ãã®ã©ãããããç»é¢ã§ã¯ãããã¯é
ããŠããŸãã
ð©
ããŒã...ãªãã¬ãã·ã¥ã¬ãŒããã¹ã±ãŒãªã³ã°ãªã©ãå€éšã¢ãã¿ãŒãšã¯ããã€ãã®éãããããŸãã ãããŸããããªãããšèšããšããå ·äœçã«ã¯ã©ãããæå³ã§ããïŒ
ç§ã®æªãã ã€ãŸããã¹ã¯ããŒã«ãåæãããªããªã£ããšããããšã§ãã ç§ã®ãªããžããªã®ã¯ããŒã³ãäœæããŠå®è¡ãããšãå€éšã¢ãã¿ãŒãšã©ãããããç»é¢ãæ¯èŒã§ããŸãã ã¢ãã¿ãŒäžã§ã¯ããããã¯å®å šã«åæããŠããŸãã ããŒãããœã³ã³ã®ç»é¢ã§ã¯ãããããŒãã¡ãã€ããŸãïŒã¹ã¯ããŒã«èŠçŽ ãšåãé床ã§æŽæ°ããªãã§ãã ããïŒã
ç§ã¯å®éã«è«Šãã position: sticky
è©ŠããŠã¿ãŸããã ããã¯å®éã«æ©èœããŠããŸãã ãã©ãŠã¶ã®ãµããŒãã¯100ïŒ
ã§ã¯ãããŸããããå®éã«ã¯1幎åãããã¯ããã«åªããŠããŸãã
åäœããå¯èœæ§ã®ããéããªãã£ã«ããªãã£ã«ã§ãããã®libããããŸãããã¿ãŒã²ãããšãããã©ãŠã¶ãŒã¯ããŸããŸãã®æ©èœããµããŒãããŠããŸãã
https://github.com/dollarshaveclub/stickybits
@ alonrbar @ bvaughnã¯ææ°ããŒãžã§ã³ã§ãã position: sticky
ãŸãã READMEã§å°ã説æããŸãã ã³ãŒãã¯ãŸã ææžåããå¿
èŠããããŸãã
ç§ã®ãœãªã¥ãŒã·ã§ã³ã¯ãMacBookç»é¢ã®Chrome75ã§ã¯æ©èœããŸããã ç§ã®ååãã¯ãã ãæŽæ°ããŠããªãã£ããšããããã¯æ©èœããŸããã 圌ããå€éšã¢ãã¿ãŒã䜿çšããå Žåãããã¯æ©èœããŸãã 圌ãã®ã©ãããããç»é¢ã§ã¯ãããã¯é ããŠããŸãã
ð©
@ranneydä»æ¥ãããã¯ãã¬ãŒã ã¬ãŒãã«é¢é£ããŠããã®ã§ã¯ãªãããšæããŸããã å€éšã¢ãã¿ãŒã®ãã¬ãŒã ã¬ãŒãã¯ãããšãã°30 fpsã§ããå¯èœæ§ããããŸãããã®å Žåããã©ãŠã¶ãŒããã£ã¹ããããããã¹ã¯ããŒã«ãã€ãã³ãã¯å°ãªããªããšæããŸãïŒã»ãšãã©ã®ãã©ãŠã¶ãŒã¯ãã¬ãŒã /ãã€ã³ãããšã«1ã€ãããã£ã¹ãããããªããšæãããïŒã ãã¶ãããããå€éšã¢ãã¿ãŒã§ã©ã°ãããç®ç«ã€çç±ã§ããïŒ
@bvaughnããã¯ããã§ãªããã°ãªããªããšæããŸãã OSã¯60hzãéä¿¡ããŠãããšèšã£ãŠãããã¢ãã¿ãŒã®ä»æ§ã¯60hzãšèšã£ãŠãããšæããŸããã誰ããåãã€ããŠããŠãé©ããªãã§ãããð
@ranneydç³ãèš³ãããŸããããçŸåšãå©çšããã ããªãããããœãªã¥ãŒã·ã§ã³ãé©åã«ç¢ºèªã§ããŸããã§ããããäžç®èŠãã ãã§ãããªããããã«èŠãã useVirtual
ãäœæããããšã«æ°ä»ããŸããã
ã©ããããããreact-window
ãã«ãªã¯ãšã¹ããäœæããããã§äœ¿çšããŠãã¬ã³ããªã³ã°ããžãã¯ããã©ã°ã€ã³ã§ããäœããã®renderTable
ã¡ãœãããå
¬éã§ããã°çŽ æŽããããšæããŸãã ãã®ããã«ããŠãã©ã€ãã©ãªã¯ãreact-windowã眮ãæããã®ã§ã¯ãªããã©ããããã ãã§æžã¿ãŸãã ãã®ã¢ãããŒãã掻çšããŠããã§ã«ããªãã®æŠéãã¹ããè¡ââãããåºãæ®åããŠããreact-window
å
ã®åé¡ã解決ã§ããã°æãŸãããšæããŸãã
å¥ã®åé¡ãšããŠã scrollTo
ãçŽæ¥DOMæäœã䜿çšããå ŽåïŒããããç¶æ
ã®èšå®ã«å ããŠããããã«ããŠãããããåã«ïŒã2ã€ã®ããŒãã«ãåæããçµæãããã¹ã ãŒãºã«ãªããšæããŸãã ç§ãééã£ãŠããªããã°ã @ bvaughnããã®æ¹åã«äœããææ¡ããŠããŸããã
@ranneydããªãã®ã¹ãã£ãããŒããŒãã«ãœãªã¥ãŒã·ã§ã³ã¯æ¬åœã«çŽ æŽãããèŠããŸãããããŠç§ã¯ããã䜿ãããšãã§ããŠãšãŠãããããã§ãã npm
䜿çšå¯èœãªAPIããªãªãŒã¹ããããšãæ€èšããŸããïŒ
@bvaughn @ranneyd
ããã§ãããªãã®æéãçµã£ãåŸãç§ã¯æè¿ãã®åé¡ã«æ»ã£ãŠããŸããã ã©ã€ãã©ãªãšrecyclerlistviewããã³react-virtual-gridã®äž¡æ¹ããã®ã³ãŒããšã¢ã€ãã¢ã䜿çšããŠãæçµçã«ç§ãæãåäœãã€ãŸãããã¹ã¯ããããšã¢ãã€ã«ã®äž¡æ¹ã§ããŸãæ©èœããåºå®ã®è¡ãšåãæã€é«æ§èœã°ãªãããå®çŸããããšãã§ããŸãããããã€ã¹ïŒç©º/çœè¡çã®ãªãã¹ã ãŒãºãªã¹ã¯ããŒã«ïŒã
ãã®TLDRã¯ãã¹ãã£ãããŒããžã·ã§ãã³ã°ãšäžç·ã«ãªãµã€ã¯ã«ã䜿çšããããšã§ããæãèå³æ·±ãã³ãŒãã¯ããã®ã¡ãœããã§èŠã€ããããšãã§ããŸãã
ããã«å¥ã®è§£æ±ºçãæžãåæ©ã«ã€ããŠã®ã¯ã¬ãžãããªã©ãããã«ãããŸãã ããããšãïŒ
å°æ¥ãã®åé¡ã«ééããå Žåã«åããŠãäœæ¥äžã®ã³ãŒããµã³ãããã¯ã¹ã®äŸãžã®ãªã³ã¯ãããã«æ®ããŠãããŸãã
https://codesandbox.io/s/y3pyp85zm1
å®å
šã«å³ã«ã¹ã¯ããŒã«ãããŸã§ã¯éåžžã«äŸ¿å©ã§ãããããããšãããããŒãã³ã³ãã³ããšãããŸãïŒã¹ã¯ããŒã«ã®åçŽã¹ã¯ããŒã«ããŒã®å¹
ã«ãã£ãŠïŒã
äžãäžããã®è§£æ±ºçãèŠã€ããŸãããïŒ
ããããšã
å°æ¥ãã®åé¡ã«ééããå Žåã«åããŠãäœæ¥äžã®ã³ãŒããµã³ãããã¯ã¹ã®äŸãžã®ãªã³ã¯ãããã«æ®ããŠãããŸãã
https://codesandbox.io/s/y3pyp85zm1å®å šã«å³ã«ã¹ã¯ããŒã«ãããŸã§ã¯éåžžã«äŸ¿å©ã§ãããããããšãããããŒãã³ã³ãã³ããšãããŸãïŒã¹ã¯ããŒã«ã®åçŽã¹ã¯ããŒã«ããŒã®å¹ ã«ãã£ãŠïŒã
äžãäžããã®è§£æ±ºçãèŠã€ããŸãããïŒ
ããããšã
å®å
šé瀺ïŒç§ã¯å®éã«èªåã®ããŒãžã§ã³ãæåããäœæããŸããã ãã®ã©ã€ãã©ãªã«å€§ããåºã¥ããç¬èªã®ä»®æ³åããããŸãã ç§ããããè¡ã£ãçç±ã¯ãMacBookãšãã¹ã¯ããŒã«ã®ã¢ãã¡ãŒã·ã§ã³ãJSãšã¯ç°ãªãã¿ã€ãã³ã°ã§çºçããç¹å®ã®Chromeãã©ã°ã«åé¡ãããããã§ãã ScrollSyncã䜿çšããã«ã¯ãæž¡ãããé¢æ°åŒã³åºããå€ãããŠãé
ãããŸããã åºæ¬çã«ãã³ã¢ã«ã¹ãã£ãããŒããããŒã䜿çšããŠã©ã€ãã©ãªãäœãçŽãå¿
èŠããããŸããïŒãã®ã¹ã¬ããã§åã«è¿°ã¹ãããã«position: sticky
䜿çšããŸãã
ãšã¯ããããã®åé¡ãåé¿ããæ¹æ³ã¯ã overflow: scroll
ã䜿çšããŠã¹ã¯ããŒã«ããŒã匷å¶ããæåŸã®ã»ã«ã«ãã®ããã£ã³ã°ãè¿œå ããããã¹ã¯ããŒã«ããŒããããã©ããïŒããã³ãã®å¹
ïŒãåçã«å€æããããšã§ãã refãšãã®äžã«é衚瀺ã®divãé
眮ããã¹ã¯ããŒã«ããŒã®ãµã€ãºã枬å®ããDOMããŒããåé€ããŸãã
overflow-y: overlay
ã䜿çšããŠãã¹ã¯ããŒã«ããŒããªãŒããŒã¬ã€ããŸããã æ®å¿µãªãããWebkitãã©ãŠã¶ã§ã®ã¿æ©èœããŸãã
æ å ±ãããããšãã ã¹ãã£ãããŒããããŒã¯éåžžã«äžè¬çãªããŒãºã§ããããã«æããããããreact-windowã«ã¹ãã£ãããŒãªæåã®è¡ãªãã·ã§ã³ãè¿œå ããã ãã§ãå€ãã®å Žåãreact-virtualizedã®ä»£ããã«ãªããŸãã ããæããŸãããïŒ
@ranneydããããšã
ã¹ã¯ããŒã«ããŒã®é ãããªãŒããŒãããŒã«ãããã°ãªããã®çµããè¿ãã§äœçœ®ããããŸãã
ãããä¿®æ£ããæ¹æ³ã«ã€ããŠäœãææ¡ã¯ãããŸããïŒ
åãã£ãŠæè¬ããŸã
ããŒãã£ãŒã«é ããŸããããleftRefã«1è¡ãè¿œå ãããã®ãªãŒããŒãããŒãé衚瀺ã«ãããšãåºæ¬çã«pbã解決ãããŸãã ïŒleftRef->ã¡ã€ã³ã°ãªãããåæããå¿ èŠããããŸããã§ãã
const headerRef = React.useRef();
const leftRef = React.useRef();
return <Box classes={{
root:classes.tableContainer
}}>
<AutoSizer>
{({ height, width }) => (<>
{/*---------------- LAÂ TABLE -------------*/}
<Grid
columnCount={1000}
columnWidth={100}
height={height}
rowCount={1000}
rowHeight={35}
width={width}
onScroll={({ scrollLeft, scrollTop }) => {
if (leftRef.current) {
leftRef.current.scrollTo({ scrollTop });
}
if (headerRef.current) {
headerRef.current.scrollTo({ scrollLeft });
}
}}
>
{({ columnIndex, rowIndex, style }) => (
<Box style={style} classes={{root:classes.cell}}>
Item {rowIndex},{columnIndex}
</Box>
)}
</Grid>
{/*---------------- HEADER -------------*/}
<Grid
ref={headerRef}
outerElementType={React.forwardRef((props, ref) => (
<div ref={ref} {...props} style={{...props.style,position:"absolute",overflow:"hidden",top:0,right:0,left:150}} />
))}
columnCount={1001} /*columns count +1 for scroll problems*/
columnWidth={100}
height={60}
rowCount={1}
rowHeight={60}
width={width}
>
{({ columnIndex, rowIndex, style }) => (
<Box style={style} classes={{root:classes.headerCell}}>
Header {rowIndex},{columnIndex}
</Box>
)}
</Grid>
{/*---------------- LEFTÂ COL -------------*/}
<Grid
ref={leftRef}
outerElementType={React.forwardRef((props, ref) => (
<div ref={ref} {...props} style={{...props.style,position:"absolute",overflow:"hidden",top:60,left:0}} />
))}
columnCount={1}
columnWidth={150}
height={height}
rowCount={251} /** add 1 for scroll problems at the end */
rowHeight={140}
width={150}
>
{({ columnIndex, rowIndex, style }) => (
<Box style={style} classes={{root:classes.headerCell}}>
Left {rowIndex},{columnIndex}
</Box>
)}
</Grid>
</>)}
</AutoSizer>
</Box>
æãåèã«ãªãã³ã¡ã³ã
ããã¯å®å šã«çã«ããªã£ãŠããŸãã ææ¡ãããããšãïŒ ç§ã¯ãããæ©èœãããŸããããããŠããã¯å®éã«ã»ããã¢ããããã®ãéåžžã«ç°¡åã§ãã éåžžã«ç°¡åãªã®ã§ãã¹ã¿ã³ãã¢ãã³ããã±ãŒãžãä¿èšŒããããšã¯ã§ããŸããã ãã¶ãããã¥ã¡ã³ãã®äŸã§ãããããã¯ç§ãæãããªãã®åŒã³åºãã§ãã å°æ¥ãã®åé¡ã«ééããå Žåã«åããŠãäœæ¥äžã®ã³ãŒããµã³ãããã¯ã¹ã®äŸãžã®ãªã³ã¯ãããã«æ®ããŠãããŸãã
https://codesandbox.io/s/y3pyp85zm1
TLDR-ããããŒã°ãªããã«refãé 眮ãããããããã£ã°ãªããã«é 眮ããŸãã