Angular 4에서 클릭시 요소로 스크롤


99

버튼을 눌렀을 때 대상으로 스크롤 할 수 있기를 원합니다. 나는 이런 생각을하고 있었다.

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

그리고 내 component.ts방법에서.

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

위의 코드는 유효하지 않지만 내가 생각하는 것을 보여주기위한 것임을 압니다. Angular에 대한 이전 경험없이 Angular 4를 배우기 시작했습니다. 나는 이와 같은 것을 찾고 있었지만 모든 예제는 Angular 4와 많이 다른 AngularJs에 있습니다.


1
구문에는 문제가 없지만 #target이 무엇인지 정의해야합니다.
wannadream

1
그래서이게 작동할까요? 임의의 숫자를 사용하고 내 함수에서 window.scrollTo (500)를 호출하면 아무 일도 일어나지 않습니다. 저는는 HTMLElement 될 것이라고 요소를 생각하고 있었다

그러나 #target은 무엇입니까? Angular는 그것을 해결하지 않을까요? 먼저 매개 변수없이 scroll ()을 테스트 할 수 있습니다.
wannadream

네 버튼에서 (click) = "scroll ()"을 시도하고 구성 요소에서 window.scrollTo (0, 500)를 시도했지만 아무 일도 일어나지 않습니다

2
하지만 500ms 지연으로 생성자에서 window.scrollTo (0, 500)를 수행하면 작동합니다

답변:


150

다음과 같이 할 수 있습니다.

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

그런 다음 구성 요소에서 :

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

편집 : 요소가 정의되지 않아 더 이상 작동하지 않는다는 주석이 표시됩니다. Angular 7에서 StackBlitz 예제 를 만들었는데 여전히 작동합니다. 누군가 작동하지 않는 예를 제공 할 수 있습니까?


어떤 이유로 정확한 코드를 실행하면 아무런 효과가 없습니다. 하드 코딩 된 window.scrollTo (0, 500)도 아무 작업도하지 않습니다

1
@ N15M0_jk 네, 필요한 것에 따라 다른 옵션과 함께 전달할 수있는 객체도 있습니다. developer.mozilla.org/en-US/docs/Web/API/Element/scrollIntoView
프랭크 모 디카

1
@Anthony scroll컴포넌트 의 함수에 전달할 요소를 참조 할 수 있습니다 . 클릭 이벤트가 scroll(target). 요소를 전달할 필요없이 구성 요소 내부에서 요소에 액세스하려면 @ViewChild.
Frank Modica

2
지금은 잘 작동합니다. 그러나 내가 어리석은 실수를 저지르고 id="target"대신 사용하기 전에 #target"el is undefined error"를주었습니다!
yashthakkar1173

1
내가 가진 요소가있는 경우 정의되지 않은 오류가 발생 믿고 #target내부입니다 *ngIf,하지만 당신이 사용하는 경우 작동합니다 @ViewChild@abbastec에서 링크 방법
spectacularbob

46

실제로 setTimeout또는 requestAnimationFrame또는 jQuery 를 사용하지 않고이를 수행하는 순수한 자바 스크립트 방식이 있습니다.

간단히 말해서 scrollView에서 스크롤하려는 요소를 찾아 scrollIntoView.

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

여기에 plunkr가 있습니다.


2
이 대답이 다른 두 가지 방법 : 1. 이것은 점프가 아닌 부드러운 스크롤링 애니메이션입니다. 2.이 답변은 창을 스크롤하지 않고 창 내에서 스크롤 뷰를 이동합니다. 예를 들어 창 내에 가로 스크롤 뷰가있는 경우입니다. plunkr에서 예제를 확인하십시오.
Jon

1
scrollIntoView의 scrollIntoViewOptions (인수로서의 객체)는 현재 Firefox 와만 호환됩니다.
Jesús Fuentes

Chrome 및 Firefox에서는 잘 작동하지만 Safari에서는 작동하지 않습니다.
Yamashiro Rion

45

Angular 4를 사용하여 수행 한 방법은 다음과 같습니다.

주형

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

이 기능을 구성 요소에 추가하십시오.

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

템플릿에서 elementRefs 또는 HTML ID를 설정하지 않았습니다. 스크롤하려는 'cat-'+ cat.category_id 요소는 정확히 어디에 있습니까?
Keegan

1
이것이 더 나은 대답입니다. 스크롤을 다른 구성 요소에 넣을 수 있습니다.
Dale Nguyen

이것은 받아 들여진 대답이어야합니다. Angular 9에서 작업 중입니다.
Sixteen

30

Angular 7에서 완벽하게 작동합니다.

HTML

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

구성 요소에서

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

2
{behavior : 'smooth'} 보너스
Squapl Recipes

그것은 나를 위해 일하고있어 ..에 대한 특별한 감사 {행동을 '부드럽게'}
Vibhu 쿠마

#target버튼 뒤에가 정의되어 있으면 작동하지 않습니다. 예를 들어 플로팅 헤더가있는 경우 관련이 있습니다.
Jonathan

21

Jon은 정답을 가지고 있으며 이것은 내 각도 5 및 6 프로젝트에서 작동합니다.

클릭하여 navbar에서 바닥 글로 부드럽게 스크롤하려면 :

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

바닥 글에서 머리글로 다시 스크롤하고 싶었 기 때문에이 함수가있는 서비스를 만들어 navbar 및 바닥 글 구성 요소에 삽입하고 필요한 곳에 'header'또는 'footer'를 전달했습니다. 실제로 사용 된 클래스 이름을 구성 요소 선언에 제공하는 것을 잊지 마십시오.

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

15

Angular에서 수행하는 또 다른 방법 :

마크 업 :

<textarea #inputMessage></textarea>

ViewChild()속성 추가 :

@ViewChild('inputMessage')
inputMessageRef: ElementRef;

scrollIntoView()함수를 사용하여 구성 요소 내부에서 원하는 곳으로 스크롤하십시오 .

this.inputMessageRef.nativeElement.scrollIntoView();

10

아래 코드 블록을 사용하여 뷰의 모든 요소 참조로 스크롤 할 수 있습니다. 대상 (elementref id )은 유효한 html 태그에있을 수 있습니다.

보기 (html 파일)

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

  

.ts파일,

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

7

다음과 같이 각도 DOM 요소에 대한 참조를 사용하여이를 달성 할 수 있습니다.

다음은 stackblitz 의 예입니다 .

구성 요소 템플릿 :

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

6

Angular에서 사용 ViewChild하고 ElementRef: HTML 요소에 ref를 제공하십시오.

<div #myDiv > 

구성 요소 내부 :

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

this.myDivRef.nativeElement요소에 도달하는 데 사용할 수 있습니다.


이것은 좋은 해결책이지만 문제는 탭을 다시로드 할 때만 작동하지만 routerLink에서는 작동하지 않는다는 것입니다. 이 문제에 대한 해결책이 있습니까?
Ahsan

-8

난 당신이 (예 : 요소를 찾기 위해 jQuery를 사용하여 그냥 물어하는지 같은 짓을 document.getElementById(...))하고 사용하며 .focus()전화를.


3
Angular를 사용할 때 jQuery가 정말로 필요합니까? Angular가 충분할 것 같은 느낌

100 % 확실하지는 않지만 Angular2에 대해 검증 및 리팩토링되지 않은 환경에 있었기 때문에 Angular에서 솔루션을 너무 열심히 검색하지 않고 액세스 할 수 있다는 것을 알고있는 것을 사용했습니다.
Kenneth Salomon

8
Jquery와 Angular를 사용해서는 안됩니다
Stefdelec

2
예, 저는 jQuery를 사용하지 말아야한다는 의견을 많이 배웠습니다. 당신은 다른 사람들이 당신 바로 위에 언급하지 않은 어떤 말도하지 않습니다.
Kenneth Salomon

겸손에 찬성했습니다. 나는 jQuery 답변이 SPA 프레임 워크로 전환하는 사람들에게 가치가 있음을 추가하고 싶습니다. 우리가 어떻게 사용했는지 보여주고 다른 솔루션을 추천하는 댓글을 확인합니다.
B2K

-17

jquery를 사용하여이 작업을 수행 할 수 있습니다.

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

HTML 코드 :

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

스크롤하려는 요소에 적용하십시오.

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

다음 은 stackblitz 샘플입니다.


1
이 작전은 구식 프레임 워크 (하위 투표)로 해결되지 않는 TypeScript 솔루션을 요구하는 것을 제외하고
ash

이것은 typescript 솔루션입니다.
GNS

1
당신은 내 요점을 놓쳤습니다. 당신의 대답은 단순히 ES *를 사용하는 대신 jQuery (가장 비효율적 인 방법으로 추가 할 수 있음)를 사용합니다. 상수도 유형을 선언하지 않습니다. 요청 된 것이 아닌 jQuery를 사용하는 잘못된 논리를 가진 나쁜 예입니다.
ash
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.