Gulir ke elemen saat diklik di Angular 4

102

Saya ingin dapat menggulir ke target saat tombol ditekan. Saya sedang memikirkan sesuatu seperti ini.

<button (click)="scroll(#target)">Button</button>

Dan dalam component.tsmetode saya seperti.

scroll(element) {
    window.scrollTo(element.yPosition)
}

Saya tahu bahwa kode di atas tidak valid tetapi hanya untuk menunjukkan apa yang saya pikirkan. Saya baru saja mulai mempelajari Angular 4 tanpa pengalaman sebelumnya tentang Angular. Saya telah mencari-cari sesuatu seperti ini tetapi semua contoh ada di AngularJs yang sangat berbeda dengan Angular 4

BuZZ-dEE
sumber
1
Sintaks Anda tidak memiliki masalah tetapi Anda perlu menentukan apa itu #target.
wannadream
1
Jadi ini harus bekerja? Ketika saya menggunakan nomor arbitrer dan memanggil window.scrollTo (500) dalam fungsi saya, tidak ada yang terjadi. Saya berpikir elemen itu akan menjadi HTMLElement
Benar, bagaimanapun, apa itu #target, Angular tidak akan menyelesaikannya? Anda dapat menguji scroll () tanpa parameter terlebih dahulu.
wannadream
Ya saya mencoba (klik) = "scroll ()" di tombol dan
2
Tetapi ketika saya melakukan window.scrollTo (0, 500) di konstruktor dengan penundaan 500ms itu berfungsi

Jawaban:

154

Anda bisa melakukannya seperti ini:

<button (click)="scroll(target)"></button>
<div #target>Your target</div>

lalu di komponen Anda:

scroll(el: HTMLElement) {
    el.scrollIntoView();
}

Edit: Saya melihat komentar yang menyatakan bahwa ini tidak lagi berfungsi karena elemen tidak ditentukan. Saya membuat contoh StackBlitz di Angular 7 dan masih berfungsi. Bisakah seseorang memberikan contoh di mana itu tidak berfungsi?

Frank Modica
sumber
Untuk beberapa alasan menjalankan kode yang tepat tidak melakukan apa-apa bagi saya. Bahkan jendela hardcode. ScrollTo (0, 500) tidak melakukan apa
1
@ N15M0_jk Ya, ada juga objek yang dapat Anda berikan dengan opsi lain, tergantung pada apa yang Anda butuhkan. developer.mozilla.org/en-US/docs/Web/API/Element/scrollIntoView
Frank Modica
1
@Anthony Ini memungkinkan Anda untuk mereferensikan elemen yang ingin Anda teruskan ke scrollfungsi pada komponen. Perhatikan bahwa event click memanggil scroll(target). Jika Anda ingin mendapatkan akses ke elemen dari dalam komponen tanpa harus meneruskan elemen tersebut, Anda dapat menggunakan @ViewChild.
Frank Modica
2
Ini bekerja dengan baik dengan saya sekarang. Tapi sebelum saya membuat kesalahan konyol dan digunakan id="target"sebagai pengganti #targetdan itu memberi saya "kesalahan el tidak terdefinisi"!
yashthakkar1173
1
Saya percaya kesalahan tak terdefinisi terjadi jika elemen dengan #targetada di dalam *ngIf, tetapi seharusnya berfungsi jika Anda menggunakan @ViewChildmetode di tautan dari @abbastec
spektakulerbob
47

Sebenarnya ada cara javascript murni untuk mencapai ini tanpa menggunakan setTimeoutatau requestAnimationFrameatau jQuery.

Singkatnya, temukan elemen di scrollView yang ingin Anda gulir, dan gunakan scrollIntoView.

el.scrollIntoView({behavior:"smooth"});

Ini plunkr .

Jon
sumber
3
2 cara jawaban ini berbeda: 1. Ini adalah animasi scrolling halus, bukan lompatan. 2. Jawaban ini tidak menggulir jendela, tetapi memindahkan tampilan gulir dalam jendela. Misalnya, jika Anda memiliki tampilan gulir horizontal di dalam jendela. Periksa plunkr sebagai contoh.
Jon
1
scrollIntoView's scrollIntoViewOptions (objek sebagai argumen) hanya kompatibel dengan Firefox saat ini.
Jesús Fuentes
Berfungsi dengan baik untuk Chrome dan Firefox, tetapi tidak untuk Safari.
Yamashiro Rion
45

Inilah cara saya melakukannya menggunakan Angular 4.

Template

<div class="col-xs-12 col-md-3">
  <h2>Categories</h2>
  <div class="cat-list-body">
    <div class="cat-item" *ngFor="let cat of web.menu | async">
      <label (click)="scroll('cat-'+cat.category_id)">{{cat.category_name}}</label>
    </div>
  </div>
</div>

tambahkan fungsi ini ke Komponen.

scroll(id) {
  console.log(`scrolling to ${id}`);
  let el = document.getElementById(id);
  el.scrollIntoView();
}
LH7
sumber
Anda belum menyetel elementRefs atau ID HTML di template Anda. Di mana tepatnya elemen 'cat -' + cat.category_id yang Anda gulir?
Keegan
1
Ini jawaban yang lebih baik. Anda dapat meletakkan scroll ke komponen lain.
Dale Nguyen
Ini harus menjadi jawaban yang diterima. Bekerja untuk Angular 9.
Sixteen
33

Di Angular 7 bekerja dengan sempurna

HTML

<button (click)="scroll(target)">Click to scroll</button>
<div #target>Your target</div>

Dalam komponen

  scroll(el: HTMLElement) {
    el.scrollIntoView({behavior: 'smooth'});
  }
Robert S.
sumber
2
bonus untuk {behavior: 'smooth'}
Squapl Recipes
Ini bekerja untuk saya .. terima kasih khusus untuk {perilaku: 'mulus'}
Vibhu kumar
Ini tidak akan berfungsi jika #targetditentukan setelah tombol, yang relevan jika Anda memiliki header mengambang misalnya ...
Jonathan
21

Jon memiliki jawaban yang benar dan ini berfungsi di proyek sudut 5 dan 6 saya.

Jika saya ingin mengklik untuk menggulir dengan lancar dari navbar ke footer:

<button (click)="scrollTo('.footer')">ScrolltoFooter</button>
<footer class="footer">some code</footer>

scrollTo(className: string):void {
   const elementList = document.querySelectorAll('.' + className);
   const element = elementList[0] as HTMLElement;
   element.scrollIntoView({ behavior: 'smooth' });
}

Karena saya ingin menggulir kembali ke header dari footer, saya membuat layanan tempat fungsi ini berada dan memasukkannya ke dalam komponen navbar dan footer dan meneruskannya ke 'header' atau 'footer' jika diperlukan. ingatlah untuk benar-benar memberikan deklarasi komponen nama kelas yang digunakan:

<app-footer class="footer"></app-footer>
Stephen E.
sumber
15

Cara lain untuk melakukannya di Angular:

Markup:

<textarea #inputMessage></textarea>

Tambahkan ViewChild()properti:

@ViewChild('inputMessage')
inputMessageRef: ElementRef;

Gulir ke mana pun Anda inginkan di dalam komponen menggunakan scrollIntoView()fungsi:

this.inputMessageRef.nativeElement.scrollIntoView();
Schnapz
sumber
10

Anda dapat menggulir ke elemen apapun ref pada tampilan Anda dengan menggunakan blok kode di bawah ini. Perhatikan bahwa target (elementref id ) bisa berada di tag html yang valid.

Di tampilan (file html)

<div id="target"> </div>
<button (click)="scroll()">Button</button>
 

  

di .tsfile,

scroll() {
   document.querySelector('#target').scrollIntoView({ behavior: 'smooth', block: 'center' });
}
Ifesinachi Bryan
sumber
7

Anda dapat mencapainya dengan menggunakan referensi ke elemen DOM sudut sebagai berikut:

Berikut adalah contoh di stackblitz

template komponen:

<div class="other-content">
      Other content
      <button (click)="element.scrollIntoView({ behavior: 'smooth', block: 'center' })">
        Click to scroll
      </button>
    </div>
    <div id="content" #element>
      Some text to scroll
</div>
Andres Gardiol
sumber
6

Dalam Angular Anda dapat menggunakan ViewChilddan ElementRef: memberikan elemen HTML Anda referensi

<div #myDiv > 

dan di dalam komponen Anda:

import { ViewChild, ElementRef } from '@angular/core';
@ViewChild('myDiv') myDivRef: ElementRef;

dapat Anda gunakan this.myDivRef.nativeElementuntuk mendapatkan elemen Anda

M.Amer
sumber
Ini adalah solusi yang baik tetapi masalahnya adalah itu hanya berfungsi ketika saya memuat ulang tab tetapi tidak dengan routerLink. Ada solusi untuk masalah ini guys?
Ahsan
-8

Saya telah melakukan sesuatu seperti yang Anda minta hanya dengan menggunakan jQuery untuk menemukan elemen (seperti document.getElementById(...)) dan menggunakan .focus()panggilan.

Kenneth Salomon
sumber
3
Apakah jQuery benar-benar dibutuhkan saat menggunakan Angular? Terasa seperti Angular sudah cukup
Tidak 100% yakin tetapi saya berada di lingkungan yang belum divalidasi dan direfraktor untuk Angular2 jadi saya tidak mencari terlalu keras untuk solusi di Angular dan hanya pergi dengan sesuatu yang saya tahu akan memiliki akses ke.
Kenneth Salomon
8
Anda tidak boleh menggunakan Jquery dan Angular
Stefdelec
2
Ya ya, saya telah belajar banyak dan semua orang berkomentar bahwa saya tidak boleh menggunakan jQuery. Anda tidak mengatakan apa pun yang belum dikomentari orang lain tepat di atas Anda.
Kenneth Salomon
Menghargai Anda atas kerendahan hati. Saya ingin menambahkan bahwa jawaban jQuery memiliki beberapa nilai bagi mereka yang bertransisi ke kerangka SPA. Dengan menunjukkan bagaimana kami biasa melakukannya, dan melihat komentar yang merekomendasikan solusi lain.
B2K
-17

Anda dapat melakukan ini dengan menggunakan jquery:

kode ts:

    scrollTOElement = (element, offsetParam?, speedParam?) => {
    const toElement = $(element);
    const focusElement = $(element);
    const offset = offsetParam * 1 || 200;
    const speed = speedParam * 1 || 500;
    $('html, body').animate({
      scrollTop: toElement.offset().top + offset
    }, speed);
    if (focusElement) {
      $(focusElement).focus();
    }
  }

kode html:

<button (click)="scrollTOElement('#elementTo',500,3000)">Scroll</button>

Terapkan ini pada elemen yang ingin Anda gulir:

<div id="elementTo">some content</div>

Berikut adalah contoh stackblitz.

Gns
sumber
1
Kecuali operasi ini meminta agar solusi TypeScript tidak berfungsi dengan kerangka kerja yang sudah usang (tidak memilih)
abu
ini adalah solusi ketikan.
Gns
1
Anda melewatkan poin saya, jawaban Anda menggunakan jQuery (bolehkah saya menambahkan dengan cara yang paling tidak efisien) daripada hanya menggunakan ES *. Konstanta Anda juga tidak mendeklarasikan tipenya. Itu hanya contoh buruk dengan logika buruk menggunakan jQuery yang bukan itu yang diminta.
abu