React-window: .scrollTo()/ .scrollToIndex()のアニメーション化❓

作成日 2018年07月20日  ·  12コメント  ·  ソース: bvaughn/react-window

こんにちは :)

この素晴らしいlibをありがとう!

私はそれを実験していて、 scrollTo() / scrollToIndex()を使用するときに、スクロール動作(「スムーズスクロール」)をアニメーション化することがどういうわけか可能かどうか疑問に思いました。

💬 question

最も参考になるコメント

これは、スクロール可能なdivへの参照を提供するouterRef小道具を使用すると簡単に実行できます。

次に、それを標準のElement.scrollTo()APIと組み合わせて使用​​でき

だからそれはこれに沿った何かになるでしょう:

export default VirtualizedList extends React.Component {
   constructor() {
     this.listRef = React.createRef();
     this.scrollableContainerRef = React.createRef();
   }

  scrollTo(scrollOffset) {
    // note that my list is vertical which is why I am feeding this to the "top" prop.
    this.scrollableContainerRef.current.scrollTo({ 
      left: 0, 
      top: scrollOffset,
      behavior: 'smooth',
    });
  }

  render() {
    <List 
      ref={this.listRef}
      outerRef={this.scrollableContainerRef}
      layout="vertical"
      ...
  }
}

注:簡潔にするために、上記の無関係なコードと小道具をすべて削除しました。

全てのコメント12件

ありがとう!

うん、あなたはこのようなことをすることができます: https

ありがとう、それは助けになります!

これはより良いでしょうが、すべてのブラウザで機能するわけではありません(ただし、ポリフィルがあります):

...
import { findDOMNode } from 'react-dom'

class MyScroller extends React.Component {
   list = React.createRef()
 scrollToAnimated(index) {
  const el = findDOMNode(this.list.current)
  if (el) {
    el.scrollTo({
     behavior: 'smooth',
     left: index * itemWidth
    })
  }
 }

 render() {
   return <List ref={this.list} ... />
 }
}

react-windowを介してこれにアクセスするか、インデックス@bvaughnの計算されたオフセットを取得する適切な方法があれば素晴らしいと思います。

この例のサンドボックスは削除されているようです。別のサンドボックスはありますか?

サンドボックスはまだそこにあります。

ええ、申し訳ありませんが、どういうわけかそれはFFで削除されたように表示されましたが、Chrome、おそらく私のアドオンでは問題ありません

これは、スクロール可能なdivへの参照を提供するouterRef小道具を使用すると簡単に実行できます。

次に、それを標準のElement.scrollTo()APIと組み合わせて使用​​でき

だからそれはこれに沿った何かになるでしょう:

export default VirtualizedList extends React.Component {
   constructor() {
     this.listRef = React.createRef();
     this.scrollableContainerRef = React.createRef();
   }

  scrollTo(scrollOffset) {
    // note that my list is vertical which is why I am feeding this to the "top" prop.
    this.scrollableContainerRef.current.scrollTo({ 
      left: 0, 
      top: scrollOffset,
      behavior: 'smooth',
    });
  }

  render() {
    <List 
      ref={this.listRef}
      outerRef={this.scrollableContainerRef}
      layout="vertical"
      ...
  }
}

注:簡潔にするために、上記の無関係なコードと小道具をすべて削除しました。

scrollTo

機能コンポーネント内でこれをどのように行いますか? すでにfromとtoの位置変数があり、リストをPositionA(現在のscrollTop)からPositionB(定義した位置)にスクロールさせようとしています。 機能コンポーネントで使用すると構文にエラーが表示されるため、scrollTo(scrollOffset){を機能させるのに問題があります。 特定の状態が変化したときにスクロール動作をトリガーしたいと思います。

テストされていない:

function MyComp() {
    const listOuterRef = useRef(null)

    const scrollTo = useCallback((scrollOffset) => {
        listOuterRef.current?.scrollTo({ 
          left: 0, 
          top: scrollOffset,
          behavior: 'smooth',
        });
    }, [])


    return <List outerRef={listOuterRef} ... />
}

あなたが空想になりたい場合:

function useSmoothScroll() {
    const listOuterRef = useRef(null)

    const scrollTo = useCallback((scrollOffset) => {
        listOuterRef.current?.scrollTo({ 
          left: 0, 
          top: scrollOffset,
          behavior: 'smooth',
        });
    }, [])
    return {
        scrollableRef: listOuterRef,   
        scrollTo
     }
}
function MyComp() {
    const { scrollableRef, scrollTo } =  useSmoothScroll()
    // use scrollTo() in a useEffect or onClick
    return <List outerRef={scrollableRef} ... />
}

テストされていない:

function MyComp() {
    const listOuterRef = useRef(null)

    const scrollTo = useCallback((scrollOffset) => {
        listOuterRef.current?.scrollTo({ 
          left: 0, 
          top: scrollOffset,
          behavior: 'smooth',
        });
    }, [])


    return <List outerRef={listOuterRef} ... />
}

あなたが空想になりたい場合:

function useSmoothScroll() {
    const listOuterRef = useRef(null)

    const scrollTo = useCallback((scrollOffset) => {
        listOuterRef.current?.scrollTo({ 
          left: 0, 
          top: scrollOffset,
          behavior: 'smooth',
        });
    }, [])
    return {
        scrollableRef: listOuterRef,   
        scrollTo
     }
}
function MyComp() {
    const { scrollableRef, scrollTo } =  useSmoothScroll()
    // use scrollTo() in a useEffect or onClick
    return <List outerRef={scrollableRef} ... />
}

返信ありがとうございます。 私は可能な解決策を研究するために数え切れないほどの時間を費やしました、そしてこれは私を大いに助けました。 あなたの助けのおかげでスクロールが機能しました! 残念ながら、私の実装はreact-windowで非常に遅れているため、react-virtualized Listに戻す必要があり、私が行っていることに対してパフォーマンスが向上しました。 ただし、react-virtualizedにはouterRefがなく、スクロール可能なdivの参照を設定する方法がわからないため、react-virtualizedでこの方法でスクロールをアニメーション化することはできません。

リストを使用してreact-virtualizedを使用すると、このようなことがどのように可能になるか考えていますか?

jqueryは、動作を微調整するための多くのオプションを備えた簡単なスクロールアニメーション関数を提供します。
outerRefをjquery要素に変換してから、その要素でanimate関数を呼び出すことができます。
https://api.jquery.com/animate/

擬似コード:

const listOuterRef = useRef();

useEffect(() => {
 $(listOuterRef.current).animate(
    {
      scrollTop: 100,
    },
    {
      duration: 500,
      // other options can be passed to customize animation behavior such as easing, callbacks, etc
    },
  );
});

return <List outerRef={listOuterRef}>...</List>;

jqueryはReactの世界ではあまり使用されていないようですが、DOMを直接読み取り/書き込みする必要があるシナリオには最適です。 ただし、絶対に控えめに使用する必要があります。 そもそもReactを使うことの全体的なポイントを簡単に損なう可能性があるからです。

グローバルスタイルまたはコンポーネントスタイルに追加するだけです。

.List {scroll-behavior: smooth;}

IMHO、最もシンプルでエレガントなソリューション、なぜ誰もそれを提案しなかったのか分かりません

このページは役に立ちましたか?
0 / 5 - 0 評価