Angular 4'te tıklandığında öğeye kaydır


115

Bir düğmeye basıldığında bir hedefe kaydırabilmek istiyorum. Bunun gibi bir şey düşünüyordum.

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

Ve benim component.tsgibi bir yöntemimde.

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

Yukarıdaki kodun geçerli olmadığını biliyorum, sadece ne düşündüğümü göstermek için. Daha önce Angular deneyimi olmadan Angular 4'ü öğrenmeye başladım. Etrafta bunun gibi bir şey arıyordum ama tüm örnekler Angular 4'ten çok farklı olan AngularJs'de.


1
Söz diziminizde sorun yok, ancak #hedefin ne olduğunu tanımlamanız gerekiyor.
wannadream

1
Yani bu çalışmalı mı? Fonksiyonumda rastgele bir numara kullandığımda ve window.scrollTo (500) 'ü çağırdığımda hiçbir şey olmuyor. Bu öğenin bir HTMLElement olacağını düşünüyordum

Doğru, ancak, #target nedir, Angular bunu çözmeyecek mi? Scroll () öğesini önce parametre olmadan test edebilirsiniz.
wannadream

Evet,

2
Ancak yapıcıda 500ms gecikmeyle window.scrollTo (0, 500)

Yanıtlar:


163

Bunu şu şekilde yapabilirsin:

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

ve sonra bileşeninizde:

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

Düzenleme: Tanımlanmamış öğe nedeniyle bunun artık çalışmadığını belirten yorumlar görüyorum. Angular 7'de bir StackBlitz örneği oluşturdum ve hala çalışıyor. Birisi lütfen işe yaramadığı bir örnek verebilir mi?


1
@ N15M0_jk Evet, neye ihtiyacınız olduğuna bağlı olarak diğer seçeneklerle birlikte verebileceğiniz bir nesne de var. developer.mozilla.org/en-US/docs/Web/API/Element/scrollIntoView
Frank Modica

1
@Anthony scrollBileşen üzerindeki fonksiyona iletmek istediğiniz elemente referans vermenizi sağlar . Tıklama olayının çağırdığına dikkat edin scroll(target). Öğeyi içeri aktarmak zorunda kalmadan bileşenin içinden öğeye erişmek istiyorsanız, kullanabilirsiniz @ViewChild.
Frank Modica

2
Şimdi benim için iyi çalışıyor. Ama aptalca bir hata yapıp id="target"yerine kullanmadan önce #targetbana "el is undefined error" verdi!
yashthakkar1173

1
Tanımsız hatanın, öğesinin #targetbir içindeyse meydana geldiğine inanıyorum *ngIf, ancak @ViewChild@abbastec
spectacularbob

1
basit ve temiz. Benim için çalışıyor Angular 10
griffinleow

55

İşte Angular 4 kullanarak bunu nasıl yaptım.

Şablon

<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>

bu işlevi Bileşene ekleyin.

scroll(id) {
  console.log(`scrolling to ${id}`);
  let el = document.getElementById(id);
  el.scrollIntoView();
}

1
Şablonunuzda elementRefs veya HTML kimlikleri ayarlamadınız. Kaydırdığınız 'cat -' + cat.category_id öğesi tam olarak nerede?
Keegan

1
Bu daha iyi bir cevap. Kaydırmayı başka bir bileşene koyabilirsiniz.
Dale Nguyen

1
Kabul edilen cevap bu olmalıdır. Açısal 9 için Çalışma
On Altı

51

Bunu setTimeoutveya requestAnimationFrameveya jQuery kullanmadan gerçekleştirmenin aslında saf bir javascript yolu var .

Kısacası, kaydırmak istediğiniz öğeyi scrollView'da bulun ve kullanın scrollIntoView.

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

İşte bir plunkr .


3
Bu cevabın farklı olmasının 2 yolu: 1. Bu, bir atlama değil, hareketli yumuşak kaydırmadır. 2. Bu yanıt bir pencereyi kaydırmaz, ancak bir pencere içinde bir kaydırma görünümünü taşır. Örneğin, pencere içinde yatay bir kaydırma görünümünüz varsa. Bir örnek için plunkr'a bakın.
Jon

1
scrollIntoView'ın scrollIntoViewOptions (bağımsız değişken olarak nesne) şu anda yalnızca Firefox ile uyumludur.
Jesús Fuentes

Chrome ve Firefox için iyi çalışır, ancak Safari için çalışmaz.
Yamashiro Rion

41

Angular 7'de mükemmel çalışıyor

HTML

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

Bileşende

scroll(el: HTMLElement) {
    el.scrollIntoView({behavior: 'smooth'});
}

2
{davranış: 'pürüzsüz'} için bonus
Squapl Tarifler

Benim için çalışıyor .. {behaviour: 'smooth'} için özel teşekkürler
Vibhu kumar

1
Bu #target, düğmeden sonra tanımlanırsa çalışmaz , bu, örneğin kayan bir başlığınız varsa önemlidir ...
Jonathan

22

Jon'un doğru cevabı var ve bu açısal 5 ve 6 projelerimde işe yarıyor.

Gezinme çubuğundan altbilgiye sorunsuzca kaydırmak için tıklamak istersem:

<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' });
}

Altbilgiden başlığa geri dönmek istediğim için, bu işlevin bulunduğu bir hizmet oluşturdum ve onu navbar ve altbilgi bileşenlerine enjekte ettim ve gerektiğinde 'üstbilgi' veya 'altbilgi' olarak ilettim. Bileşen bildirimlerine kullanılan sınıf adlarını vermeyi unutmayın:

<app-footer class="footer"></app-footer>

15

Angular'da yapmanın başka bir yolu:

İşaretleme:

<textarea #inputMessage></textarea>

ViewChild()Mülk ekle :

@ViewChild('inputMessage')
inputMessageRef: ElementRef;

scrollIntoView()Fonksiyonu kullanarak bileşenin içinde istediğiniz herhangi bir yere gidin :

this.inputMessageRef.nativeElement.scrollIntoView();

12

Aşağıdaki kod bloğunu kullanarak görünümünüzdeki herhangi bir öğe referansına gidebilirsiniz. Hedefin (elementref kimliği ) herhangi bir geçerli html etiketinde olabileceğini unutmayın.

Görünümde (html dosyası)

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

  

üzerine .tsdosya

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

7

Bunu, aşağıdaki gibi bir açısal DOM öğesine başvurarak elde edebilirsiniz:

İşte stackblitz'deki örnek

bileşen şablonu:

<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>

7

Angular'da kullanabilir ViewChildve ElementRef: HTML öğenize bir ref verebilirsiniz

<div #myDiv > 

ve bileşeninizin içinde:

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

this.myDivRef.nativeElementelementine ulaşmak için kullanabilirsin


Bu iyi bir çözüm ancak sorun, yalnızca sekmeyi yeniden yüklediğimde ancak routerLink ile çalışmadığında çalışıyor olmasıdır. Bu problem için herhangi bir çözüm var mı arkadaşlar?
Ahsan

classbununla nasıl kullanabilirim ?
C Alonso C Ortega

0

Bu numarayı yapmam gerekiyor, belki de özel bir HTML öğesi kullandığım içindir. Bunu yapmazsam, targetiçinde sahip onItemAmounterClickolmayacakscrollIntoView yöntemi

.html

<div *ngFor"...">
      <my-component #target (click)="clicked(target)"></my-component>
</div>

.ts

onItemAmounterClick(target){
  target.__ngContext__[0].scrollIntoView({behavior: 'smooth'});
}

-8

Sadece jQuery'yi kullanarak öğeyi (örneğin document.getElementById(...)) bulup .focus()aramayı kullanarak istediğiniz gibi bir şey yaptım .


3
Angular'ı kullanırken jQuery gerçekten gerekli mi? Angular yeterli olmalı gibi geliyor

% 100 emin değilim, ancak Angular2 için doğrulanmamış ve yeniden düzenlenmemiş bir ortamdaydım, bu yüzden Angular'da bir çözüm için çok fazla arama yapmadım ve sadece erişebileceğimi bildiğim bir şeyle gittim.
Kenneth Salomon

8
Jquery ve
Angular'ı

2
Evet evet, çok şey öğrendim ve herkes jQuery kullanmamam gerektiğini söylüyor. Başkalarının tam üstünüzde yorum yapmadığı hiçbir şey söylemiyorsunuz.
Kenneth Salomon

Alçakgönüllülük için sana destek verdim. JQuery yanıtlarının SPA çerçevelerine geçiş yapanlar için bir değeri olduğunu eklemek isterim. Bunu nasıl yaptığımızı göstererek ve başka çözümler öneren yorumları görerek.
B2K

-17

Bunu jquery kullanarak yapabilirsiniz:

ts kodu:

    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();
    }
  }

HTML Kodu :

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

Bunu kaydırmak istediğiniz öğelere uygulayın:

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

İşte bir stackblitz örneği.


1
Bu operasyon dışında, TypeScript çözümlerinin kullanılmayan bir çerçeve ile geçici çözüm istemesi (olumsuz oylama)
ash

bu daktilo çözümüdür.
Gns

1
Benim fikrimi kaçırdınız, cevabınız sadece ES * kullanmak yerine jQuery kullanıyor (en verimsiz şekilde ekleyebilir miyim). Sabitleriniz de türlerini belirtmiyor. Sadece jQuery kullanan kötü mantıklı kötü bir örnek, bu sorulan şey değildi.
Ash
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.