Skip to content

Commit 0fc7238

Browse files
author
poying
committed
check in
1 parent 6c37baf commit 0fc7238

20 files changed

+367
-0
lines changed

.babelrc.js

+5
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
module.exports = {
2+
presets: [
3+
"@babel/preset-env"
4+
]
5+
}

.editorconfig

+12
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
root = true
2+
3+
[*]
4+
charset = utf-8
5+
end_of_line = lf
6+
indent_size = 2
7+
indent_style = space
8+
insert_final_newline = true
9+
trim_trailing_whitespace = true
10+
11+
[*.md]
12+
trim_trailing_whitespace = false

.gitignore

+8
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
.DS_Store
2+
.vscode
3+
*.log
4+
node_modules
5+
/tmp
6+
/commonjs
7+
/module
8+
./cache

.idea/.gitignore

+5
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

.idea/get-window-scroll-top.iml

+12
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

.idea/misc.xml

+72
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

.idea/modules.xml

+8
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

.idea/vcs.xml

+6
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

.npmignore

+10
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
.idea
2+
.DS_Store
3+
.vscode
4+
*.log
5+
coverage
6+
node_modules
7+
.gitignore
8+
/.babelrc.js
9+
/src
10+
/.cache

.npmrc

+2
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
loglevel=info
2+
package-lock=false

README.md

+46
Original file line numberDiff line numberDiff line change
@@ -1,2 +1,48 @@
11
# get-window-scroll-top
2+
23
get window's scroll top cross browser
4+
5+
## Install
6+
7+
```
8+
npm install get-window-scroll-top
9+
```
10+
11+
12+
## Usage
13+
14+
```js
15+
import getWindowScrollTop from 'get-window-scroll-top'
16+
17+
const scrollTop = getWindowScrollTop()
18+
// value: 1000
19+
```
20+
21+
## Why use this module?
22+
23+
To get window's scroll top, you must consider the compatibility of multiple browsers.
24+
25+
Then you have to use `feature detect`, which checks the following scenes:
26+
27+
1. `window.pageYOffset`
28+
2. `document.body.scrollTop`
29+
3. `document.documentElement.scrollTop`
30+
31+
and handle the edge cases where some of them are invalid.
32+
33+
One of the common implements is as follows:
34+
35+
```js
36+
() => window.pageYOffset || document.body.scrollTop || document.documentElement.scrollTop;
37+
```
38+
39+
It seems that it's just one line to get window's scroll top. However, the outcome is obvious:
40+
41+
+ Missing edge cases when `window`/`document`/`document.body`/`document.documentElement` is missing, making the code above to throw.
42+
+ Unnecessary conditional checks **`DURING EVER CALL`**. You may find it unnoticeable, but please consider invoking the function in window's `scroll` event listener, it might a waste of cost.
43+
44+
To overcome the above details, we invent this module.
45+
46+
We use feature detect including edge cases, once the code find a way to access the `scrollTop` value properly, future call to the function will `JUST INVOKE THE EXTACT IMPLEMENT` without any unnecessary checks. In this way, we gain the best performance as possible.
47+
48+
The source code might seem a little longer, but after `treeshaking`/`uglify`, it's nothing to worry about, just several bytes increment.

package.json

+35
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
{
2+
"name": "get-window-scroll-top",
3+
"version": "1.0.0",
4+
"description": "get window's scroll top cross browser",
5+
"main": "commonjs/es5/index.js",
6+
"module": "module/es7/index.js",
7+
"jsnext:main": "module/es7/index.js",
8+
"scripts": {
9+
"build": "babel-node src/build/index.js",
10+
"prepublish": "npm run build"
11+
},
12+
"keywords": [
13+
"window",
14+
"scrolltop",
15+
"browser"
16+
],
17+
"devDependencies": {
18+
"@babel/cli": "^7.1.5",
19+
"@babel/core": "^7.1.6",
20+
"@babel/node": "^7.0.0",
21+
"@babel/preset-env": "^7.1.6",
22+
"rollup": "^2.6.1",
23+
"rollup-plugin-babel": "^4.0.3"
24+
},
25+
"repository": {
26+
"type": "git",
27+
"url": "git+https://github.com/xboy2012/get-window-scroll-top.git"
28+
},
29+
"author": "xboy2012",
30+
"license": "ISC",
31+
"bugs": {
32+
"url": "https://github.com/xboy2012/get-window-scroll-top/issues"
33+
},
34+
"homepage": "https://github.com/xboy2012/get-window-scroll-top#readme"
35+
}

src/build/build_es5_cjs.js

+20
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
import { rollup } from 'rollup'
2+
import babel from 'rollup-plugin-babel'
3+
import { ROOT_DIR } from '../core/configs'
4+
import { externals } from '../core/consts'
5+
6+
export default async () => {
7+
const bundle = await rollup({
8+
input: `${ROOT_DIR}/src/index.js`,
9+
external: externals,
10+
plugins: [
11+
babel(),
12+
],
13+
})
14+
await bundle.write({
15+
file: `${ROOT_DIR}/commonjs/es5/index.js`,
16+
format: 'cjs',
17+
sourcemap: true,
18+
strict: false,
19+
})
20+
}

src/build/build_es5_module.js

+20
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
import { rollup } from 'rollup'
2+
import babel from 'rollup-plugin-babel'
3+
import { ROOT_DIR } from '../core/configs'
4+
import { externals } from '../core/consts'
5+
6+
export default async () => {
7+
const bundle = await rollup({
8+
input: `${ROOT_DIR}/src/index.js`,
9+
external: externals,
10+
plugins: [
11+
babel(),
12+
],
13+
})
14+
await bundle.write({
15+
file: `${ROOT_DIR}/module/es5/index.js`,
16+
format: 'es',
17+
sourcemap: true,
18+
strict: false,
19+
})
20+
}

src/build/build_es7_cjs.js

+16
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
import { rollup } from 'rollup'
2+
import { ROOT_DIR } from '../core/configs'
3+
import { externals } from '../core/consts'
4+
5+
export default async () => {
6+
const bundle = await rollup({
7+
input: `${ROOT_DIR}/src/index.js`,
8+
external: externals,
9+
})
10+
await bundle.write({
11+
file: `${ROOT_DIR}/commonjs/es7/index.js`,
12+
format: 'cjs',
13+
sourcemap: true,
14+
strict: false,
15+
})
16+
}

src/build/build_es7_module.js

+16
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
import { rollup } from 'rollup'
2+
import { ROOT_DIR } from '../core/configs'
3+
import { externals } from '../core/consts'
4+
5+
export default async () => {
6+
const bundle = await rollup({
7+
input: `${ROOT_DIR}/src/index.js`,
8+
external: externals,
9+
})
10+
await bundle.write({
11+
file: `${ROOT_DIR}/module/es7/index.js`,
12+
format: 'es',
13+
sourcemap: true,
14+
strict: false,
15+
})
16+
}

src/build/index.js

+15
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
import buildES7CJS from './build_es7_cjs';
2+
import buildES5CJS from './build_es5_cjs';
3+
import buildES7Module from './build_es7_module';
4+
import buildES5Module from './build_es5_module';
5+
6+
const run = async () => {
7+
await Promise.all([
8+
buildES7CJS(),
9+
buildES5CJS(),
10+
buildES7Module(),
11+
buildES5Module()
12+
]);
13+
};
14+
15+
run();

src/core/configs.js

+3
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
import path from 'path'
2+
3+
export const ROOT_DIR = path.resolve(__dirname, '../..')

src/core/consts.js

+2
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
// 所有外部依赖的lib
2+
export const externals = []

src/index.js

+54
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,54 @@
1+
function getPageYOffset() {
2+
return window.pageYOffset;
3+
}
4+
5+
function getBodyScrollTop () {
6+
return document.body.scrollTop;
7+
}
8+
9+
function getDocumentElementScrollTop() {
10+
return document.documentElement.scrollTop;
11+
}
12+
13+
function getScrollTopAuto() {
14+
if (typeof window === 'undefined') {
15+
return 0;
16+
}
17+
const pageYOffset = getPageYOffset();
18+
if (pageYOffset) {
19+
// window.pageYOffset has a proper value,
20+
// thus future invoke use getPageYOffset();
21+
_getScrollTop = getPageYOffset;
22+
return pageYOffset;
23+
}
24+
if (typeof document === 'undefined') {
25+
return 0;
26+
}
27+
if (document.body) {
28+
const bodyScrollTop = getBodyScrollTop();
29+
if (bodyScrollTop) {
30+
// document.body.scrollTop has a proper value,
31+
// thus future invoke use getBodyScrollTop();
32+
_getScrollTop = getBodyScrollTop;
33+
return bodyScrollTop;
34+
}
35+
}
36+
if (document.documentElement) {
37+
const documentElementScrollTop = getDocumentElementScrollTop();
38+
if (documentElementScrollTop) {
39+
// document.documentElement.scrollTop has a proper value,
40+
// thus future invoke use getDocumentElementScrollTop();
41+
_getScrollTop = getDocumentElementScrollTop;
42+
return documentElementScrollTop;
43+
}
44+
}
45+
return 0;
46+
}
47+
48+
let _getScrollTop = getScrollTopAuto;
49+
50+
const getScrollTop = () => {
51+
return _getScrollTop();
52+
}
53+
54+
export default getScrollTop;

0 commit comments

Comments
 (0)