web-dev-qa-db-ja.com

ScrollToリストビューの特定のアイテムIonic 2

ionic 2。のリストビューの特定のアイテムにスクロールしたい2.配列にバインドされたリストビューがあります。

export class TestPage {
    @ViewChild(Content) content: Content;
    public items: Array<Object> = [];

    ionViewWillEnter() {
        console.log(this.navParams.data);
        this.customService.getArray(this.params.index).then((items) => {
            this.items = items;
                //scroll to item
                // this.content.scrollTo()
        });
     }
}

ビューは次のとおりです。

<ion-list [virtualScroll]="items" approxItemHeight="120px" approxItemWidth="100%" 
    class="items-listview list list-md">
  <button class="items-listview-item item item-md" *virtualItem="let item">
    <div class="items-listview-text">
        {{ item.text }}<span>{{item.index}}</span>
    </div>
  </button>
</ion-list>

scrollTo 位置、つまり上下のみをサポートし、要素自体はサポートしないことがわかります。リストビューアイテム(例:アイテム番号150)自体をスクロールするにはどうすればよいですか? item no 150の位置を取得し、scrollToに渡すにはどうすればよいですか?

8
DotNet Dreamer

私が思いついた解決策を投稿しています。まず、各リストビューアイテムに一意のIDを指定してから、ListViewを選択する必要があります。

@ViewChild(VirtualScroll) listView: VirtualScroll;

その後、(バッファ比を動的に変更していたため)スクロール後にリストビューのサイズを変更するタイムアウトを持つ関数(次の)ScrollToを作成しました。

private scrollTo(index: number) {
    let key = '#customIds_' + index;

    let hElement: HTMLElement = this.content._elementRef.nativeElement;
    let element = hElement.querySelector(key);
    element.scrollIntoView();

    //wait till scroll animation completes
    setTimeout(() => {
        //resize it! otherwise will not update the bufferRatio
        this.listView.resize();
    },500);
}

最後に、リストビューが読み込まれるまで待っていたので、2秒遅れてこの関数を呼び出しました。

//must be delay otherwise content scroll doesn't go to element properly..magic!
setTimeout(() => {
    this.scrollTo('someId');
}, 1000);
2
DotNet Dreamer

各アイテムにIDを割り当てることができます([id]="'item' + item.index"のようなことを実行してから、コードでそのIDを使用してoffsetTopを取得します。

scrollTo(elementId:string) {
    let yOffset = document.getElementById(elementId).offsetTop;
    this.content.scrollTo(0, yOffset, 4000)
}
5
sebaferreras

現在受け入れられている回答は、親要素に対してのみスクロールされたため、(DOMをトラバースせずに)選択された要素までスクロールするために私が思いついたものは次のとおりです。

  scrollTo(element:string) {
    let elem = document.getElementById(element);
    var box = elem.getBoundingClientRect();

    var body = document.body;
    var docEl = document.documentElement;

    var scrollTop = window.pageYOffset || docEl.scrollTop || body.scrollTop;
    var clientTop = docEl.clientTop || body.clientTop || 0;
    var top  = box.top +  scrollTop - clientTop;
    var cDim = this.content.getContentDimensions();

    var scrollOffset = Math.round(top) + cDim.scrollTop - cDim.contentTop;

    this.content.scrollTo(0, scrollOffset, 500);
  }
4
jonesy827