UNPKG

react-iscroll

Version:

React component for wrapping iScroll library.

242 lines (183 loc) 6.96 kB
# React iScroll React component for wrapping iScroll library. ## ! Version 2.0 is only for React >= 15.5 - If you depends on older react < 15.5, use react-iscroll@1.x.y ## ! Breaking changes in version 1.0.0 - Property for passing iScroll instance is renamed from `iscroll` to `iScroll` and naming is unified across whole package - use it like `<ReactIScroll iScroll={iScroll}>` instead of ~~`<ReactIScroll iscroll={iScroll}>`~~ - Inner content wrapper is removed. https://github.com/schovi/react-iscroll/commit/ecd75bb75667a45d2e14a2eda0a1b7d56c9d54f4 - You can do it by yourself by wrapping childrens of ReactIScroll component into one more div with specific styling (check **Horizontal scroll example** there in README) - Main iScroll element has same behaviour and you can still change styling with `style` and `className` properties. ### What is iScroll? > iScroll is a high performance, small footprint, dependency free, multi-platform javascript scroller. > > -- <cite>[iScroll's homepage][1]</cite> [1]:http://iscrolljs.com/ Works on mobile and desktop, supports zooming, pagging, parallax scrolling, carousels and is incredibly small (4kb compress gzipped). ### Why React component? React components are a great way to compose your application. And they are a great way to handle third party libraries. You can wrap complex logic around a library and expose a simple API, which react users are used to. ## Install npm install react-iscroll ## Usage Simple example app. Allow scrolling on long list and catch event when scrolling starts. ```js var React = require('react'), ReactIScroll = require('react-iscroll'), iScroll = require('iscroll'); var ExampleApp = React.createClass({ getDefaultProps: function() { return ({ options: { mouseWheel: true, scrollbars: true } }) }, onScrollStart: function() { console.log("iScroll starts scrolling") }, render: function() { var i = 0, len = 1000, listOfLi = []; for(i; i < len; i++) { listOfLi.push(<li key={i}>Row {i+1}</li>) } return ( <div style={height: '100vh'}> <h1>Example of scrollable list</h1> <ReactIScroll iScroll={iScroll} options={this.props.options} onScrollStart={this.onScrollStart}> <ul> {listOfLi} </ul> </ReactIScroll> </div> ) } }) ``` ## FAQs ### onScroll event does not works You have to use **probe** version of iScroll and add `probeType` to `<ReactIScroll options={{probeType:2}}>`. Check [iScroll documentation](http://iscrolljs.com/) for more information. ## Configuration (API) Basic configuration. Just component with iScroll library. You can pick build which you want. ```js var iScroll = require('iscroll/build/iscroll-lite') <ReactIScroll iScroll={iScroll}> <div>Long content...</div> </ReactIScroll> ``` You can customize iScroll options with `options` property. Supports all from [iScroll manual](http://iscrolljs.com/) ```js var iScroll = require('iscroll/build/iscroll-probe') var options = { mouseWheel: true, scrollbars: true, freeScroll: true, invertWheelDirection: true, momentum: false, indicators: {...} } <ReactIScroll iScroll={iScroll} options={options}> <div>Long content...</div> </ReactIScroll> ``` Component supports all iScroll events. All of them passed iScroll instance to callback. ```js var iScroll = require('iscroll/build/iscroll-probe') <ReactIScroll iScroll={iScroll} onBeforeScrollStart={this.onBeforeScrollStart} onScrollCancel={this.onScrollCancel} onScrollStart={this.onScrollStart} onScroll={this.onScroll} onScrollEnd={this.onScrollEnd} onFlick={this.onFlick} onZoomStart={this.onZoomStart} onZoomEnd={this.onZoomEnd}> <div>Long content...</div> </ReactIScroll> ``` Plus there is one special event 'onRefresh' which is triggered when iScroll is refreshed. You can then get state of iScroll like `iscroll.hasVerticalScroll`, `iscroll.x` or `iscroll.scale`. **Watch out when updating state by value from iScroll. Always update state only when value changed to prevent circular updating (stack level too deep)** ```js var iScroll = require('iscroll/build/iscroll-lite') onRefresh: function(iScrollInstance) { var yScroll = iScrollInstance.y; console.log("vertical position:" + yScroll) if(this.state.y != yScroll) { this.setState({y: yScroll}) } }, render: function() { return ( <ReactIScroll iScroll={iScroll} onRefresh={this.onRefresh}> <div>Long content...</div> </ReactIScroll> ) } ``` ### function component.getIScroll() Return iScroll instance if initialized ### function component.withIScroll([waitForInit], callback) Run callback with iScroll instance as argument if instance is initialized. You can pass `true` as first argument for call callback after iScroll is initialized ```js onSomethingClick: function(ev) { ev.preventDefault() this.refs.iScroll.withIScroll(function(iScroll) { iScroll.scrollTo(0,0) }) }, render: function() { return( <div> <ReactIScroll ref="iScroll" iScroll={iScroll} onRefresh={this.onRefresh}> <div>Long content...</div> <a class="#" onClick={this.onSomethingClick}>Back to top</a> </ReactIScroll> </div> ) } ``` ## Horizontal scroll Common usecase of horizontal scrolling ```js var React = require('react'), ReactIScroll = require('react-iscroll'), iScroll = require('iscroll'); var HorizontalScroll = React.createClass({ render: function() { return ( <ReactIScroll iScroll={iScroll} options={{mouseWheel: true, scrollbars: true, scrollX: true}}> <div style={{width:'200%'}}> <ul> {listOfLi} </ul> </div> </ReactIScroll> ) } }) ``` ## Example There is example application. You can run it with this commands: - `npm install` - `npm run example` - `open http://localhost:8080/` ## To-Do - [ ] Add tests - [ ] Think about `shouldComponentUpdate`. Now it is always true because `this.props.children` are new object everytime and can't be compared via `==` or `===`. Maybe there is some way how to cheaply compare them. - [ ] Don't initialize IScroll when there is no child supplied. ### Done - [x] Make this README.md :) - [x] Trigger `onRefresh` event when iScroll is internally refreshed (e.g. on window resize) - [x] Do not `require('iscroll')` by itself. Instead pass it in props (there is few different versions of iScroll and you want to pick correct one for you) - [x] Publish to npm - [x] Convert source code into Babel ## License React iScroll is released under the [MIT License](http://www.opensource.org/licenses/MIT).