@mornya/scrolling-anchor-libs v1.17.0
Scrolling Anchor Libs
The Scrolling Anchor UI module.
This project has been created by Vessel CLI. For a simple and quick reference about it, click here.
About
스크롤링 앵커로 지정된 각각의 HTML 요소(클라이언트들)을 화면 스크롤 위치에 따라 페이지 상단 및 하단 영역에 attach 혹은 detach 하도록 구현해주는 UI 라이브러리.
Installation
해당 모듈을 사용할 프로젝트에서는 아래와 같이 설치한다.
$ npm install --save @mornya/scrolling-anchor-libs
or
$ yarn add @mornya/scrolling-anchor-libs
Usage
SPA 형태 혹은 SSR 환경의 앱에서 사용이 가능하며, React.js / Vue.js 등의 라이프사이클과는 별개로 동작하므로 컴포넌트 mount 시점에 라이브러리를 초기화 하고 unmount 시점에 라이브러리를 해제 해주면 된다.
Required default style
라이브러리 내 SCSS 파일(@mornya/scrolling-anchor-libs/dist/scrolling-anchor.scss
)이 반드시 적용되어야 하므로 해당 SCSS 파일을 import 해주거나, 참고하여 커스터마이징 후 적용해준다.
아래 스타일은 scrolling-anchor.scss
파일에 있는 내용으로, 기본적으로 적용되어야 제대로 동작한다.
$scrolling-anchor-zindex: 99;
.scrolling-anchor {
& > * {
display: inherit;
}
&[data-direction="top"] > .sa-attached,
&[data-direction="bottom"] > .sa-attached {
display: block;
position: fixed;
z-index: $scrolling-anchor-zindex;
}
}
Vue.js example
<template>
...
<div class="scrolling-anchor" data-direction="top"> <!-- "top" is default -->
<nav>Top Navigation</nav>
</div>
...
<div
class="scrolling-anchor"
data-attach-delay="200"
data-detach-delay="400"
>
<div>
Top direction bar<br/>
The styles will be applied after 200ms when attached<br/>
also detached styles will be applied after 400ms
</div>
</div>
...
<div class="scrolling-anchor" data-direction="bottom">
<nav>Bottom Navigation</nav>
</div>
...
</template>
<script>
import { ScrollingAnchor } from '@mornya/scrolling-anchor-libs';
export default {
data () {
return {
saNav: null,
};
},
updated () {
if (!this.saNav) {
this.saNav = new ScrollingAnchor();
}
},
beforeDestroy () {
this.saNav?.destroy();
},
};
</script>
<style lang="scss">
@import "~@mornya/scrolling-anchor-libs/dist/scrolling-anchor.scss";
</style>
React.js example
import React, { useRef, useEffect } from 'react';
import { ScrollingAnchor } from '@mornya/scrolling-anchor-libs';
import '@mornya/scrolling-anchor-libs/dist/scrolling-anchor.scss';
type Props = {};
const Navigation: React.VFC<Props> = (_props) => {
const saNav = useRef<ScrollingAnchor | null>(null);
useEffect(() => {
if (!saNav.current) {
saNav.current = new ScrollingAnchor('.scrolling-anchor', {
onAttach (eventTarget) {
console.log('Navigation attached:', eventTarget.el);
},
onDetach (eventTarget) {
console.log('Navigation detached:', eventTarget.el);
},
});
}
return () => {
// unmounted
saNav.current?.destroy();
};
}, []); // mounted
return (
<>
{/* ... */}
<div className="scrolling-anchor" data-direction="top"> <!-- "top" is default -->
<nav>Top Navigation</nav>
</div>
{/* ... */}
<div
className="scrolling-anchor"
data-attach-delay="200"
data-detach-delay="400"
>
<div>
Top direction bar<br/>
The styles will be applied after 200ms when attached<br/>
also detached styles will be applied after 400ms
</div>
</div>
{/* ... */}
<div className="scrolling-anchor" data-direction="bottom">
<nav>Bottom Navigation</nav>
</div>
</>
);
}
Attributes
data-attach-delay
해당 HTML 속성 값(숫자, > 0ms)이 지정된 ScrollingAnchor 영역은 상단 혹은 하단 화면영역에 attach 되려는 순간 .sa-child-will-attach
클래스가 추가되며, 지정한 값 만큼 시간이 지난 후 제거되면서 .sa-child-attached
클래스가 추가 된다.
동시에 실제 attach가 일어나는 .scrolling-anchor
클래스 하위 노드에는 .sa-will-attach
클래스가 추가되고 삭제되면서 .sa-attached
클래스가 추가된다.
트렌지션 등의 효과가 적용되는 시간만큼 해당 HTML 속성 값을 지정해주면 된다.
data-detach-delay
data-attach-delay
와는 반대로 detach 상황에 적용된다. .scrolling-anchor
클래스로 지정된 요소에는 .sa-child-will-detach
클래스가 추가되었다가 지정된 시간이 지난 후 삭제되며, 하위 노드에서는 .sa-will-detach
클래스가 추가되었다가 마찬가지로 삭제된다.
.sa-detached
같은 클래스는 생성되지 않으며,.sa-attached
클래스가 존재하면 attach 된 것이고 없으면 detach 된 것이다.
data-prepared
스크롤링 앵커가 스크롤 시작시 바로 부착될 경우, 화면상으로 튀어 보이는 것을 방지하기 위해 미리 부착된 것 처럼 보이게 처리 한다.
data-waypointed
스크롤링 앵커가 초기화되는 시점에 첫 스크롤링 앵커가 attach 될지 여부를 선언한다. 예를 들어 Y-offset이 0인 앵커의 경우 data-waypoint="true" 설정시 초기화 시점에 attach 되게 된다.
Options
스크롤링 앵커 라이브러리를 일반적으로 사용할 때는 별도의 옵션은 필요하지 않지만 화면이 동적으로 변화되는 경우에는 옵션을 통해 각 앵커 영역의 offset을 조정할 수 있다.
// 각 값들은 디폴트 설정 값임.
import { IScrollingAnchorOption } from './ScrollingAnchor';
const option: IScrollingAnchorOption = {
isFixedSize: true,
debouncedResize: 200,
offsetAttachTop: 0,
offsetAttachBottom: 0,
onAttach: (eventTarget: IScrollingAnchorEventTarget) => {},
onDetach: (eventTarget: IScrollingAnchorEventTarget) => {},
onScroll: (nextOffset: number, prevOffset: number, maxOffset: number) => {},
};
isFixedSize
상/하단 앵커가 attach될 때, 계산된 width
, height
값으로 앵커의 너비/높이를 고정할지의 여부. false
로 지정시에는 앵커들에 대해 미리 너비/높이가 지정되어 있어야 자연스럽게 보인다.
debouncedResize
resize
이벤트가 발생할 때 디바운스 시간(milliseconds)을 조정. 0
이하의 값은 디바운스 없이 처리 됨.
offsetAttachTop
화면 상단에 앵커가 attach되는 시작 offset을 지정. 예를 들어 offsetAttachTop: 100
으로 지정하게 되면 앵커는 화면 상단 100px 지점부터 attach가 시작된다. 화면이 동적으로 변화되는 경우 컴포넌트 update 라이프사이클에 퍼블릭 메소드인 setPosition
을 사용하여 동적으로 해당 값을 조정할 수 있다.
offsetAttachBottom
화면 하단에 앵커가 attach되는 시작 offset을 지정. offsetAttachTop
옵션과 마찬가지로 앵커가 화면 하단에 attach 되는 경우에 사용 가능하다.
onAttach
각 앵커가 상/하단에 attach 되는 시점에 발생하는 이벤트.
function onAttach (eventTarget: IScrollingAnchorEventTarget) {}
eventTarget 객체:
el
: attach 된 해당 앵커 HTML 요소 객체.height
: attach 된 해당 앵커의 높이.offsetTop
: 전체 attach 된 앵커 높이의 합.direction
: attach 된 앵커의 위치를 의미한다. class="scrolling-anchor"로 지정한 앵커 HTML 엘리먼트의data-direction
값이다 (top
orbottom
)lastIndex
: data-direction 속성 값이 동일한 앵커 중의 몇 번 째 엘리먼트인지를 의미한다 (0부터 시작). 예를 들어 상단에 attach되는 앵커가 2개 일 경우 HTML 엘리먼트 순서대로 index 번호가 매겨져서 index는 각각 0과 1일 된다. 단 하단의 경우에는 역순으로 index 번호가 매겨진다 (마지막 앵커 index가 0). attach 된 앵커가 없을 경우 -1.
onDetach
각 앵커가 attach 되는 시점을 벗어나 detach되어 원래 자리로 돌아가는 시점에 발생하는 이벤트.
function onDetach (eventTarget: IScrollingAnchorEventTarget) {}
eventTarget 객체:
el
: detach 된 해당 앵커 HTML 요소 객체.height
: detach 된 해당 앵커의 높이.offsetTop
: onAttach의 offsetTop과 동일.direction
: onAttach의 direction과 동일lastIndex
: onAttach의 index와 동일
onScroll
화면이 스크롤링 될 때 이벤트를 발생시키며 아래와 같은 파라미터 값을 제공하므로 사용자 콜백 함수를 만들어 처리 할 내용을 라이브러리에 제공해주면 된다.
function onScroll (nextOffset: number, prevOffset: number, maxOffset: number) {}
nextOffset
: 화면 스크롤시 이동한 페이지 offset 값prevOffset
: 마지막으로 이동했던 페이지 offset 값이며, nextOffset 값과 비교하여 스크롤 하여 이동한 거리 및 방향을 알 수 있다.maxOffset
: 화면 상에서 이동 가능한 최대 offset 값을 알 수 있다.
Methods
initialize()
new ScrollingAnchor()
로 선언된 객체를 다시 초기화 한다.
destroy
메소드가 실행되어 리스너와 스크롤링 앵커 객체를 모두 해제한 후 재설정 하므로 해당 메소드를 미리 실행할 필요 없다.function initialize (): void {}
destroy
사용한 자원 및 리스너 등을 모두 해제할 때 사용. 컴포넌트의 unmount 혹은 destroy 라이프사이클이 진행되는 시점에 호출해주면 된다.
function destroy (): void {}
getScrollOffsetX
/ getScrollOffsetY
현재 화면 스크롤 offset을 리턴해주는 static 메소드.
function getScrollOffsetX (): nubmer {}
function getScrollOffsetY (): nubmer {}
(예시)
console.log(
ScrollingAnchor.getScrollOffsetX(),
', ',
ScrollingAnchor.getScrollOffsetY(),
);
setPosition
동적으로 상/하단의 attach 시작 offset을 지정할 수 있다.
function setPosition (option: IScrollingAnchorPosition): void {}
option은 초기 ScrollingAnchor 생성시 사용한 옵션과 동일한 내용이지만 offsetAttachTop
, offsetAttachBottom
두 값만 사용되어진다. 이 값을 하나 이상 넘겨주면 된다 (넘기지 않아도 무관).
scrollTo
지정한 HTML엘리먼트의 위치가 상단에 오도록 화면을 스크롤 한다.
function scrollTo (scrollOption: IScrollToOption): Promise<IScrollToResult | null> {}
(예시)
scrollTo({
el: document.querySelector('#target-element'), // null 일 경우 오류 발생
marginTop: 10, // 해당 값만큼 아래 오프셋 위치로 오도록 지정 (default: 0)
delay: 0, // 실제 스크롤을 해당 값만큼 지연 (milliseconds)
isAnimate: true, // Smooth-scroll 여부
resolveAfter: 250, // 스크롤 후 최종위치 콜백이 리턴되기까지 지연될 시간 (milliseconds)
});
reset
DOM 랜더링 이후에 UI 변경이 있을 경우, 리스너 등 초기화가 불필요한 부분을 제외하고 각 스크롤링 앵커의 상태 등을 모두 초기화 한다. ⚠️ 주의: 실행시 각 스크롤 앵커 영역 위치 재조정으로 스크롤 앵커 영역이 화면에서 깜빡일 수 있다.
function reset (): void {}
Change Log
프로젝트 변경사항은 CHANGELOG.md 파일 참조.
License
프로젝트 라이센스는 LICENSE 파일 참조.
10 months ago
8 months ago
8 months ago
12 months ago
1 year ago
1 year ago
1 year ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
4 years ago
4 years ago
5 years ago
5 years ago
5 years ago
5 years ago