스크롤 전략
스크롤 전략은 제공된 IgxOverlayService
에서 스크롤이 처리되는 방식을 결정합니다. 네 가지 스크롤 전략이 있습니다.
- NoOperation- 아무 작업도 수행하지 않습니다.
- 차단- 이벤트가 취소되고 구성 요소가 창과 함께 스크롤되지 않습니다.
- 닫기- 허용 오차를 사용하고 허용 오차를 초과하는 경우 스크롤 시 확장된 구성 요소를 닫습니다.
- 절대- 모든 것을 스크롤합니다.
용법
모든 스크롤 전략에는 다음과 같은 메서드가 있습니다.
initialize
- 스크롤 전략을 초기화합니다. 문서 참조, 오버레이 서비스 및 렌더링된 구성 요소의 ID가 필요합니다.attach
- 지정된 요소 또는 문서에 스크롤 전략을 첨부합니다.detach
- 스크롤 전략을 분리합니다.
this.scrollStrategy.initialize(document, overlayService, id);
this.scrollStrategy.attach();
this.scrollStrategy.detach();
typescript
시작하기
스크롤 전략은 overlay.attach()
메서드가 호출될 때 overlaySettings
변수의 속성으로 전달됩니다.
// Initializing and using overlay settings
const overlaySettings: OverlaySettings = {
positionStrategy: new GlobalPositionStrategy(),
scrollStrategy: new AbsoluteScrollStrategy(), //Passes the scroll strategy
modal: true,
closeOnOutsideClick: true
}
const overlayId = overlay.attach(dummyElement, overlaySettings);
typescript
오버레이에서 사용되는 스크롤 전략을 변경하려면 오버레이에 전달된 overlaySettings
객체의 scrollStrategy
속성을 재정의하세요. 전략이 이미 연결된 경우 이전에 생성된 ID를 분리해야 합니다.
// overlaySettings is an existing object of type OverlaySettings
// to override the scroll strategy
const newOverlaySettings = Object.assing({}, overlaySettings);
Object.assing(newOverlaySettings, {
scrollStrategy: new CloseScrollStrategy()
})
const overlayId = overlay.attach(dummyElement, newOverlaySettings);
overlay.show(overlayId);
typescript
종속성
스크롤 전략을 사용하려면 다음과 같이 가져옵니다.
import { NoOpScrollStrategy } from "./scroll/NoOpScrollStrategy";
typescript
스크롤 전략
스크롤 전략을 overlaySettings
객체에 전달하여 오버레이가 스크롤을 처리하는 방법을 결정할 수 있습니다. 아래 데모에서는 별도의 scrollStrategies
간의 차이점을 보여줍니다.
import { Component, ElementRef, OnDestroy, OnInit, ViewChild, ViewContainerRef, inject } from '@angular/core';
import { AbsoluteScrollStrategy, BlockScrollStrategy, CloseScrollStrategy, ConnectedPositioningStrategy, IgxOverlayService, NoOpScrollStrategy, IgxIconComponent } from 'igniteui-angular';
import { Subject } from 'rxjs';
import { takeUntil } from 'rxjs/operators';
import { MyDynamicCardComponent } from '../overlay-dynamic-card/overlay-dynamic-card.component';
@Component({
selector: 'app-overlay-sample',
styleUrls: ['./overlay-scroll-sample-2.component.scss'],
templateUrl: './overlay-scroll-sample-2.component.html',
providers: [IgxOverlayService],
imports: [IgxIconComponent, MyDynamicCardComponent]
})
export class OverlayScrollSample2Component implements OnInit, OnDestroy {
private overlay = inject<IgxOverlayService>(IgxOverlayService);
private viewContainerRef = inject(ViewContainerRef);
@ViewChild('scrollDemo', { static: true })
public scrollDemo: ElementRef;
@ViewChild(MyDynamicCardComponent, { static: true })
public overlayDemo: MyDynamicCardComponent;
@ViewChild('mainContainer', { static: true })
public mainContainer: ElementRef;
public previewHidden = false;
private destroy$ = new Subject<boolean>();
private _overlayId: string;
private _target: HTMLElement;
constructor() {
this.overlay.opening
.pipe(takeUntil(this.destroy$))
.subscribe(() => this.previewHidden = true);
this.overlay
.closed
.pipe(takeUntil(this.destroy$))
.subscribe(() => this.previewHidden = false);
}
public ngOnInit(): void {
(this.mainContainer.nativeElement as HTMLElement).style.height = '450px';
this.overlay.opening.subscribe(() => {
this.previewHidden = true;
});
this.overlay.closing.subscribe(() => {
this.previewHidden = false;
});
}
public onClickScrollStrategy(strategy: string) {
let scrollStrategy;
const positionStrategy = new ConnectedPositioningStrategy();
switch (strategy) {
case ('absolute'):
scrollStrategy = new AbsoluteScrollStrategy();
this._target = this.scrollDemo.nativeElement.children[0];
break;
case ('block'):
scrollStrategy = new BlockScrollStrategy();
this._target = this.scrollDemo.nativeElement.children[1];
break;
case ('close'):
scrollStrategy = new CloseScrollStrategy();
this._target = this.scrollDemo.nativeElement.children[2];
break;
default:
scrollStrategy = new NoOpScrollStrategy();
this._target = this.scrollDemo.nativeElement.children[3];
}
if (this._overlayId) {
this.overlay.detach(this._overlayId);
delete this._overlayId;
}
this._overlayId = this.overlay.attach(MyDynamicCardComponent, this.viewContainerRef, {
target: this._target,
positionStrategy,
scrollStrategy,
modal: false,
closeOnOutsideClick: true
});
this.overlay.show(this._overlayId);
}
public ngOnDestroy(): void {
this.destroy$.next(true);
this.destroy$.complete();
if (this._overlayId) {
this.overlay.detach(this._overlayId);
delete this._overlayId;
}
}
}
ts<div class='overlay-sample' #mainContainer>
<div class='container'>
<div class='container__row'>
<div class='section__row--wide'>
<div class='section__container--wide' #scrollDemo>
<span (click)="onClickScrollStrategy('absolute')">
<igx-icon>notifications</igx-icon>
<p>Absolute</p>
</span>
<span (click)="onClickScrollStrategy('block')">
<igx-icon>notifications</igx-icon>
<p>Block</p>
</span>
<span (click)="onClickScrollStrategy('close')">
<igx-icon>notifications</igx-icon>
<p>Close</p>
</span>
<span (click)="onClickScrollStrategy('')">
<igx-icon>notifications</igx-icon>
<p>None</p>
</span>
</div>
</div>
</div>
</div>
<div class='container' [hidden]="previewHidden">
<app-overlay-dynamic-card-component></app-overlay-dynamic-card-component>
</div>
</div>
htmlbody {
overflow-y: scroll !important;
}
.overlay-sample {
padding: 32px 0px 32px 32px;
display: flex;
flex-direction: row;
height: 200px;
overflow-y: scroll;
}
.container__row > div, .section__container--wide > span, .section__position-element > div {
display: inline-block;
}
.section__row--wide, .container__row, .section__header {
width: 100%;
}
.section__row > span {
height: 48px;
}
.section__row--wide, .section__container--wide > span {
height: 80px;
max-width: 320px;
}
span:hover {
border: 1px solid #e41c77;
box-sizing: border-box;
cursor: pointer;
}
.section__container--wide {
align-content: flex-start;
display: flex;;
}
.section__container--wide > span {
text-align: center;
vertical-align: middle;
line-height: 12px;
font-weight: 500;
width: 80px;
padding-top: 16px;
p {
margin-top: 0px;
}
}
.section__position-element, .section__position-header {
width: 144px;
text-align: center;
}
.section__separator {
width: 32px;
}
.container {
width: 50%;
height: 600px;
display: flex;
flex-direction: column;
align-items: center;
}
.overlay__element {
width: 288px;
height: 144px;
}
.section__header {
max-height: 96px;
text-align: left;
font-weight: 700;
font-size: 16px;
}
.container__row {
height: 100%;
text-align: left;
margin-top: 16px;
}
.section__position-element, .section__row--wide {
box-shadow: 0 1px 3px 0 rgba(0, 0, 0, 0.2), 0 1px 1px 0 rgba(0, 0, 0, 0.14), 0 2px 1px -1px rgba(0, 0, 0, 0.12);
}
scss
이 샘플이 마음에 드시나요? 전체 Ignite UI for Angular 툴킷에 액세스하고 몇 분 안에 나만의 앱을 구축해 보세요. 무료로 다운로드하세요.
모달
overlaySettings
객체를 사용하면 부울 속성(modal
)을 전달할 수도 있습니다. 오버레이 표시 방법을 제어합니다.
-
modal
속성이false
인 경우 요소는 DOM 전경에 연결되지만 모든 항목은 여전히 활성화되어 상호 작용할 수 있습니다(예: 스크롤, 클릭 등). -
modal
속성이true
이면 요소가 DOM 전경에 연결되고 오버레이 차단기가 그 뒤에 래핑되어 모든 이벤트의 전파를 중지합니다.
import { Component, ElementRef, OnDestroy, ViewChild, inject } from '@angular/core';
import { AbsoluteScrollStrategy, AutoPositionStrategy, ConnectedPositioningStrategy, ElasticPositionStrategy, GlobalPositionStrategy, HorizontalAlignment, IgxOverlayService, OverlaySettings, PositionSettings, VerticalAlignment, IgxSwitchComponent, IgxIconComponent, IgxCardComponent, IgxCardHeaderComponent, IgxCardContentDirective } from 'igniteui-angular';
import { FormsModule } from '@angular/forms';
// tslint:disable:object-literal-sort-keys
@Component({
selector: 'app-overlay-sample',
styleUrls: ['./overlay-scroll-sample-1.component.scss'],
templateUrl: './overlay-scroll-sample-1.component.html',
providers: [IgxOverlayService],
imports: [IgxSwitchComponent, FormsModule, IgxIconComponent, IgxCardComponent, IgxCardHeaderComponent, IgxCardContentDirective]
})
export class OverlayScrollSample1Component implements OnDestroy {
private overlay = inject<IgxOverlayService>(IgxOverlayService);
@ViewChild('modalDemo', { static: true })
public modalDemo: ElementRef;
@ViewChild('overlayDemo', { static: true })
public overlayDemo: ElementRef;
@ViewChild('mainContainer', { static: true })
public mainContainer: ElementRef;
public modalValue = true;
private _defaultPositionSettings: PositionSettings = {
horizontalDirection: HorizontalAlignment.Center,
horizontalStartPoint: HorizontalAlignment.Center,
verticalDirection: VerticalAlignment.Middle,
verticalStartPoint: VerticalAlignment.Middle
};
private _overlaySettings: OverlaySettings = {
positionStrategy: new GlobalPositionStrategy(),
scrollStrategy: new AbsoluteScrollStrategy(),
modal: true,
closeOnOutsideClick: true
};
private _overlayId: string;
public onClickModal(event: Event, strategy: string) {
event.stopPropagation();
const positionSettings = Object.assign(Object.assign({}, this._defaultPositionSettings), {
horizontalDirection: HorizontalAlignment.Right,
horizontalStartPoint: HorizontalAlignment.Right,
verticalDirection: VerticalAlignment.Bottom,
verticalStartPoint: VerticalAlignment.Bottom
});
let positionStrategy;
switch (strategy) {
case ('auto'):
positionStrategy = new AutoPositionStrategy(positionSettings);
break;
case ('elastic'):
positionStrategy = new ElasticPositionStrategy(positionSettings);
break;
case ('connected'):
positionStrategy = new ConnectedPositioningStrategy(positionSettings);
break;
default:
positionStrategy = new GlobalPositionStrategy(Object.assign(positionSettings, {
horizontalDirection: HorizontalAlignment.Center,
verticalDirection: VerticalAlignment.Middle
}));
}
const showSettings = Object.assign(Object.assign({}, this._overlaySettings), {
target: this.modalDemo.nativeElement,
modal: this.modalValue,
positionStrategy
});
if (this._overlayId) {
this.overlay.detach(this._overlayId);
delete this._overlayId;
}
this._overlayId = this.overlay.attach(this.overlayDemo, showSettings);
this.overlay.show(this._overlayId, showSettings);
}
public ngOnDestroy(): void {
if (this._overlayId) {
this.overlay.detach(this._overlayId);
delete this._overlayId;
}
}
}
ts<div class='overlay-sample' #mainContainer>
<div class='container'>
<div class="container__row">
<igx-switch [(ngModel)]='modalValue'>
Modal
</igx-switch>
<div class='section__row--wide'>
<div class="section__container--wide" #modalDemo>
<span (click)="onClickModal($event, 'auto')">
<igx-icon>notifications</igx-icon>
<p>Auto</p>
</span>
<span (click)="onClickModal($event, 'elastic')">
<igx-icon>notifications</igx-icon>
<p>Elastic</p>
</span>
<span (click)="onClickModal($event, 'connected')">
<igx-icon>notifications</igx-icon>
<p>Connect</p>
</span>
<span (click)="onClickModal($event, 'global')">
<igx-icon>notifications</igx-icon>
<p>Global</p>
</span>
</div>
</div>
</div>
</div>
<div class='container'>
<div class="overlay__element" #overlayDemo>
<igx-card elevated>
<igx-card-header>
<h3 class="igx-card-header__title">Overlay</h3>
</igx-card-header>
<igx-card-content>
<p class="igx-card-content__text">Click on the positioning settings to dynamically re-attach this
element.</p>
</igx-card-content>
</igx-card>
</div>
</div>
</div>
html.overlay-sample {
padding: 32px 0px 32px 32px;
overflow-y: scroll;
display: flex;
flex-direction: row;
height: 1600px;
margin-bottom: 500px;
}
.container__row > div, .section__container--wide > span, .section__position-element > div {
display: inline-block;
}
.section__row--wide, .container__row, .section__header {
width: 100%;
}
.section__row > span {
height: 48px;
}
.section__row--wide, .section__container--wide > span {
height: 80px;
max-width: 320px;
}
span:hover {
border: 1px solid #e41c77;
box-sizing: border-box;
cursor: pointer;
}
.section__container--wide {
align-content: flex-start;
display: flex;
}
.section__container--wide > span {
text-align: center;
vertical-align: middle;
line-height: 12px;
font-weight: 500;
width: 80px;
padding-top: 16px;
p {
margin-top: 0px;
}
}
.section__position-element, .section__position-header {
width: 144px;
text-align: center;
}
.section__separator {
width: 32px;
}
.container {
width: 50%;
display: flex;
flex-direction: column;
align-items: center;
}
.overlay__element {
width: 288px;
height: 144px;
}
.section__header {
max-height: 96px;
text-align: left;
font-weight: 700;
font-size: 16px;
}
.container__row {
height: 100%;
text-align: left;
margin-top: 16px;
}
.section__position-element, .section__row--wide {
box-shadow: 0 1px 3px 0 rgba(0, 0, 0, 0.2), 0 1px 1px 0 rgba(0, 0, 0, 0.14), 0 2px 1px -1px rgba(0, 0, 0, 0.12);
}
.igx-switch {
padding: 16px;
}
scss