Skip to content
This repository has been archived by the owner on Jan 8, 2018. It is now read-only.

jindo.m.Scroll

Lee Yongsoo edited this page Mar 9, 2017 · 6 revisions

iScroll 거버넌스

상세한 가이드는 iScroll 공식 홈페이지를 참조하세요. 이 페이지에서는 초기 개발 방식에 대해 설명하고, 해당 컴포넌트 개발시 추가적으로 고려할 사항에 대해 설명하는 페이지입니다.

개요

IE8에서 iScroll을 사용하고자 한다면, iScroll 5.2.0+을 사용해야만 합니다.

  • ie8 폴리필 라이브러리를 iScroll 사용전에 삽입합니다. 아래 코드는 ie8 인 경우에는 ie8 폴리필을 삽입하는 코드입니다. 자세한 내용은 ie8 폴리필 프로젝트를 참조하기 바랍니다.
  • 또한, IE8에서는 Function.prototype.bind를 지원하지 않기 때문에, es5-shim을 iScroll 사용전에 삽입하거나, MDN의 Function.prototype.bind 폴리필 함수를 iScroll 사용전에 삽입하셔도 됩니다.
<!--[if IE 8]>
<script src="https://cdnjs.cloudflare.com/ajax/libs/es5-shim/4.5.7/es5-shim.min.js"></script>
<script
  src="//cdnjs.cloudflare.com/ajax/libs/ie8/0.4.0/ie8.js"
></script><![endif]-->
<script src="iscroll.js"></script>

설치

공식 홈페이지에서 다운로드 링크와 npm, bower를 제공하고 있습니다.

bower install iscroll
  • npm 설치
npm install iscroll

IScroll 버전

IScroll은 총 5가지 버전의 build 파일을 제공합니다. 따라서, 개발자는 서비스요구사항에 가장 적합한 버전을 적용하시기 바랍니다.

  • build/iscroll.js : 일반적인 스크롤 기능이 있는 기본 버전
  • build/iscroll-lite.js : 스냅기능, 스크롤바, 바운스휠, 키 바인딩 기능이 제거된 가장 성능이 좋은 버전
  • build/iscroll-probe.js : 스크롤이 발생할때, 좌표의 정보를 실시간으로 알아야 할 경우 필요한 버전. 이 버전에서는 scroll 이벤트를 별도로 지원한다.
  • build/iscroll-zoom.js : 기본 버전에 zoom 기능이 추가된 버전
  • build/iscroll-infinite.js : DOM recycle이 되어 무한개의 컨텐츠를 스크롤할 수 있는 버전

개발하기

1. 마크업 생성

스크롤을 적용할 마크업을 생성한다. iScroll은 다음과 같이 실제 화면에 보여지는 wrapper영역과 스크롤이 가능한 ul 영역으로 나뉩니다. 기본적인 마크업은 다음과 같습니다.

<div id="wrapper">
    <ul>
        <li>...</li>
        <li>...</li>
        ...
    </ul>
</div>

2. 인스턴스 생성

첫번째 파라미터로, wrapper의 CSS선택자나 엘리먼트를 지정하고, 두번째 파라미터로 iScroll의 옵션을 지정한다.

var scroll = new IScroll("#wrapper", {
	//...
}

고려할 사항

iScroll은 성능향상을 위해 useTransform, HWCompositing, useTransition을 제공합니다.

useTransform (기본값 : true)

이 옵션이 false일 경우, iScroll은 컨텐츠를 left/top과 같은 style로 좌표를 이동한다. style로 이동할경우, 매번 layout이벤트가 발생하게 되어 성능에 문제가 생길수 있다. 따라서, 이 옵션은 항상 기본값인 true로 지정한다.

HWCompositing (기본값 : true)

이 옵션이 true일 경우, iScroll은 하드웨어가속을 적용한다. 하드웨어 가속을 적용하면, 스크롤 영역이 별도의 레이어로 구성되어, 스크롤 성능이 굉장히 좋아진다. 하지만, 환경에 따라(브라우저 종류/버전, OS종류/버전...), 오히려 하드웨어 가속은 성능의 bottleneck을 초래하기 때문에, 신중하게 적용해야한다. egjs에서는 환경에 맞게 하드웨어 가속을 적용할 수 있는 가이드를 제공하고 있다. 이 가이드는 다음 함수를 호출함으로써 확인할 수 있다.

// true일 경우, 하드웨어 가속 적용, false일 경우, 하드웨어 가속미 적용
eg.isHWAccelerable();

useTransition (기본값 : true)

이 옵션이 true일 경우, iScroll은 requestAnimation 방식이 아닌, CSS Transition 방식으로 스크롤 애니메이션을 동작시킨다. CSS Transition으로 동작하면, 현대 브라우저에서는 애니메이션을 별도의 Thread로 구성한다. 별도의 Thread로 동작하는 경우에는 다음과 같은 장점을 얻을수 있다.

  • 애니메이션 도중 발생하는 작업(ajax,timer,..)이 있을 경우, 애니메이션이 끊기지 않는다.
  • Main Thread와 별개로 별도의 Thread로 동작하기 때문에, 애니메이션이 보다 부드럽게 동작한다.

하지만, 환경에 따라(브라우저 종류/버전, OS종류/버전...), 오히려 CSS Transition 방식이 정상적으로 동작하지 않는 경우가 있기 때문에, 신중하게 적용해야한다. egjs에서는 환경에 맞게 CSS Transition을 적용할 수 있는 가이드를 제공하고 있다. 이 가이드는 다음 함수를 호출함으로써 확인할 수 있다.

// true일 경우, 하드웨어 가속 적용, false일 경우, 하드웨어 가속미 적용
eg.isTransitional();

iscroll-probe 버전의 probeType3인 경우에는 useTransition 옵션이 false로 강제 지정된다.

egjs가 가이드 하는 IScroll 필수 옵션

// iScroll 적용 예
var scroll = new IScroll("#wrapper", {
	useTransform : true,
	HWCompositing : eg.isHWAccelerable(),
	useTransition : eg.isTransitional()
	// ...
}

JMC의 jindo.m.Scroll과의 차이

마크업

JMC에서는 iScroll과 마찬가지로, 마크업을 지정하고, 인스턴스를 생성하는 방식으로 개발을 합니다. 다만, JMC에서는 사용자 편의를 위해서, 마크업에서 필요한 필수 CSS를 자동으로 지정합니다.

따라서, JMC에서는 nHeight, nWidth와 같이 Scroll wrapper의 크기를 지정하는 옵션을 별도로 제공 하였습니다. http://jindo.nhncorp.com/docs/jindo-mobile/archive/latest/doc/internal/classes/jindo.m.Scroll.html#constructor 하지만, iScroll에서는 이와 관련된 css를 아래와 같이 선택적으로 개발자가 지정을 해주어야 합니다.

#wrapper {
	/* 필수 */
	position: relative;
	width: 300px;
	height: 300px;
	overflow: hidden;
	/* 윈도우에서 네이티브 이벤트 방지 속성 */
	-ms-touch-action: none;
	/* 롱탭 방지 속성들 */
	-webkit-touch-callout: none;
	-webkit-user-select: none;
	-moz-user-select: none;
	-ms-user-select: none;
	user-select: none;
	/* 단말기 회전시 텍스트 사이즈가 변경되는 것을 방지하는 속성 */
	-webkit-text-size-adjust: none;
	-moz-text-size-adjust: none;
	-ms-text-size-adjust: none;
	-o-text-size-adjust: none;
	text-size-adjust: none;
}
#scroller {
	position: absolute;
	/* 엘리먼트 선택시 하이라이트 막는 속성 */
	-webkit-tap-highlight-color: rgba(0,0,0,0);
	/* 하드웨어 가속을 시작시점 부터 적용하기 위한 속성들 */
	-webkit-transform: translateZ(0);
	-moz-transform: translateZ(0);
	-ms-transform: translateZ(0);
	-o-transform: translateZ(0);
	transform: translateZ(0);
}

이벤트

1. JMC의 jindo.m.Scroll과 iScroll은 외부 이벤트에 대한 처리가 다릅니다.

기본적으로 JMC는 특정 상황을 제외하고는 외부로 발생한 이벤트를 전달하지만, iScroll은 기본적(eventPassthrough:false, preventDefault:true가 기본값)으로 외부로 이벤트를 전달하지 않습니다. 즉, iScroll에서 발생한 native 이벤트(click, 브라우저 스크롤 동작, 등)가 동작하지 않도록 설정되어 있습니다.

  • JMC의 jindo.m.Scroll은 가로 스크롤이 가능한 경우(bUseHScroll=true), 세로로 스크롤 하면 시스템 스크롤이 동작합니다. 반대로, 세로 스크롤이 가능한 경우(bUseVScroll=true)에는 가로로 스크롤 하면 시스템 스크롤이 동작합니다. iScroll에서는 기본적으로 가로, 세로 스크롤과 상관없이 이벤트가 막힙니다
  • iScroll은 기본적으로 이벤트가 외부로 전달되지 않기 때문에, click, tap과 같은 옵션이 있어서 click과 tap 이벤트를 발생할수 있도록 지정할 수 있습니다. 다만, eventPassthrough 옵션이 true이거나, preventDefault가 false일 경우에는 JMC와 마찬가지로 외부 이벤트를 전달합니다. 따라서, 별도의 옵션을 지정할 필요가 없습니다.

2. JMC의 jindo.m.Scroll과 iScroll이 다루는 이벤트가 다릅니다.

  • JMC의 jindo.m.Scroll은 PC일 경우에는 Mouse 이벤트를, Mobile일 경우에는 Touch 이벤트를, Pointer이벤트가 가능한 경우에는 Pointer 이벤트를 사용합니다.
  • iScroll은 기본적으로 Mouse, Touch, Pointer 이벤트를 모두 사용합니다. 따라서, 불필요한 이벤트 처리가 될수 있습니다. 이 부분은 disableMouse, disableTouch, disablePointer 옵션을 통해 제어할 수 있습니다.

모바일 브라우저에 따라 click이나 tap 이벤트가 2번 발생하는 이슈가 있습니다. 해당 이슈는 touch 이벤트보다 mouse 이벤트가 먼저 발생하여 발생하는 이슈입니다. 따라서, 해당 이슈를 해결하기 위해서는 disableMouse 옵션을 true로 설정하여 불필요한 mouse 이벤트를 사용하지 않도록 설정 하시면 됩니다.

  • iScroll 5.2.0에서 부터는 Mouse, Touch, Pointer 이벤트 지원여부에 따라, disablePointer, disableTouch, disableMouse의 기본값이 다릅니다. pointer > touch > mouse 순으로 우선순위를 두어 기본값이 설정됩니다.
    • pointer와 touch 이벤트를 지원하는 경우에는 disablePointer:false, disableTouch:true, disableMouse:true로 기본값이 정해짐.
    • touch와 mouse 이벤트를 지원하는 경우에는 disablePointer:true, disableTouch:false, disableMouse:true로 기본값이 정해짐.
    • mouse 이벤트만 지원하는 경우에는 disablePointer:true, disableTouch:true, disableMouse:false로 기본값이 정해짐.

JMC의 Scroll 계열 컴포넌트들은 iscroll을 이용하여 어떻게 구현하나요?

JMC에서 기본적으로 제공하던 Scroll 계열 컴포넌트는 plugin구조의 jindo.m.DynamicPlugin, jindo.m.PullPlugin 이 있으며, jindo.m.Scroll 컴포넌트를 상속받은 jindo.m.IndexScroll 컴포넌트가 있다.

jindo.m.DynamicPlugin

DynamicPlugin은 대용량 컨텐츠를 스크롤하기 위해서, jindo.m.Scroll에서 사용하는 플러그인 모듈이다. 해당 기능은 iscroll-infinite 버전을 이용하면 쉽게 개발 할수 있다.

다만, iscroll-infinite는 동일한 높이를 가진 컨텐츠로 구성 해야하만 정상 동작한다. 그 외의 상황에서는 eg.InfiniteGrid를 이용하면 컨텐츠의 크기와 상관없이 해당 기능을 더욱 다양하게 구현할 수 있다.

jindo.m.PullPlugin

PullPlugin은 Pull down/up을 구현하기 위해서, jindo.m.Scroll에서 사용하는 플러그인 모듈이다. pull

해당 기능은 iScroll4.x (http://cubiq.org/dropbox/iscroll4/examples/pull-to-refresh/) 에서는 지원하였으며, iScroll 5.x 에서는 지원하지 않고 있다. 따라서, 현재 가이드하는 iScroll5 에서는 관련 기능을 구현 할수 없다. 하지만, eg.MovableCoord를 이용하면 위와 같은 기능들보다 화려한 인터럭션을 쉽게 개발 할수 있다.

상세한 내역은 egjs의 eg.MovableCoord를 참조하기 바란다.

jindo.m.IndexScroll

IndexScroll은 아이폰의 전화번호부와 같은 UI를 구현한 컴포넌트이다. 해당 컴포넌트와 같은 기능을 구현하기 위해서는 iscroll-probe 버전을 이용하면 쉽게 개발할 수 있다.

index

iscroll-probe 버전에서는 스크롤이 일어날 때 마다 "scroll" 이벤트를 사용할 수 있어서, 스크롤과 함께 동작하는 UI를 구현 할 수 있다.

상세한 내역은 다음을 참조하기 바란다.