npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2024 – Pkg Stats / Ryan Hefner

@mornya/scrolling-anchor-libs

v1.17.0

Published

The project of Scrolling Anchor UI library.

Downloads

88

Readme

Scrolling Anchor Libs

npm node types downloads license

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 or bottom)
  • 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 파일 참조.