├── examples
├── App.css
├── index.css
├── index.js
├── pages
│ ├── bscroll-pullDown
│ │ ├── main.css
│ │ └── index.js
│ ├── bscroll-pullup
│ │ ├── main.css
│ │ └── index.js
│ ├── bscroll-vertical
│ │ ├── main.css
│ │ └── index.js
│ ├── bscroll-multi
│ │ ├── main.css
│ │ └── index.js
│ └── bscroll-sample
│ │ ├── sample.css
│ │ └── index.js
└── App.js
├── public
├── favicon.ico
├── manifest.json
└── index.html
├── src
├── loading
│ ├── loading.gif
│ ├── loading.css
│ └── loading.js
├── scroll
│ ├── betterScroll.css
│ └── index.js
└── bubble
│ └── bubble.js
├── cli
└── gh-pages.js
├── config
├── jest
│ ├── fileTransform.js
│ └── cssTransform.js
├── polyfills.js
├── paths.js
├── env.js
├── webpackDevServer.config.js
├── webpack.config.lib.js
├── webpack.config.dev.js
└── webpack.config.prod.js
├── .gitignore
├── lib
├── react-scroll.css
└── react-bscroll.js
├── package.json
├── .eslintrc
├── README.md
└── scripts
├── dev.js
├── build-lib.js
└── build-demo.js
/examples/App.css:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/public/favicon.ico:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/soluteli/react-bscroll/HEAD/public/favicon.ico
--------------------------------------------------------------------------------
/examples/index.css:
--------------------------------------------------------------------------------
1 | body {
2 | margin: 0;
3 | padding: 0;
4 | font-family: sans-serif;
5 | }
6 |
--------------------------------------------------------------------------------
/src/loading/loading.gif:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/soluteli/react-bscroll/HEAD/src/loading/loading.gif
--------------------------------------------------------------------------------
/examples/index.js:
--------------------------------------------------------------------------------
1 | import React from 'react';
2 | import ReactDOM from 'react-dom';
3 | import './index.css';
4 | import App from './App';
5 |
6 | ReactDOM.render(, document.getElementById('root'));
7 |
--------------------------------------------------------------------------------
/src/loading/loading.css:
--------------------------------------------------------------------------------
1 | .loading-container {
2 | width: 100%;
3 | }
4 |
5 | .loading-container img {
6 | display: block;
7 | width: 20px;
8 | height: 20px;
9 | margin: 0 auto;
10 | }
--------------------------------------------------------------------------------
/cli/gh-pages.js:
--------------------------------------------------------------------------------
1 | var ghpages = require('gh-pages');
2 | // var path = require('path');
3 |
4 | ghpages.publish('dist', function(err) {
5 | if (err) {
6 | return console.log('gh pages error', err)
7 | }
8 | console.log('gh pages success')
9 |
10 | });
--------------------------------------------------------------------------------
/public/manifest.json:
--------------------------------------------------------------------------------
1 | {
2 | "short_name": "React App",
3 | "name": "Create React App Sample",
4 | "icons": [
5 | {
6 | "src": "favicon.ico",
7 | "sizes": "192x192",
8 | "type": "image/png"
9 | }
10 | ],
11 | "start_url": "./index.html",
12 | "display": "standalone",
13 | "theme_color": "#000000",
14 | "background_color": "#ffffff"
15 | }
16 |
--------------------------------------------------------------------------------
/config/jest/fileTransform.js:
--------------------------------------------------------------------------------
1 | 'use strict';
2 |
3 | const path = require('path');
4 |
5 | // This is a custom Jest transformer turning file imports into filenames.
6 | // http://facebook.github.io/jest/docs/tutorial-webpack.html
7 |
8 | module.exports = {
9 | process(src, filename) {
10 | return `module.exports = ${JSON.stringify(path.basename(filename))};`;
11 | },
12 | };
13 |
--------------------------------------------------------------------------------
/config/jest/cssTransform.js:
--------------------------------------------------------------------------------
1 | 'use strict';
2 |
3 | // This is a custom Jest transformer turning style imports into empty objects.
4 | // http://facebook.github.io/jest/docs/tutorial-webpack.html
5 |
6 | module.exports = {
7 | process() {
8 | return 'module.exports = {};';
9 | },
10 | getCacheKey() {
11 | // The output is always the same.
12 | return 'cssTransform';
13 | },
14 | };
15 |
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | # See https://help.github.com/ignore-files/ for more about ignoring files.
2 |
3 | # dependencies
4 | /node_modules
5 |
6 | # testing
7 | /coverage
8 |
9 | # production
10 | /build
11 |
12 | # misc
13 | .DS_Store
14 | .env.local
15 | .env.development.local
16 | .env.test.local
17 | .env.production.local
18 |
19 | npm-debug.log*
20 | yarn-debug.log*
21 | yarn-error.log*
22 |
23 | yarn.lock
24 |
--------------------------------------------------------------------------------
/src/loading/loading.js:
--------------------------------------------------------------------------------
1 | import React, { Component } from 'react'
2 |
3 | import './loading.css'
4 |
5 | const loadingImg = require('./loading.gif')
6 |
7 | class Loading extends Component {
8 |
9 | render () {
10 | return (
11 |
12 |

13 |
14 | )
15 | }
16 | }
17 |
18 | export default Loading
19 |
--------------------------------------------------------------------------------
/examples/pages/bscroll-pullDown/main.css:
--------------------------------------------------------------------------------
1 | .container {
2 | position: relative;
3 | height: 400px;
4 | background: rgba(0,0,0,.3);
5 | border: 1px solid #000;
6 | }
7 |
8 | .content {
9 | /*width: 200%;*/
10 | position: relative;
11 | margin: 0;
12 | }
13 |
14 | .content-item {
15 | height: 60px;
16 | line-height: 60px;
17 | font-size: 18px;
18 | padding-left: 20px;
19 | border-bottom: 1px solid #e5e5e5;
20 | }
21 |
--------------------------------------------------------------------------------
/examples/pages/bscroll-pullup/main.css:
--------------------------------------------------------------------------------
1 | .container {
2 | position: relative;
3 | height: 400px;
4 | background: rgba(0,0,0,.3);
5 | border: 1px solid #000;
6 | }
7 |
8 | .content {
9 | /*width: 200%;*/
10 | position: relative;
11 | margin: 0;
12 | }
13 |
14 | .content-item {
15 | height: 60px;
16 | line-height: 60px;
17 | font-size: 18px;
18 | padding-left: 20px;
19 | border-bottom: 1px solid #e5e5e5;
20 | }
21 |
--------------------------------------------------------------------------------
/examples/pages/bscroll-vertical/main.css:
--------------------------------------------------------------------------------
1 | .container {
2 | position: relative;
3 | height: 400px;
4 | background: rgba(0,0,0,.3);
5 | border: 1px solid #000;
6 | }
7 |
8 | .content {
9 | /*width: 200%;*/
10 | position: relative;
11 | margin: 0;
12 | }
13 |
14 | .content-item {
15 | height: 60px;
16 | line-height: 60px;
17 | font-size: 18px;
18 | padding-left: 20px;
19 | border-bottom: 1px solid #e5e5e5;
20 | }
21 |
--------------------------------------------------------------------------------
/examples/pages/bscroll-multi/main.css:
--------------------------------------------------------------------------------
1 | .container {
2 | position: relative;
3 | height: 300px;
4 | background: rgba(0,0,0,.3);
5 | border: 1px solid #000;
6 | margin-bottom: 10px;
7 | }
8 |
9 | .content {
10 | /*width: 200%;*/
11 | position: relative;
12 | margin: 0;
13 | }
14 |
15 | .content-item {
16 | height: 60px;
17 | line-height: 60px;
18 | font-size: 18px;
19 | padding-left: 20px;
20 | border-bottom: 1px solid #e5e5e5;
21 | }
22 |
--------------------------------------------------------------------------------
/lib/react-scroll.css:
--------------------------------------------------------------------------------
1 | .loading-container{width:100%}.loading-container img{display:block;width:20px;height:20px;margin:0 auto}.b-wrapper{position:absolute;left:0;top:0;right:0;bottom:0;overflow:hidden;background:#fff}.b-pullup-wrapper{height:60px;line-height:60px}.b-pulldown-wrapper,.b-pullup-wrapper{width:100%;display:-ms-flexbox;display:flex;-ms-flex-pack:center;justify-content:center;-ms-flex-align:center;align-items:center}.b-pulldown-wrapper{position:absolute;top:0;left:0;-webkit-transition:all;-o-transition:all;transition:all;pointer-events:none}.b-pulldown-wrapper .after-trigger{margin-top:10px}
--------------------------------------------------------------------------------
/config/polyfills.js:
--------------------------------------------------------------------------------
1 | 'use strict';
2 |
3 | if (typeof Promise === 'undefined') {
4 | // Rejection tracking prevents a common issue where React gets into an
5 | // inconsistent state due to an error, but it gets swallowed by a Promise,
6 | // and the user has no idea what causes React's erratic future behavior.
7 | require('promise/lib/rejection-tracking').enable();
8 | window.Promise = require('promise/lib/es6-extensions.js');
9 | }
10 |
11 | // fetch() polyfill for making API calls.
12 | require('whatwg-fetch');
13 |
14 | // Object.assign() is commonly used with React.
15 | // It will use the native implementation if it's present and isn't buggy.
16 | Object.assign = require('object-assign');
17 |
--------------------------------------------------------------------------------
/src/scroll/betterScroll.css:
--------------------------------------------------------------------------------
1 | .b-wrapper {
2 | position: absolute;
3 | left: 0;
4 | top: 0;
5 | right: 0;
6 | bottom: 0;
7 | overflow: hidden;
8 | background: #fff;
9 | }
10 |
11 | .b-pullup-wrapper {
12 | width: 100%;
13 | display: flex;
14 | justify-content: center;
15 | align-items: center;
16 | height: 60px;
17 | line-height: 60px;
18 | }
19 |
20 | .b-pulldown-wrapper {
21 | position: absolute;
22 | width: 100%;
23 | top: 0;
24 | left: 0;
25 | display: flex;
26 | justify-content: center;
27 | align-items: center;
28 | transition: all;
29 | pointer-events: none;
30 | }
31 |
32 | .b-pulldown-wrapper .after-trigger {
33 | margin-top: 10px
34 | }
35 |
--------------------------------------------------------------------------------
/examples/pages/bscroll-sample/sample.css:
--------------------------------------------------------------------------------
1 | .container {
2 | position: relative;
3 | height: 400px;
4 | background: rgba(0,0,0,.3);
5 | border: 1px solid #000;
6 | }
7 |
8 | .b-wrapper {
9 | position: absolute;
10 | left: 0;
11 | top: 0;
12 | right: 0;
13 | bottom: 0;
14 | overflow: hidden;
15 | background: #fff;
16 | }
17 |
18 | .b-content {
19 | /*width: 200%;*/
20 | position: relative;
21 | margin: 0;
22 | }
23 |
24 | .b-content-item {
25 | /*height: 60px;*/
26 | line-height: 60px;
27 | font-size: 18px;
28 | padding-left: 20px;
29 | border-bottom: 1px solid #e5e5e5;
30 | }
31 |
32 | .b-pullup-wrapper {
33 | width: 100%;
34 | display: flex;
35 | justify-content: center;
36 | align-items: center;
37 | height: 60px;
38 | line-height: 60px;
39 | }
40 |
--------------------------------------------------------------------------------
/examples/pages/bscroll-vertical/index.js:
--------------------------------------------------------------------------------
1 | import React, { Component } from 'react'
2 | import Scroll from 'src/scroll'
3 |
4 | import './main.css'
5 |
6 | const Data = []
7 | for (let i = 0; i < 10; i++) {
8 | Data.push(i)
9 | }
10 | class VerticalScrollPage extends Component {
11 | constructor (props, context) {
12 | super(props, context)
13 |
14 | this.state = {
15 | listData: Data,
16 | childData: 666
17 | }
18 | }
19 |
20 | componentDidMount () {
21 | for (let i = 10; i < 30; i++) {
22 | Data.push(i)
23 | }
24 | }
25 |
26 | clickItem (item) {
27 | console.log('clickEvent', item)
28 | }
29 |
30 | render () {
31 | return (
32 |
33 |
34 |
35 |
36 | {this.state.listData.map((item, index) =>
37 | (-
41 | item:{item}
42 |
),
43 | )}
44 |
45 |
46 |
47 |
48 | )
49 | }
50 | }
51 |
52 | export default VerticalScrollPage
53 |
--------------------------------------------------------------------------------
/public/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
11 |
12 |
13 |
22 | React App
23 |
24 |
25 |
28 |
29 |
39 |
40 |
41 |
42 |
--------------------------------------------------------------------------------
/examples/pages/bscroll-multi/index.js:
--------------------------------------------------------------------------------
1 | import React, { Component } from 'react'
2 | import Scroll from 'src/scroll'
3 |
4 | import './main.css'
5 |
6 | let Data = []
7 | for (let i = 0; i < 10; i++) {
8 | Data.push(i)
9 | }
10 | let Data2 = []
11 | for (let i = 10; i < 20; i++) {
12 | Data2.push(i)
13 | }
14 | class BscrollMultiPage extends Component {
15 | constructor (props, context) {
16 | super(props, context)
17 |
18 | this.state = {
19 | listData: Data,
20 | listData2: Data2,
21 | childData: 666
22 | }
23 | }
24 |
25 | componentDidMount () {
26 | for (let i = 10; i < 30; i++) {
27 | Data.push(i)
28 | }
29 | }
30 |
31 | clickItem (item) {
32 | console.log('clickEvent', item)
33 | }
34 |
35 | render () {
36 | return (
37 |
38 |
39 |
40 |
41 | {this.state.listData.map((item, index) =>
42 | (-
46 | item:{item}
47 |
),
48 | )}
49 |
50 |
51 |
52 |
53 |
54 |
55 | {this.state.listData2.map((item, index) =>
56 | (-
60 | item:{item}
61 |
),
62 | )}
63 |
64 |
65 |
66 |
67 | )
68 | }
69 | }
70 |
71 | export default BscrollMultiPage
72 |
--------------------------------------------------------------------------------
/examples/App.js:
--------------------------------------------------------------------------------
1 | import React, { Component } from 'react'
2 | import { HashRouter as Router, Route, Link } from 'react-router-dom'
3 |
4 | // import BScrollSamplePage from './pages/bscroll-sample'
5 | import BScrollVertivalPage from './pages/bscroll-vertical/index'
6 | import BScrollPullupPage from './pages/bscroll-pullup/index'
7 | import BScrollPullDownPage from './pages/bscroll-pullDown/index'
8 | import BscrollMultiPage from './pages/bscroll-multi/index'
9 |
10 | class Home extends Component {
11 | render () {
12 | return (
13 |
14 | -
15 |
Demos
16 | 如果在pc端预览,请在打开移动调试工具后,先刷新后查看效果
17 |
18 |
19 | {/*- 01: 使用原better-scroll
*/}
20 | - 01: react-scroll -- 简单案例
21 | - 02: react-scroll -- 上拉加载
22 | - 03: react-scroll -- 下拉加载
23 | - 04: react-scroll -- 多个scroll
24 |
25 | )
26 | }
27 | }
28 |
29 | class App extends Component {
30 | render () {
31 | return (
32 |
33 |
34 | {/* 导航 */}
35 |
36 |
37 | {/* better-scroll */}
38 | {/**/}
39 |
40 |
41 |
42 |
43 |
44 |
45 | )
46 | }
47 | }
48 |
49 | export default App;
50 |
--------------------------------------------------------------------------------
/examples/pages/bscroll-pullDown/index.js:
--------------------------------------------------------------------------------
1 | import React, { Component } from 'react'
2 | import Scroll from 'src/scroll'
3 |
4 | import './main.css'
5 |
6 | const Data = []
7 | let NEWTOPDATAINDEX1 = 1
8 | for (let i = 0; i < 10; i++) {
9 | Data.push(i)
10 | }
11 | class PullDownScrollPage extends Component {
12 | constructor (props, context) {
13 | super(props, context)
14 |
15 | this.state = {
16 | listData: Data,
17 | childData: 666
18 | }
19 | }
20 |
21 | componentWillMount () {
22 | NEWTOPDATAINDEX1 = 1
23 | }
24 |
25 | componentDidMount () {
26 | }
27 |
28 | componentWillUnmount () {
29 | clearTimeout(this.timer)
30 | }
31 |
32 | pullDownFreshAction = () => {
33 | return new Promise((resolve) => {
34 | this.timer = setTimeout(() => {
35 | if (Math.random() > 0) {
36 | // 如果有新数据
37 | let newPage = []
38 | for (let i = 0; i < 2; i++) {
39 | newPage.unshift(`我是顶部新数据${NEWTOPDATAINDEX1++}`)
40 | }
41 | this.setState({
42 | listData: [
43 | ...newPage,
44 | ...this.state.listData
45 | ],
46 | })
47 | }
48 | resolve()
49 | }, 1000)
50 | })
51 | }
52 |
53 | clickItem (item) {
54 | console.log('clickEvent', item)
55 | }
56 |
57 | render () {
58 | return (
59 |
60 |
61 |
65 |
66 | {this.state.listData.map((item, index) =>
67 | (-
71 | item:{item}
72 |
),
73 | )}
74 |
75 |
76 |
77 |
78 | )
79 | }
80 | }
81 |
82 | export default PullDownScrollPage
83 |
--------------------------------------------------------------------------------
/examples/pages/bscroll-pullup/index.js:
--------------------------------------------------------------------------------
1 | import React, { Component } from 'react'
2 | import Scroll from 'src/scroll'
3 |
4 | import './main.css'
5 |
6 | const Data = []
7 | let NEWDATAINDEX = 1
8 | for (let i = 0; i < 10; i++) {
9 | Data.push(i)
10 | }
11 | class PullupScrollPage extends Component {
12 | constructor (props, context) {
13 | super(props, context)
14 |
15 | this.state = {
16 | listData: Data,
17 | childData: 666
18 | }
19 | }
20 |
21 | componentWillMount () {
22 | NEWDATAINDEX = 1
23 | }
24 |
25 | componentDidMount () {
26 | }
27 |
28 | componentWillUnmount () {
29 | console.log('compomentWillUnmount')
30 | console.log(this.timer)
31 | clearTimeout(this.timer)
32 | }
33 |
34 | loadMoreData = () => {
35 | // 更新数据
36 | return new Promise( resolve => {
37 | console.log('pulling up and load data')
38 | this.timer = setTimeout(() => {
39 | if (Math.random() > 0) {
40 | // 如果有新数据
41 | let newPage = []
42 | for (let i = 0; i < 2; i++) {
43 | newPage.push(`我是新数据${NEWDATAINDEX++}`)
44 | }
45 | this.setState({
46 | listData: [
47 | ...this.state.listData,
48 | ...newPage
49 | ],
50 | })
51 | }
52 | resolve()
53 | }, 1000)
54 | })
55 | }
56 |
57 | clickItem (item) {
58 | console.log('clickEvent', item)
59 | }
60 |
61 | render () {
62 | return (
63 |
64 |
65 |
70 |
71 | {this.state.listData.map((item, index) =>
72 | (-
76 | item:{item}
77 |
),
78 | )}
79 |
80 |
81 |
82 |
83 | )
84 | }
85 | }
86 |
87 | export default PullupScrollPage
88 |
--------------------------------------------------------------------------------
/config/paths.js:
--------------------------------------------------------------------------------
1 | 'use strict';
2 |
3 | const path = require('path');
4 | const fs = require('fs');
5 | const url = require('url');
6 |
7 | // Make sure any symlinks in the project folder are resolved:
8 | // https://github.com/facebookincubator/create-react-app/issues/637
9 | const appDirectory = fs.realpathSync(process.cwd());
10 | const resolveApp = relativePath => path.resolve(appDirectory, relativePath);
11 |
12 | const envPublicUrl = process.env.PUBLIC_URL;
13 |
14 | function ensureSlash(path, needsSlash) {
15 | const hasSlash = path.endsWith('/');
16 | if (hasSlash && !needsSlash) {
17 | return path.substr(path, path.length - 1);
18 | } else if (!hasSlash && needsSlash) {
19 | return `${path}/`;
20 | } else {
21 | return path;
22 | }
23 | }
24 |
25 | const getPublicUrl = appPackageJson =>
26 | envPublicUrl || require(appPackageJson).homepage;
27 |
28 | // We use `PUBLIC_URL` environment variable or "homepage" field to infer
29 | // "public path" at which the app is served.
30 | // Webpack needs to know it to put the right