├── webpack.md ├── path.png ├── nodejs.md ├── gulp.md ├── README.md ├── package.json.md ├── css.md └── javascript.md /webpack.md: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /path.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zhaosaisai/snippets/HEAD/path.png -------------------------------------------------------------------------------- /nodejs.md: -------------------------------------------------------------------------------- 1 | # The common snippets of the nodejs :blush: 2 | 3 | #### path基本方法 4 | 5 | ```javascript 6 | const path = require('path'); 7 | 8 | //规范化字符串 9 | path.normalize('github.com//seeyou404/../index'); 10 | //=>'github.com/index' 11 | path.normalize('github.com//seeyou404/./index/..//route'); 12 | //=>'github.com/seeyou404/route' 13 | 14 | //连接路径--参数必须是字符串 15 | path.join('seeyou404', 'index', 'vevdor'); 16 | //=>'seeyou404/index/vevdor' 17 | path.join('seeyou404', 'index', '../', 'vevdor'); 18 | //=>'seeyou404/vevdor' 19 | 20 | //将相对路径转换成绝对路径 21 | path.resolve('seeyou404', 'index'); 22 | //=> 当前文件的绝对路径/seeyoy404/index 23 | path.resolve('seeyou404', 'index', '/js', '../'); 24 | //=> / 25 | path.resolve('seeyou404', 'index', './js', '../'); 26 | //=> 当前文件的绝对路径/seeyoy404/index 27 | 28 | //将两个绝对路径转换成相对路径--参数必须是绝对路径--相对路径会先转换成绝对路径 29 | path.relative('/seeyou404', '/seeyou404/index'); 30 | //=> index 31 | path.relative('/seeyou404', '/index'); 32 | //=> ../index 33 | 34 | // 获取文件所在的路径--获取最后一个路径分割符前的地址 35 | path.dirname('./index/index.js'); 36 | //=> ./index 37 | path.dirname('./index/js'); 38 | //=> ./index 39 | 40 | // 获取文件的后缀 41 | path.extname('./index/index.js'); 42 | //=> .js 43 | path.extname('./index/js'); 44 | //=> '' 45 | 46 | // 获取文件的名称 47 | path.basename('./index/index.js'); 48 | //=> index.js 49 | path.basename('./index/index.js', '.js'); 50 | //=> index 51 | path.basename('./index/index.js', 'dex.js'); 52 | //=> in 53 | path.basename('./index/js'); 54 | //=> 'js' 55 | ``` 56 | #### url基本方法 57 | ```javascript 58 | const url = require('url'); 59 | 60 | // 解析url 61 | url.parse('https://github.com/seeyou404/snippets?name=seeyou404&age=23#fe'); 62 | /* 63 | { 64 | protocol: 'https:', //协议 65 | slashes: true, // 66 | auth: null, //认证信息 67 | host: 'github.com', //域 68 | port: null, //端口号 69 | hostname: 'github.com', //主机 70 | hash: '#fe', //哈希值 71 | search: '?name=seeyou404&age=23', //查询字符串 72 | query: 'name=seeyou404&age=23', // 查询字符串 73 | pathname: '/seeyou404/snippets', // 路径 74 | path: '/seeyou404/snippets?name=seeyou404&age=23', //完整路径 75 | href: 'https://github.com/seeyou404/snippets?name=seeyou404&age=23#fe' //完整的url 76 | } 77 | */ 78 | 79 | // 格式化url--相当于url.parse的逆运算 80 | url.parse(urlObj); 81 | 82 | // url的路径转化 83 | url.resolve('seeyou404/index', 'js'); 84 | //=> 'seeyou404/js' 85 | url.resolve('seeyou404/index/', 'js'); 86 | //=> 'seeyou404/index/js' 87 | url.resolve('seeyou404/index', '/js'); 88 | //=> '/js' 89 | url.resolve('https://github.com/seeyou404/', '/js'); 90 | //=> 'https://github.com/js' 91 | url.resolve('https://github.com/seeyou404', 'js'); 92 | //=> 'https://github.com/js' 93 | url.resolve('https://github.com/seeyou404/', 'js'); 94 | //=> 'https://github.com/seeyou404/js' 95 | 96 | // 格式化url的查询字符串 97 | require('queryString').parse(url.parse('https://github.com/seeyou404/snippets?name=seeyou404&age=23#fe').query); 98 | //=> { name: 'seeyou404', age: '23' } 99 | ``` 100 | -------------------------------------------------------------------------------- /gulp.md: -------------------------------------------------------------------------------- 1 | # The common snippets of the gulp :blush: 2 | 3 | >先了解一下gulp.src(path)的path的几种书写方式: 4 | > 5 | > 6 | 7 | #### gulp-sass:编译sass 8 | 9 | ```javascript 10 | // 基本使用 11 | const gulp = require('gulp'); 12 | const sass = require('gulp-sass'); 13 | 14 | gulp.task('sass', () => { 15 | return gulp.src('./sass/**/*.scss') 16 | .pipe(sass().on('error', sass.logError)) 17 | .pipe(gulp.dest('./css')) 18 | }) 19 | 20 | 21 | gulp.task('default', ['sass']); 22 | ``` 23 | ```javascript 24 | //指明输出的格式 25 | const gulp = require('gulp'); 26 | const sass = require('gulp-sass'); 27 | 28 | gulp.task('sass', () => { 29 | return gulp.src('./sass/**/*.scss') 30 | //outputStyle指明输出格式:compressed, 31 | .pipe(sass({outputStyle:'compressed'}).on('error', sass.logError)) 32 | .pipe(gulp.dest('./css')) 33 | }) 34 | 35 | 36 | gulp.task('default', ['sass']); 37 | 38 | ``` 39 | 40 | #### gulp-sourcemaps:生成sourcemaps 41 | 42 | ```javascript 43 | const gulp = require('gulp'); 44 | const sass = require('gulp-sass'); 45 | const sourcemaps = require('gulp-sourcemaps'); 46 | 47 | gulp.task('sass', () => { 48 | return gulp.src('./sass/**/*.scss') 49 | //先调用init 50 | .pipe(sourcemaps.init()) 51 | .pipe(sass().on('error', sass.logError)) 52 | //调用write()-无参数,sourcemap在源文件中 53 | .pipe(sourcemaps.write()) 54 | .pipe(gulp.dest('./css')) 55 | }) 56 | 57 | 58 | gulp.task('default', ['sass']); 59 | 60 | ``` 61 | 62 | ```javascript 63 | const gulp = require('gulp'); 64 | const sass = require('gulp-sass'); 65 | const sourcemaps = require('gulp-sourcemaps'); 66 | 67 | gulp.task('sass', () => { 68 | return gulp.src('./sass/**/*.scss') 69 | .pipe(sourcemaps.init()) 70 | .pipe(sass().on('error', sass.logError)) 71 | //传递一个路径--存放sourcemaps文件 72 | .pipe(sourcemaps.write('./sassmaps')) 73 | .pipe(gulp.dest('./css')) 74 | }) 75 | 76 | 77 | gulp.task('default', ['sass']); 78 | 79 | ``` 80 | #### gulp-uglify:压缩js文件 81 | 82 | ```javascript 83 | // 基本使用 84 | const gulp = require('gulp'); 85 | const uglify = require('gulp-uglify'); 86 | 87 | gulp.task('uglify', () => { 88 | return gulp.src('./src/**/*.js') 89 | .pipe(uglify()) 90 | .pipe(gulp.dest('./js')) 91 | }) 92 | 93 | gulp.task('default', ['uglify']); 94 | 95 | ``` 96 | 97 | ```javascript 98 | //添加错误处理 99 | const gulp = require('gulp'); 100 | const uglify = require('gulp-uglify'); 101 | 102 | gulp.task('uglify', () => { 103 | return gulp.src('./src/**/*.js') 104 | .pipe(uglify()) 105 | .pipe(gulp.dest('./js')) 106 | .on('error', (err) => { 107 | console.error('the error happening', err.toString()); 108 | }) 109 | }) 110 | 111 | gulp.task('default', ['uglify']); 112 | 113 | ``` 114 | 115 | ```javascript 116 | //结合pump使用 117 | const gulp = require('gulp'); 118 | const uglify = require('gulp-uglify'); 119 | const pump = require('pump'); 120 | 121 | gulp.task('uglify', (cb) => { 122 | pump([ 123 | gulp.src('./src/**/*.js'), 124 | uglify(), 125 | gulp.dest('./js') 126 | ],cb) 127 | }) 128 | 129 | gulp.task('default', ['uglify']); 130 | 131 | ``` 132 | #### gulp-imagemin:压缩图片 133 | ```javascript 134 | const gulp = require('gulp'); 135 | const imagemin = require('gulp-imagemin'); 136 | 137 | gulp.task('imagemin', () => { 138 | return gulp.src('./images/*.*') 139 | .pipe(imagemin({ 140 | progressive:true 141 | })) 142 | .pipe(gulp.dest('./dist/images')) 143 | 144 | }) 145 | 146 | gulp.task('default', ['imagemin']); 147 | ``` 148 | #### gulp-babel:编译es6 149 | 150 | ```javascript 151 | //转换成普通的es5 有的特性不能转换 152 | const gulp = require('gulp'); 153 | const babel = require('gulp-babel'); 154 | 155 | gulp.task('babel', () => { 156 | return gulp.src('./src/**/*.js') 157 | .pipe(babel({ 158 | presets:['es2015'] 159 | })) 160 | .pipe(gulp.dest('./js')); 161 | }) 162 | 163 | gulp.task('default', ['babel']); 164 | ``` 165 | 166 | ```javascript 167 | //可以使用generator特性 168 | const gulp = require('gulp'); 169 | const babel = require('gulp-babel'); 170 | 171 | gulp.task('babel', () => { 172 | return gulp.src('./src/**/*.js') 173 | .pipe(babel({ 174 | plugins:['transform-runtime'] 175 | })) 176 | .pipe(gulp.dest('./js')); 177 | }) 178 | 179 | gulp.task('default', ['babel']); 180 | 181 | ``` 182 | 183 | #### 防止进程挂掉:gulp-plumber 184 | 185 | ```javascript 186 | const gulp = require('gulp'); 187 | const sass = require('gulp-sass'); 188 | const plumber = require('gulp-plumber'); 189 | 190 | gulp.task('sass', () => { 191 | return gulp.src('./sass/**/*.scss') 192 | .pipe(plumber()) 193 | .pipe(sass()) 194 | .pipe(gulp.dest('./dist/css')) 195 | }) 196 | 197 | gulp.task('default', ['sass']); 198 | ``` 199 | 200 | 201 | ```javascript 202 | const gulp = require('gulp'); 203 | const sass = require('gulp-sass'); 204 | const plumber = require('gulp-plumber'); 205 | 206 | gulp.task('sass', () => { 207 | return gulp.src('./sass/**/*.scss') 208 | .pipe(plumber({ 209 | errorHandler(err){ //自定义错误处理函数 210 | console.log(err.toString()); 211 | } 212 | })) 213 | .pipe(sass()) 214 | .pipe(gulp.dest('./dist/css')) 215 | }) 216 | 217 | gulp.task('default', ['sass']); 218 | ``` 219 | 220 | #### gulp结合browser-sync自动刷新 221 | 222 | ```javascript 223 | const gulp = require('gulp'); 224 | const babel = require('gulp-babel'); 225 | const sass = require('gulp-sass'); 226 | const plumber = require('gulp-plumber'); //gulp的容错处理,可防止出错的时候,进程挂掉 227 | const browserSync = require('browser-sync').create(); 228 | const reload = browserSync.reload; 229 | 230 | //sass任务 231 | gulp.task('sass', () => { 232 | return gulp.src('./sass/**/*.scss') 233 | .pipe(plumber()) 234 | .pipe(sass({outStyle:'compressed'}).on('error', sass.logError)) 235 | .pipe(gulp.dest('./dist/css')) 236 | .pipe(reload({stream:true})) 237 | }) 238 | //编译es6的任务 239 | gulp.task('es6', () => { 240 | return gulp.src('./js/**/*.js') 241 | .pipe(plumber({ 242 | errorHandler(err){ //自定义错误处理函数 243 | console.log('the error happening',err.toString()); 244 | } 245 | })) 246 | .pipe(babel({ 247 | presets:['es2015'] 248 | })) 249 | .pipe(gulp.dest('./dist/js')) 250 | .pipe(reload({stream:true})) 251 | }) 252 | //自动刷新任务 253 | gulp.task('server', ['sass', 'es6'], () => { 254 | browserSync.init({ 255 | server:'./', 256 | notify:false //去掉提示信息-移动端页面很有用 257 | }) 258 | 259 | //监听任务 260 | gulp.watch('./sass/**/*.scss', ['sass']); 261 | gulp.watch('./js/**/*.js', ['es6']); 262 | gulp.watch('./*.html').on('change', reload); 263 | }) 264 | //默认任务 265 | gulp.task('default', ['server']); 266 | 267 | 268 | ``` 269 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # snippets :blush: 2 | >The repository is used for collecting the common snippets of FE. Here are several different common code snippets. such as [css](https://github.com/seeyou404/snippets/blob/master/css.md)/[javascript](https://github.com/seeyou404/snippets/blob/master/javascript.md)/[nodejs](https://github.com/seeyou404/snippets/blob/master/nodejs.md)/[package.json](https://github.com/seeyou404/snippets/blob/master/package.json.md)/[gulp](https://github.com/seeyou404/snippets/blob/master/gulp.md) 3 | 4 | ### list of the snippets 5 | * [css](https://github.com/seeyou404/snippets/blob/master/css.md) 6 | * [样式重置](https://github.com/seeyou404/snippets/blob/master/css.md#样式重置) 7 | * [垂直居中](https://github.com/seeyou404/snippets/blob/master/css.md#垂直居中) 8 | * [消除表格默认的间隔](https://github.com/seeyou404/snippets/blob/master/css.md#消除表格默认的间隔) 9 | * [表格列宽自适应](https://github.com/seeyou404/snippets/blob/master/css.md#表格列宽自适应) 10 | * [盒子的阴影](https://github.com/seeyou404/snippets/blob/master/css.md#盒子的阴影) 11 | * [盒子内部阴影](https://github.com/seeyou404/snippets/blob/master/css.md#盒子内部阴影) 12 | * [清除浮动](https://github.com/seeyou404/snippets/blob/master/css.md#清除浮动) 13 | * [定义文本选择样式](https://github.com/seeyou404/snippets/blob/master/css.md#定义文本选择样式) 14 | * [长文本换行](https://github.com/seeyou404/snippets/blob/master/css.md#长文本换行) 15 | * [设置透明度](https://github.com/seeyou404/snippets/blob/master/css.md#设置透明度) 16 | * [css设置背景全屏](https://github.com/seeyou404/snippets/blob/master/css.md#css设置背景全屏) 17 | * [css3渐变模板](https://github.com/seeyou404/snippets/blob/master/css.md#css3渐变模板) 18 | * [@font-face模板](https://github.com/seeyou404/snippets/blob/master/css.md#@font-face模板) 19 | * [隔行变色](https://github.com/seeyou404/snippets/blob/master/css.md#隔行变色) 20 | * [首字突出显示](https://github.com/seeyou404/snippets/blob/master/css.md#首字突出显示) 21 | * [兼容设置最小高度](https://github.com/seeyou404/snippets/blob/master/css.md#兼容设置最小高度) 22 | * [不同的链接显示](https://github.com/seeyou404/snippets/blob/master/css.md#不同的链接显示) 23 | * [禁用移动端的选择高亮显示](https://github.com/seeyou404/snippets/blob/master/css.md#禁用移动端的选择高亮显示) 24 | * [javascript](https://github.com/seeyou404/snippets/blob/master/javascript.md) 25 | * [防反跳](https://github.com/seeyou404/snippets/blob/master/javascript.md#防反跳) 26 | * [拉平数组](https://github.com/seeyou404/snippets/blob/master/javascript.md#拉平数组) 27 | * [获取函数的返回值](https://github.com/seeyou404/snippets/blob/master/javascript.md#获取函数的返回值) 28 | * [动态加载javascript](https://github.com/seeyou404/snippets/blob/master/javascript.md#动态加载javascript) 29 | * [移动端页面初始化](https://github.com/seeyou404/snippets/blob/master/javascript.md#移动端页面初始化) 30 | * [获取随机数](https://github.com/seeyou404/snippets/blob/master/javascript.md#获取随机数) 31 | * [获取元素的计算之后的样式](https://github.com/seeyou404/snippets/blob/master/javascript.md#获取元素的计算之后的样式) 32 | * [判断对象的数据类型](https://github.com/seeyou404/snippets/blob/master/javascript.md#判断对象的数据类型) 33 | * [对象复制](https://github.com/seeyou404/snippets/blob/master/javascript.md#对象复制) 34 | * [判断网页是否在微信浏览器打开](https://github.com/seeyou404/snippets/blob/master/javascript.md#判断网页是否在微信浏览器打开) 35 | * [判断手机系统](https://github.com/seeyou404/snippets/blob/master/javascript.md#判断手机系统) 36 | * [获取查询字符串的值](https://github.com/seeyou404/snippets/blob/master/javascript.md#获取查询字符串的值) 37 | * [获取元素在页面中的位置](https://github.com/seeyou404/snippets/blob/master/javascript.md#获取元素在页面中的位置) 38 | * [js仿照md5](https://github.com/seeyou404/snippets/blob/master/javascript.md#js仿照md5) 39 | * [获取星期几](https://github.com/seeyou404/snippets/blob/master/javascript.md#获取星期几) 40 | * [requestAnimationFrame的兼容性处理](https://github.com/seeyou404/snippets/blob/master/javascript.md#requestAnimationFrame的兼容性处理) 41 | * [数组去重--6种方式](https://github.com/seeyou404/snippets/blob/master/javascript.md#数组去重) 42 | * [操作className](https://github.com/seeyou404/snippets/blob/master/javascript.md#操作className) 43 | * [hasClass](https://github.com/seeyou404/snippets/blob/master/javascript.md#hasClass) 44 | * [addClass](https://github.com/seeyou404/snippets/blob/master/javascript.md#addClass) 45 | * [removeClass](https://github.com/seeyou404/snippets/blob/master/javascript.md#removeClass) 46 | * [toggleClass](https://github.com/seeyou404/snippets/blob/master/javascript.md#toggleClass) 47 | * [判断网页运行在电脑还是手机](https://github.com/seeyou404/snippets/blob/master/javascript.md#判断网页运行在电脑还是手机) 48 | * [cookie的操作](https://github.com/seeyou404/snippets/blob/master/javascript.md#cookie的操作) 49 | * [函数节流](https://github.com/seeyou404/snippets/blob/master/javascript.md#函数节流) 50 | * [函数去抖](https://github.com/seeyou404/snippets/blob/master/javascript.md#函数去抖) 51 | * [nodejs](https://github.com/seeyou404/snippets/blob/master/nodejs.md) 52 | * [path基本方法](https://github.com/seeyou404/snippets/blob/master/nodejs.md#path基本方法) 53 | * [path.normalize--规范化字符串](https://github.com/seeyou404/snippets/blob/master/nodejs.md#path基本方法) 54 | * [path.join--连接路径](https://github.com/seeyou404/snippets/blob/master/nodejs.md#path基本方法) 55 | * [path.resolve--将相对路径转换成绝对路径](https://github.com/seeyou404/snippets/blob/master/nodejs.md#path基本方法) 56 | * [path.relative--转换成相对路径](https://github.com/seeyou404/snippets/blob/master/nodejs.md#path基本方法) 57 | * [path.dirname--获取文件所在路径](https://github.com/seeyou404/snippets/blob/master/nodejs.md#path基本方法) 58 | * [path.extname--获取文件后缀](https://github.com/seeyou404/snippets/blob/master/nodejs.md#path基本方法) 59 | * [path.basename--获取文件的名称](https://github.com/seeyou404/snippets/blob/master/nodejs.md#path基本方法) 60 | * [url基本方法](https://github.com/seeyou404/snippets/blob/master/nodejs.md#url基本方法) 61 | * [url.parse--解析url](https://github.com/seeyou404/snippets/blob/master/nodejs.md#url基本方法) 62 | * [url.format--格式化url](https://github.com/seeyou404/snippets/blob/master/nodejs.md#url基本方法) 63 | * [url.resolve--url的路径转化](https://github.com/seeyou404/snippets/blob/master/nodejs.md#url基本方法) 64 | * [querystring.parse--格式化url的查询字符串](https://github.com/seeyou404/snippets/blob/master/nodejs.md#url基本方法) 65 | * [package.json](https://github.com/seeyou404/snippets/blob/master/package.json.md) 66 | * [package.json](https://github.com/seeyou404/snippets/blob/master/package.json.md#package.json) 67 | * [版本号解释](https://github.com/seeyou404/snippets/blob/master/package.json.md#版本号解释) 68 | * [实例参考:npm的package.json文件](https://github.com/seeyou404/snippets/blob/master/package.json.md#实例参考:npm的package.json文件) 69 | * [gulp](https://github.com/seeyou404/snippets/blob/master/gulp.md) 70 | * [gulp-sass:编译sass](https://github.com/seeyou404/snippets/blob/master/gulp.md#gulp-sass:编译sass) 71 | * [gulp-sourcemaps:生成sourcemaps](https://github.com/seeyou404/snippets/blob/master/gulp.md#gulp-sourcemaps:生成sourcemaps) 72 | * [gulp-uglify:压缩js文件](https://github.com/seeyou404/snippets/blob/master/gulp.md#gulp-uglify:压缩js文件) 73 | * [gulp-imagemin:压缩图片](https://github.com/seeyou404/snippets/blob/master/gulp.md#gulp-imagemin:压缩图片) 74 | * [gulp-babel:编译es6](https://github.com/seeyou404/snippets/blob/master/gulp.md#gulp-babel:编译es6) 75 | * [防止进程挂掉:gulp-plumber](https://github.com/seeyou404/snippets/blob/master/gulp.md#防止进程挂掉:gulp-plumber) 76 | * [gulp结合browser-sync自动刷新](https://github.com/seeyou404/snippets/blob/master/gulp.md#gulp结合browser-sync自动刷新) 77 | * [webpack](https://github.com/seeyou404/snippets/blob/master/webpack.md) 78 | 79 | 80 | ### Explanation 81 | 1. The title of the snippet is necessary and it is perfect if brief 82 | 2. The comments of the code should be necessary and appropriate 83 | 3. You should indicate the source if the snippets are't original 84 | -------------------------------------------------------------------------------- /package.json.md: -------------------------------------------------------------------------------- 1 | # The fields of the package.json file :blush: 2 | 3 | #### package.json 4 | 5 | ```javascript 6 | { 7 | "name":包的名称,必须滴,毕竟每件东西都有名字。(没有是无法install的), 8 | "version":版本号,必须滴,没有是无法install的, 9 | "description":对你的包的简单描述,随便写,尽量符合你的包的特点, 10 | "keywords":关键字,便于search, 11 | "homepage":项目的主页,可选的,有最好写上,方便别人查看和装逼, 12 | "bugs":{ 13 | //是一个对象,下面的两种方式可全写或其一,就是用来别人反馈你的bug的 14 | "url":提交bug的url, 15 | "email":提交bug的email 16 | }, 17 | "license":许可证,告诉别人,他有什么权力,他有什么限制。如果你使用的是通用的许可证,直接写一个名字即可。用的是复杂的,可提供一个对象。如下: 18 | "licenses" : [ 19 | { "type" : "MyLicense", 20 | "url" : "http://github.com/owner/project/path/to/license" 21 | } 22 | ], 23 | "author":作者,你自己, 24 | "contributors":数组,谁给你的项目做了贡献,就把谁加进去,别让人家骂你, 25 | "person":{ 26 | //提供详细信息的,可提供下面三个字段 27 | "name":就是名字, 28 | "url":本尊对应的url, 29 | "email":本尊的email 30 | }, 31 | "files":数组,包含项目中的文件。受 .npmignore 文件的影响, 32 | "main":指定包的入口文件的名称,就是别人直接使用你的包的名称的时候,程序会从这个字段指定的文件开始运行。相对于根目录的文件路径, 33 | "bin":挺牛掰的一个玩意,可以是一个命令到文件名称的映射,也可以是一个字符串,那么这时候可执行文件的名称就是包的名称, 34 | "man":单一的文件名称或者是一个包含文件名称的数组,主要用于让man程序使用, 35 | "directories":{ 36 | "lib":我们的库文件夹放在什么地方, 37 | "bin":指定bin字段的位置,前提是你没有指定bin属性,否则无效, 38 | "man":当前模块man文档的位置, 39 | "doc":文档,一般是md文件 40 | }, 41 | "repository":{ 42 | //指定你的代码存放的位置 43 | "type":存放代码的工具,比如git,svn, 44 | "url":代码存放位置的url,以github为例,可能是下面这种形式:http://github.com/seeyou404/snippets.git 45 | }, 46 | "scripts":{ 47 | //这个字段比较高大上,主要用于简写npm命令的,也可以理解成,给你的命令定义一些别名,刻意直接通过npm run 命令名进行运行 48 | }, 49 | "config":{ 50 | //配置npm包中的一些命令,可以通过npm_package_config_名称来获取 51 | }, 52 | "dependencies":{ 53 | //用于定义项目开发时所依赖的模块,基本形式如下: 54 | "模块名称":一个表示范围的版本号或者是一个git url 55 | }, 56 | "peerDependencies":{ 57 | //如果一个模块只能够依赖另一个模块的摸个版本运行,那么,我们需要在这里指定,此时,当用户安装的时候,如果安装的时候不符合版本约定,那么就是提醒用户 58 | }, 59 | "bundledDependencies":数组,指定一组包名,会在发布的时候打包进去,也可以写成bundleDependencies, 60 | "optionalDependencies":指定可选的依赖,啥意思呢,就是一个依赖可用可不用,安装成功就使用,在安装失败的时候npm也能够继续初始化,这里的包会覆盖掉同名的dependencies里面同名的项, 61 | "engines":{ 62 | //指明一些程序的版本,比如node,npm 63 | "node":">=4.1.2 <6.0.0" 64 | }, 65 | "engineStrict":一个非常不建议使用的属性,知道有它就好了, 66 | "os":指定我们的包所能够运行的操作系统, 67 | "cpu":指定我们的包运行的cpu架构, 68 | "preferGlobal":如果你的包希望全局安装使用,把它设置为true,那么当用户局部安装的时候,会给出一个警告, 69 | "private":把包设置成私有的,npm不会发布它, 70 | "publishConfig":发布的时候使用的配置集合 71 | } 72 | ``` 73 | > [参考](http://mujiang.info/translation/npmjs/files/package.json.html) 74 | 75 | #### 版本号解释 76 | 77 | ```javascript 78 | { 79 | "version":必须和指定的version一致, 80 | ">version":必须比指定的version的版本大, 81 | ">=version":大于或等于指定的version, 82 | "=version1 <=version2, 88 | 89 | } 90 | ``` 91 | #### 实例参考:npm的package.json文件 92 | 93 | ```javascript 94 | { 95 | "version": "3.10.9", 96 | "name": "npm", 97 | "description": "a package manager for JavaScript", 98 | "keywords": [ 99 | "install", 100 | "modules", 101 | "package manager", 102 | "package.json" 103 | ], 104 | "preferGlobal": true, 105 | "config": { 106 | "publishtest": false 107 | }, 108 | "homepage": "https://docs.npmjs.com/", 109 | "author": "Isaac Z. Schlueter (http://blog.izs.me)", 110 | "repository": { 111 | "type": "git", 112 | "url": "https://github.com/npm/npm" 113 | }, 114 | "bugs": { 115 | "url": "https://github.com/npm/npm/issues" 116 | }, 117 | "directories": { 118 | "bin": "./bin", 119 | "doc": "./doc", 120 | "lib": "./lib", 121 | "man": "./man" 122 | }, 123 | "main": "./lib/npm.js", 124 | "bin": "./bin/npm-cli.js", 125 | "dependencies": { 126 | "abbrev": "~1.0.9", 127 | "ansicolors": "~0.3.2", 128 | "ansistyles": "~0.1.3", 129 | "aproba": "~1.0.4", 130 | "archy": "~1.0.0", 131 | "asap": "~2.0.5", 132 | "chownr": "~1.0.1", 133 | "cmd-shim": "~2.0.2", 134 | "columnify": "~1.5.4", 135 | "config-chain": "~1.1.11", 136 | "dezalgo": "~1.0.3", 137 | "editor": "~1.0.0", 138 | "fs-vacuum": "~1.2.9", 139 | "fs-write-stream-atomic": "~1.0.8", 140 | "fstream": "~1.0.10", 141 | "fstream-npm": "~1.2.0", 142 | "glob": "~7.1.0", 143 | "graceful-fs": "~4.1.9", 144 | "has-unicode": "~2.0.1", 145 | "hosted-git-info": "~2.1.5", 146 | "iferr": "~0.1.5", 147 | "inflight": "~1.0.5", 148 | "inherits": "~2.0.3", 149 | "ini": "~1.3.4", 150 | "init-package-json": "~1.9.4", 151 | "lockfile": "~1.0.2", 152 | "lodash._baseuniq": "~4.6.0", 153 | "lodash.clonedeep": "~4.5.0", 154 | "lodash.union": "~4.6.0", 155 | "lodash.uniq": "~4.5.0", 156 | "lodash.without": "~4.4.0", 157 | "mkdirp": "~0.5.1", 158 | "node-gyp": "~3.4.0", 159 | "nopt": "~3.0.6", 160 | "normalize-git-url": "~3.0.2", 161 | "normalize-package-data": "~2.3.5", 162 | "npm-cache-filename": "~1.0.2", 163 | "npm-install-checks": "~3.0.0", 164 | "npm-package-arg": "~4.2.0", 165 | "npm-registry-client": "~7.2.1", 166 | "npm-user-validate": "~0.1.5", 167 | "npmlog": "~4.0.0", 168 | "once": "~1.4.0", 169 | "opener": "~1.4.2", 170 | "osenv": "~0.1.3", 171 | "path-is-inside": "~1.0.2", 172 | "read": "~1.0.7", 173 | "read-cmd-shim": "~1.0.1", 174 | "read-installed": "~4.0.3", 175 | "read-package-json": "~2.0.4", 176 | "read-package-tree": "~5.1.5", 177 | "readable-stream": "~2.1.5", 178 | "realize-package-specifier": "~3.0.3", 179 | "request": "~2.75.0", 180 | "retry": "~0.10.0", 181 | "rimraf": "~2.5.4", 182 | "semver": "~5.3.0", 183 | "sha": "~2.0.1", 184 | "slide": "~1.1.6", 185 | "sorted-object": "~2.0.1", 186 | "strip-ansi": "~3.0.1", 187 | "tar": "~2.2.1", 188 | "text-table": "~0.2.0", 189 | "uid-number": "0.0.6", 190 | "umask": "~1.1.0", 191 | "unique-filename": "~1.1.0", 192 | "unpipe": "~1.0.0", 193 | "validate-npm-package-name": "~2.2.2", 194 | "which": "~1.2.11", 195 | "wrappy": "~1.0.2", 196 | "write-file-atomic": "~1.2.0" 197 | }, 198 | "bundleDependencies": [ 199 | "abbrev", 200 | "ansi-regex", 201 | "ansicolors", 202 | "ansistyles", 203 | "aproba", 204 | "archy", 205 | "asap", 206 | "chownr", 207 | "cmd-shim", 208 | "columnify", 209 | "config-chain", 210 | "debuglog", 211 | "dezalgo", 212 | "editor", 213 | "fs-vacuum", 214 | "fs-write-stream-atomic", 215 | "fstream", 216 | "fstream-npm", 217 | "glob", 218 | "graceful-fs", 219 | "has-unicode", 220 | "hosted-git-info", 221 | "iferr", 222 | "imurmurhash", 223 | "inflight", 224 | "inherits", 225 | "ini", 226 | "init-package-json", 227 | "lockfile", 228 | "lodash._baseindexof", 229 | "lodash._baseuniq", 230 | "lodash._bindcallback", 231 | "lodash._cacheindexof", 232 | "lodash._createcache", 233 | "lodash._getnative", 234 | "lodash.clonedeep", 235 | "lodash.restparam", 236 | "lodash.union", 237 | "lodash.uniq", 238 | "lodash.without", 239 | "mkdirp", 240 | "node-gyp", 241 | "nopt", 242 | "normalize-git-url", 243 | "normalize-package-data", 244 | "npm-cache-filename", 245 | "npm-install-checks", 246 | "npm-package-arg", 247 | "npm-registry-client", 248 | "npm-user-validate", 249 | "npmlog", 250 | "once", 251 | "opener", 252 | "osenv", 253 | "path-is-inside", 254 | "read", 255 | "read-cmd-shim", 256 | "read-installed", 257 | "read-package-json", 258 | "read-package-tree", 259 | "readable-stream", 260 | "readdir-scoped-modules", 261 | "realize-package-specifier", 262 | "request", 263 | "retry", 264 | "rimraf", 265 | "semver", 266 | "sha", 267 | "slide", 268 | "sorted-object", 269 | "strip-ansi", 270 | "tar", 271 | "text-table", 272 | "uid-number", 273 | "umask", 274 | "unique-filename", 275 | "unpipe", 276 | "validate-npm-package-license", 277 | "validate-npm-package-name", 278 | "which", 279 | "wrappy", 280 | "write-file-atomic" 281 | ], 282 | "devDependencies": { 283 | "deep-equal": "~1.0.1", 284 | "marked": "~0.3.6", 285 | "marked-man": "~0.1.5", 286 | "npm-registry-couchapp": "~2.6.12", 287 | "npm-registry-mock": "~1.0.1", 288 | "require-inject": "~1.4.0", 289 | "sprintf-js": "~1.0.3", 290 | "standard": "~6.0.8", 291 | "tacks": "~1.2.2", 292 | "tap": "~7.1.2" 293 | }, 294 | "scripts": { 295 | "dumpconf": "env | grep npm | sort | uniq", 296 | "prepublish": "node bin/npm-cli.js prune --prefix=. --no-global && rimraf test/*/*/node_modules && make doc-clean && make -j4 doc", 297 | "preversion": "bash scripts/update-authors.sh && git add AUTHORS && git commit -m \"update AUTHORS\" || true", 298 | "tap": "tap --reporter=classic --timeout 300", 299 | "tap-cover": "tap --coverage --reporter=classic --timeout 600", 300 | "test": "standard && npm run test-tap", 301 | "test-coverage": "npm run tap-cover -- \"test/tap/*.js\" \"test/network/*.js\"", 302 | "test-tap": "npm run tap -- \"test/tap/*.js\"", 303 | "test-node": "\"$NODE\" \"node_modules/.bin/tap\" --timeout 240 \"test/tap/*.js\" \"test/network/*.js\"" 304 | }, 305 | "license": "Artistic-2.0" 306 | } 307 | ``` 308 | >[From](https://github.com/npm/npm/blob/master/package.json) 309 | -------------------------------------------------------------------------------- /css.md: -------------------------------------------------------------------------------- 1 | # The common snippets of the css :blush: 2 | 3 | ## 布局篇 4 | 5 | #### 样式重置 6 | 7 | ```css 8 | html { 9 | font-family: sans-serif; 10 | /* 1 */ 11 | line-height: 1.15; 12 | /* 2 */ 13 | -ms-text-size-adjust: 100%; 14 | /* 3 */ 15 | -webkit-text-size-adjust: 100%; 16 | /* 3 */ 17 | } 18 | 19 | body { 20 | margin: 0; 21 | } 22 | 23 | article, 24 | aside, 25 | footer, 26 | header, 27 | nav, 28 | section { 29 | display: block; 30 | } 31 | 32 | h1 { 33 | font-size: 2em; 34 | margin: 0.67em 0; 35 | } 36 | 37 | figcaption, 38 | figure, 39 | main { 40 | /* 1 */ 41 | display: block; 42 | } 43 | 44 | figure { 45 | margin: 1em 40px; 46 | } 47 | 48 | hr { 49 | box-sizing: content-box; 50 | /* 1 */ 51 | height: 0; 52 | /* 1 */ 53 | overflow: visible; 54 | /* 2 */ 55 | } 56 | 57 | pre { 58 | font-family: monospace, monospace; 59 | /* 1 */ 60 | font-size: 1em; 61 | /* 2 */ 62 | } 63 | 64 | a { 65 | background-color: transparent; 66 | /* 1 */ 67 | -webkit-text-decoration-skip: objects; 68 | /* 2 */ 69 | } 70 | 71 | a:active, 72 | a:hover { 73 | outline-width: 0; 74 | } 75 | 76 | abbr[title] { 77 | border-bottom: none; 78 | /* 1 */ 79 | text-decoration: underline; 80 | /* 2 */ 81 | text-decoration: underline dotted; 82 | /* 2 */ 83 | } 84 | 85 | b, 86 | strong { 87 | font-weight: inherit; 88 | } 89 | 90 | b, 91 | strong { 92 | font-weight: bolder; 93 | } 94 | 95 | code, 96 | kbd, 97 | samp { 98 | font-family: monospace, monospace; 99 | /* 1 */ 100 | font-size: 1em; 101 | /* 2 */ 102 | } 103 | 104 | dfn { 105 | font-style: italic; 106 | } 107 | 108 | mark { 109 | background-color: #ff0; 110 | color: #000; 111 | } 112 | 113 | small { 114 | font-size: 80%; 115 | } 116 | 117 | sub, 118 | sup { 119 | font-size: 75%; 120 | line-height: 0; 121 | position: relative; 122 | vertical-align: baseline; 123 | } 124 | 125 | sub { 126 | bottom: -0.25em; 127 | } 128 | 129 | sup { 130 | top: -0.5em; 131 | } 132 | 133 | audio, 134 | video { 135 | display: inline-block; 136 | } 137 | 138 | audio:not([controls]) { 139 | display: none; 140 | height: 0; 141 | } 142 | 143 | img { 144 | border-style: none; 145 | } 146 | 147 | svg:not(:root) { 148 | overflow: hidden; 149 | } 150 | 151 | button, 152 | input, 153 | optgroup, 154 | select, 155 | textarea { 156 | font-family: sans-serif; 157 | /* 1 */ 158 | font-size: 100%; 159 | /* 1 */ 160 | line-height: 1.15; 161 | /* 1 */ 162 | margin: 0; 163 | /* 2 */ 164 | } 165 | 166 | button, 167 | input { 168 | /* 1 */ 169 | overflow: visible; 170 | } 171 | 172 | button, 173 | select { 174 | /* 1 */ 175 | text-transform: none; 176 | } 177 | 178 | button, 179 | html [type="button"], 180 | /* 1 */ 181 | 182 | [type="reset"], 183 | [type="submit"] { 184 | -webkit-appearance: button; 185 | /* 2 */ 186 | } 187 | 188 | button::-moz-focus-inner, 189 | [type="button"]::-moz-focus-inner, 190 | [type="reset"]::-moz-focus-inner, 191 | [type="submit"]::-moz-focus-inner { 192 | border-style: none; 193 | padding: 0; 194 | } 195 | 196 | button:-moz-focusring, 197 | [type="button"]:-moz-focusring, 198 | [type="reset"]:-moz-focusring, 199 | [type="submit"]:-moz-focusring { 200 | outline: 1px dotted ButtonText; 201 | } 202 | 203 | fieldset { 204 | border: 1px solid #c0c0c0; 205 | margin: 0 2px; 206 | padding: 0.35em 0.625em 0.75em; 207 | } 208 | 209 | legend { 210 | box-sizing: border-box; 211 | /* 1 */ 212 | color: inherit; 213 | /* 2 */ 214 | display: table; 215 | /* 1 */ 216 | max-width: 100%; 217 | /* 1 */ 218 | padding: 0; 219 | /* 3 */ 220 | white-space: normal; 221 | /* 1 */ 222 | } 223 | 224 | progress { 225 | display: inline-block; 226 | /* 1 */ 227 | vertical-align: baseline; 228 | /* 2 */ 229 | } 230 | 231 | textarea { 232 | overflow: auto; 233 | } 234 | 235 | [type="checkbox"], 236 | [type="radio"] { 237 | box-sizing: border-box; 238 | /* 1 */ 239 | padding: 0; 240 | /* 2 */ 241 | } 242 | 243 | [type="number"]::-webkit-inner-spin-button, 244 | [type="number"]::-webkit-outer-spin-button { 245 | height: auto; 246 | } 247 | 248 | [type="search"] { 249 | -webkit-appearance: textfield; 250 | /* 1 */ 251 | outline-offset: -2px; 252 | /* 2 */ 253 | } 254 | 255 | [type="search"]::-webkit-search-cancel-button, 256 | [type="search"]::-webkit-search-decoration { 257 | -webkit-appearance: none; 258 | } 259 | 260 | ::-webkit-file-upload-button { 261 | -webkit-appearance: button; 262 | /* 1 */ 263 | font: inherit; 264 | /* 2 */ 265 | } 266 | 267 | details, 268 | /* 1 */ 269 | menu { 270 | display: block; 271 | } 272 | 273 | summary { 274 | display: list-item; 275 | } 276 | 277 | canvas { 278 | display: inline-block; 279 | } 280 | 281 | template { 282 | display: none; 283 | } 284 | 285 | [hidden] { 286 | display: none; 287 | } 288 | ``` 289 | > 参考[normalize.css](https://github.com/necolas/normalize.css) 290 | 291 | #### 垂直居中 292 | 293 | ```css 294 | /*知道宽高*/ 295 | .verticalCenter{ 296 | width: 100px; 297 | height: 100px; 298 | position: absolute; 299 | top: 50%; 300 | left: 50%; 301 | margin-top: -50px; 302 | margin-left: -50px; 303 | } 304 | ``` 305 | 306 | ```css 307 | /*不知道宽高--使用transform*/ 308 | .verticalCenter{ 309 | position: absolute; 310 | top: 50%; 311 | left: 50%; 312 | transform: translate(-50%, -50%); 313 | } 314 | ``` 315 | 316 | ```css 317 | /*不知道宽高--使用flex布局*/ 318 | .verticalCenterContainer{ 319 | display: flex; 320 | justify-content: center; 321 | align-items: center; 322 | } 323 | ``` 324 | 325 | #### 消除表格默认的间隔 326 | ```css 327 | table{ 328 | border-collapse: collapse; 329 | } 330 | ``` 331 | 332 | #### 表格列宽自适应 333 | ```css 334 | table td{ 335 | white-space: nowrap; 336 | } 337 | ``` 338 | 339 | #### 盒子的阴影 340 | 341 | ```css 342 | /*一边阴影*/ 343 | .boxShadow { 344 | width: 100px; 345 | height: 100px; 346 | background-color: red; 347 | position: relative; 348 | } 349 | 350 | .boxShadow:after { 351 | content: ''; 352 | width: 5px; 353 | height: 90px; 354 | position: absolute; 355 | left: 0px; 356 | top: 10px; 357 | background-color: green; 358 | box-shadow: 0px 0px 5px 5px green; 359 | z-index: -1; 360 | } 361 | ``` 362 | 363 | ```css 364 | /*两边阴影*/ 365 | .boxShadow{ 366 | width: 100px; 367 | height: 100px; 368 | background-color: red; 369 | box-shadow: 5px 5px 5px green; 370 | } 371 | ``` 372 | 373 | 374 | ```css 375 | /*三边阴影*/ 376 | .boxShadow { 377 | width: 100px; 378 | height: 100px; 379 | background-color: red; 380 | box-shadow: 5px 5px 5px green; 381 | position: relative; 382 | } 383 | 384 | .boxShadow:after { 385 | content: ''; 386 | width: 5px; 387 | height: 90px; 388 | position: absolute; 389 | left: 0px; 390 | top: 10px; 391 | background-color: green; 392 | box-shadow: 0px 0px 5px 5px green; 393 | z-index: -1; 394 | } 395 | ``` 396 | 397 | 398 | ```css 399 | /*四边阴影*/ 400 | .boxShadow{ 401 | width: 100px; 402 | height: 100px; 403 | background-color: red; 404 | box-shadow: 0px 0px 5px green; 405 | } 406 | ``` 407 | #### 盒子内部阴影 408 | 409 | ```css 410 | .boxshadow{ 411 | box-shadow: inset 0 0 5px #ccc; 412 | } 413 | ``` 414 | #### 清除浮动 415 | 416 | ```css 417 | .clearfix{ 418 | width:100px; 419 | height:100px; 420 | overflow:hidden; 421 | } 422 | ``` 423 | 424 | ```css 425 | .clearfix:after{ 426 | content:""; 427 | display: block; 428 | width:0; 429 | height:0; 430 | line-height: 0; 431 | visibility: hidden; 432 | clear: both; 433 | } 434 | ``` 435 | 436 | ```css 437 | .clearfix:after{ 438 | content: ""; 439 | display: table; 440 | clear: both; 441 | } 442 | ``` 443 | 444 | #### 定义文本选择样式 445 | 446 | ```css 447 | ::-webkit-selection, ::-moz-selection, ::selection{ 448 | background-color:red; 449 | } 450 | ``` 451 | 452 | 453 | #### 长文本换行 454 | 455 | ```css 456 | .wrap{ 457 | white-space: pre; 458 | word-wrap: break-word; 459 | } 460 | ``` 461 | 462 | #### 设置透明度 463 | 464 | ```css 465 | .opacity{ 466 | opacity:0.5; 467 | filter:alpha(opacity=50); 468 | } 469 | ``` 470 | #### css设置背景全屏 471 | 472 | ```css 473 | html{ 474 | background: url() no-repeat center center fixed; 475 | background-size: cover; 476 | } 477 | ``` 478 | 479 | #### css3渐变模板 480 | 481 | ```css 482 | .gradient{ 483 | background:#bca321; 484 | background-image:linear-gradient(top, #000, #fff); 485 | background-image:-o-linear-gradient(top, #000, #fff); 486 | background-image:-moz-linear-gradient(top, #000, #fff); 487 | background-image:-ms-linear-gradient(top, #000, #fff); 488 | background-image:-webkit-linear-gradient(top, #000, #fff); 489 | background-image:-webkit-gradient(linear, left top, from(#000), to(#fff)); 490 | } 491 | ``` 492 | #### @font-face模板 493 | 494 | ```css 495 | @font-face{ 496 | font-family: 'custormFont'; 497 | src: url('webfont.eot'); /* IE9 Compat Modes */ 498 | src: url('webfont.eot?#iefix') format('embedded-opentype'), /* IE6-IE8 */ 499 | url('webfont.woff') format('woff'), /* Modern Browsers */ 500 | url('webfont.ttf') format('truetype'), /* Safari, Android, iOS */ 501 | url('webfont.svg#svgFontName') format('svg'); /* Legacy iOS */ 502 | } 503 | body{ 504 | font-family: 'custormFont', 'Arial', '微软雅黑'; 505 | } 506 | ``` 507 | 508 | #### 隔行变色 509 | 510 | ```css 511 | table tr:nth-child(even){ 512 | background-color:#ccc; 513 | } 514 | table tr:nth-child(odd){ 515 | background-color:#eee; 516 | } 517 | ``` 518 | 519 | #### 首字突出显示 520 | 521 | ```css 522 | div::first-letter{ 523 | float: left; 524 | color:#000; 525 | font-size:3em; 526 | margin:5px 0 0 5px; 527 | } 528 | ``` 529 | 530 | #### 兼容设置最小高度 531 | 532 | ```css 533 | .minHeight{ 534 | min-height:300px; 535 | height:auto !important; 536 | height:300px; 537 | } 538 | ``` 539 | #### 不同的链接显示 540 | ```css 541 | a[href^="http://"]{ 542 | padding-left:20px; 543 | background:url(); 544 | } 545 | a[href$=".pdf"]{ 546 | padding-left:20px; 547 | background:url(); 548 | } 549 | a[href$=".ppt"]{ 550 | padding-left:20px; 551 | background:url(); 552 | } 553 | ``` 554 | 555 | #### 禁用移动端的选择高亮显示 556 | 557 | ```css 558 | body{ 559 | user-select: none; 560 | -webkit-touch-callout: none; 561 | -webkit-user-select: none; 562 | -moz-user-select: none; 563 | -ms-user-select: none; 564 | } 565 | ``` 566 | -------------------------------------------------------------------------------- /javascript.md: -------------------------------------------------------------------------------- 1 | # The common snippets of the javascript :blush: 2 | 3 | 4 | #### 防反跳 / debounce 5 | 6 | ```js 7 | const debounce = (action, delay) => { 8 | let timer 9 | return function () { 10 | var context = this 11 | var args = arguments 12 | clearTimeout(timer) 13 | timer = setTimeout(() => { action.apply(context, args) }, delay) 14 | } 15 | } 16 | ``` 17 | 18 | #### 拉平数组 / flatten 19 | 20 | ```js 21 | const flatten = arr => { 22 | let list = [] 23 | const flattenFunc = arg => arg.forEach(item => Array.isArray(item) ? flattenFunc(item) : list.push(item)) 24 | flattenFunc(arr) 25 | return list 26 | } 27 | ``` 28 | 29 | #### 获取函数的返回值 / value 30 | 31 | ```js 32 | const value = func => { 33 | const valueFunc = arg => typeof arg === 'function' ? valueFunc(arg()) : arg 34 | return valueFunc(func) 35 | } 36 | ``` 37 | 38 | #### 动态加载javascript 39 | 40 | ```javascript 41 | function loadScript(url, callback){ 42 | var script = document.createElement('script'); 43 | script.type = 'text/javascript'; 44 | 45 | if(script.readyState){ //IE 46 | script.onreadystatechange = function(){ 47 | if(script.readyState === 'loaded' || script.readyState === 'complete'){ 48 | script.onreadystatechange = null; 49 | callback() 50 | } 51 | } 52 | }else{ //Others 53 | script.onload = callback.call(this); 54 | } 55 | 56 | script.url = url; 57 | document.getElementsByTagName('head')[0].appendChild(script); 58 | } 59 | ``` 60 | 61 | > From:[The best way to load external JavaScript](https://www.nczonline.net/blog/2009/07/28/the-best-way-to-load-external-javascript/) 62 | 63 | #### 移动端页面初始化 64 | 65 | 66 | ```javascript 67 | ;(function(factory){ 68 | window.factory = factory(window, document); 69 | 70 | return window.factory; 71 | })(function(win, doc){ 72 | var context = { 73 | init:function(scale){ 74 | var html = document.documentElement; 75 | var width = html.clientWidth > scale ? scale : html.clientWidth; 76 | var dpr = window.devicePixelRatio >= 1.5 ? 2 : window.devicePixelRatio; 77 | 78 | //设置html的dpr和fontsize 79 | html.setAttribute('data-dpr', dpr); 80 | html.style.fontSize = width * 100 / scale + 'px'; 81 | 82 | //设置body的宽度--可以解决微信内置浏览器里面的一个小bug 83 | this.setBody(); 84 | }, 85 | view:function(){ 86 | return { 87 | w:document.documentElement.clientWidth, 88 | h:document.documentElement.clientHeight 89 | } 90 | }, 91 | setBody:function(){ 92 | var body = document.body; 93 | body.style.width = this.view().w + 'px'; 94 | body.style.height = this.view().h + 'px'; 95 | } 96 | } 97 | }) 98 | ``` 99 | 100 | #### 获取随机数 101 | 102 | ```javascript 103 | function getRandom(min, max){ 104 | //左开右闭 105 | return Math.ceil(Math.random() * (max - min + 1) + min); 106 | } 107 | ``` 108 | 109 | ```javascript 110 | function getRandom(min, max){ 111 | //左闭右开 112 | return Math.floor(Math.random() * (max - min + 1) + min); 113 | } 114 | ``` 115 | 116 | ```javascript 117 | function getRandom(min, max){ 118 | //闭区间 119 | return Math.round(Math.random() * (max - min + 1) + min, 10); 120 | } 121 | ``` 122 | #### 获取元素的计算之后的样式 123 | 124 | ```javascript 125 | function getStyle(obj, attr){ 126 | return obj.currentStyle ? obj.currentStyle[attr] : getComputedStyle(obj, null)[attr]; 127 | } 128 | ``` 129 | #### 判断对象的数据类型 130 | 131 | ```javascript 132 | function type(obj){ 133 | return Object.prototype.toString.call(obj).match(/\s(\w+)/)[1].toLowerCase(); 134 | } 135 | ``` 136 | 137 | #### 对象复制 138 | 139 | ```javascript 140 | function copy(obj, deep){ 141 | var result = ''; 142 | if(type(obj) !== 'object') return; 143 | //利用JSON的方法进行深复制和浅复制 144 | return result = deep ? JSON.parse(JSON.stringify(obj)) : obj; 145 | } 146 | ``` 147 | #### 判断网页是否在微信浏览器打开 148 | 149 | ```javascript 150 | function isWeChat(){ 151 | return navigator.userAgent.toLowerCase().match(/MicroMessenger/i) === "micromessenger"; 152 | } 153 | ``` 154 | 155 | #### 判断手机系统 156 | 157 | ```javascript 158 | function isApple(){ 159 | return /ip(hone|ad|od)/i.test(navigator.userAgent.toLowerCase()); 160 | } 161 | ``` 162 | ```javascript 163 | function isAndroid(){ 164 | return /android/i.test(navigator.userAgent.toLowerCase()); 165 | } 166 | ``` 167 | #### 获取查询字符串的值 168 | 169 | ```javascript 170 | function getQuery(url){ 171 | var arr = []; 172 | var query = {}; 173 | 174 | url = url && url.charAt(0) === '?' ? url.slice(1) : url || location.search.slice(1); 175 | arr = url.split('&'); 176 | 177 | arr.forEach(function(v){ 178 | var a = v.split('='); 179 | query[a[0]] = encodeURIComponent(a[1]); 180 | }) 181 | 182 | return query; 183 | } 184 | ``` 185 | #### 获取元素在页面中的位置 186 | 187 | ```javascript 188 | function getPosition(ele){ 189 | var position = { 190 | left:ele.offsetLeft, 191 | top:ele.offsetTop 192 | }; 193 | var currentParent = ele.offsetParent; 194 | 195 | while (currentParent !== null) { 196 | position.left += currentParent.offsetLeft; 197 | position.top += currentParent.offsetTop; 198 | currentParent = currentParent.offsetParent; 199 | } 200 | 201 | return position; 202 | } 203 | ``` 204 | 205 | ```javascript 206 | function getPosition(ele){ 207 | return ele.getBoundingClientRect(); 208 | } 209 | ``` 210 | #### js仿照md5 211 | 212 | ```javascript 213 | function md5(){ 214 | var str = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/'; 215 | return str.split('').sort(function(v1,v2){ 216 | return Math.random() > 0.5; 217 | }).join('').slice(0, 32); 218 | } 219 | ``` 220 | #### 获取星期几 221 | 222 | ```javascript 223 | function getDay(){ 224 | var arr = ['星期天', '星期一', '星期二', '星期三', '星期四', '星期五', '星期六']; 225 | return arr[new Date().getDay()]; 226 | } 227 | ``` 228 | 229 | #### requestAnimationFrame的兼容性处理 230 | 231 | ```javascript 232 | ;(function(){ 233 | var lastTime = 0; 234 | var vendors = ['ms', 'moz', 'webkit', 'o']; 235 | 236 | for(var i = 0; i < vendors.length && !window.requestAnimationFrame; ++i){ 237 | window.requestAnimationFrame = window[vendors[i] + 'RequestAnimationFrame']; 238 | window.cancelAnimationFrame = window[vendors[i] + 'CancelAnimationFrame'] || window[vendors[x] + 'CancelRequestAnimationFrame']; 239 | } 240 | 241 | if (!window.requestAnimationFrame) window.requestAnimationFrame = function(callback, element) { 242 | var currTime = new Date().getTime(); 243 | var timeToCall = Math.max(0, 16 - (currTime - lastTime)); 244 | var id = window.setTimeout(function() { 245 | callback(currTime + timeToCall); 246 | }, timeToCall); 247 | lastTime = currTime + timeToCall; 248 | return id; 249 | }; 250 | if (!window.cancelAnimationFrame) window.cancelAnimationFrame = function(id) { 251 | clearTimeout(id); 252 | }; 253 | })() 254 | ``` 255 | #### 数组去重 256 | 257 | ```javascript 258 | Array.prototype.unique = function() { 259 | return Array.from(new Set(this)); 260 | } 261 | ``` 262 | 263 | ```javascript 264 | Array.prototype.unique = function() { 265 | var sortArr = this.sort(); 266 | return sortArr.filter(function(v,i,context){ 267 | return v != context[i+1]; 268 | }) 269 | } 270 | ``` 271 | 272 | ```javascript 273 | Array.prototype.unique = function() { 274 | var result = []; 275 | this.forEach(function(v){ 276 | if(result.indexOf(v) === -1){ 277 | result.push(v); 278 | } 279 | }) 280 | return result; 281 | } 282 | ``` 283 | 284 | ```javascript 285 | Array.prototype.unique = function() { 286 | var json = {}; 287 | var result = []; 288 | this.forEach(function(value){ 289 | var type = Object.prototype.toString.call(value).match(/\s(\w+)/)[1].toLowerCase(); 290 | if(!((type + '-'+value) in json)){ 291 | json[type + '-'+value] = true; 292 | result.push(value); 293 | } 294 | }) 295 | return result; 296 | } 297 | ``` 298 | 299 | ```javascript 300 | Array.prototype.unique = function() { 301 | var sortArr = this.sort(), 302 | i = 0; 303 | for(; i < sortArr.length; i++){ 304 | if(sortArr[i] === sortArr[i+1]){ 305 | sortArr.splice(i,1); 306 | i--; 307 | } 308 | } 309 | return sortArr; 310 | } 311 | ``` 312 | 313 | ```javascript 314 | Array.prototype.unique = function() { 315 | var sortArr = this.sort(), result = []; 316 | sortArr.reduce((v1,v2) => { 317 | if(v1 !== v2){ 318 | result.push(v1); 319 | } 320 | return v2; 321 | }) 322 | result.push(sortArr[sortArr.length - 1]); 323 | return result; 324 | } 325 | ``` 326 | 327 | #### 操作className 328 | 329 | ```javascript 330 | //操作className时候的辅助函数 331 | function toArray(argu){ 332 | var splitText = typeof argu === 'string' ? (argu.indexOf(' ') !== -1 ? ' ' : ',') : ' '; 333 | return Array.isArray(argu) ? argu : argu.split(splitText); 334 | } 335 | ``` 336 | >说明:以下四种方法的参数的形式可以为以下几种 337 | 338 | > * 数组:['classname1', 'classname2'] 339 | > * string 340 | > * 单字符串:'classname1' 341 | > * 空格分隔: 'classname1 classname2' 342 | > * 逗号分隔: 'classname1, classname2' 343 | 344 | ```javascript 345 | HTMLElement.prototype.hasClass = function (classname) { 346 | let selfClass = this.className.split(' '); 347 | classname = toArray(classname); 348 | if(this.classList){ 349 | for(let v of classname){ 350 | if(!this.classList.contains(v)){ 351 | return false; 352 | } 353 | } 354 | }else{ 355 | for(let v of classname){ 356 | if(selfClass.indexOf(v) === -1){ 357 | return false; 358 | } 359 | } 360 | } 361 | return true; 362 | } 363 | ``` 364 | 365 | ```javascript 366 | HTMLElement.prototype.addClass = function (classname) { 367 | return this.className = Array.from(new Set((toArray(classname).join(' ') + ' ' + this.className).split(' '))).join(' '); 368 | } 369 | ``` 370 | 371 | ```javascript 372 | HTMLElement.prototype.addClass = function (classname) { 373 | classname = toArray(classname); 374 | classname.forEach(function(v){ 375 | if(!this.hasClass(v)){ 376 | this.className += ' ' + v; 377 | } 378 | }.bind(this)) 379 | return this; 380 | } 381 | ``` 382 | 383 | ```javascript 384 | HTMLElement.prototype.removeClass = function (classname) { 385 | var selfClass = Array.from(new Set(this.className.split(' '))); 386 | classname = toArray(classname); 387 | classname.forEach(function(v){ 388 | if(selfClass.indexOf(v) !== -1){ 389 | selfClass.splice(selfClass.indexOf(v), 1); 390 | } 391 | }) 392 | this.className = selfClass.join(' '); 393 | return this; 394 | } 395 | ``` 396 | 397 | ```javascript 398 | HTMLElement.prototype.toggleClass = function (classname) { 399 | classname = toArray(classname); 400 | classname.forEach(function(v){ 401 | if(this.hasClass(v)){ 402 | this.removeClass(v) 403 | }else{ 404 | this.addClass(v); 405 | } 406 | }.bind(this)) 407 | } 408 | ``` 409 | 410 | #### 判断网页运行在电脑还是手机 411 | 412 | ```javascript 413 | //返回true是手机,否则是电脑 414 | const isMobile = () => { 415 | return ['android', 'iphone', 'symbianos', 'windows phone', 'ipad', 'ipod'].some((v) => { 416 | return navigator.userAgent.toLowerCase().indexOf(v) >= 0; 417 | }) 418 | } 419 | ``` 420 | 421 | #### 转意html 422 | 423 | ```javascript 424 | const escapeHTML = (html) => { 425 | let htmlMap = { 426 | '<': "<", 427 | '>':'>', 428 | '&':'&', 429 | '"':'"' 430 | }; 431 | 432 | return html.replace(/[<>"&]/g, (char) => htmlMap[char]); 433 | } 434 | ``` 435 | 436 | ### 操作cookie 437 | 438 | ```javascript 439 | /* 440 | 这里主要是一些操作cookie时候的一些工具方法 441 | */ 442 | class Utils { 443 | 444 | //第一个方法主要用于转义cookie里面的特殊字符 445 | encode(str){ 446 | return String(str).replace(/[,;"\s%\\]/g, (c) => encodeURIComponent(c)); 447 | } 448 | 449 | //第二个方法主要是用于对比编码的字符串进行解码的方法 450 | decode(str){ 451 | return decodeURIComponent(str); 452 | } 453 | 454 | //第三个方法主要是用于判断变量是不是纯粹的javascript对象的方法 455 | isPlainObject(obj){ 456 | return !!obj && Object.prototype.toString.call(obj) === '[object Object]'; 457 | } 458 | 459 | //第四个方法主要是进行回退的方法 460 | fallback(value, fallback){ 461 | return value == null ? fallback : value; 462 | } 463 | } 464 | export default new Utils(); 465 | ``` 466 | 467 | ```javascript 468 | import util from './utils.js'; 469 | /* 470 | 这个是操作cookie的主要的类 471 | */ 472 | class Cookie{ 473 | 474 | constructor(config){ 475 | this.defaultConfig = util.isPlainObject(config) ? config : {path: '/', domain:'', secure: false, expires: 1}; 476 | this.defaultTime = 60 * 60 *24 * 1000; 477 | } 478 | 479 | set(key, value, options){ 480 | //设置cookie的方法--主要有两种设置形式,key为字符串或者对象也可以是数组。当key是字符串的时候,value就是其对应的值,当key是对象的时候,则键表示cookie的名称 481 | //值表示cookie的值,value参数则是options设置对象,此时所有的cookie共用一个相同的选项设置对象 482 | //当cookie是数组的时候,设置形式如下 [{name:value, 'options':{这个对象就是对应的配置选项}},...] 483 | //name就是cookie的名称 value就是cookie的值 option就是这个cookie对应的选项对象 484 | 485 | //先判断是不是对象--是对象的话,就利用循环转换成不是对象的cookie的设置方式 486 | if(util.isPlainObject(key)){ 487 | //key是对象的情况--先判断一下key.option是否存在,存在则使用这个,不存在则使用options。注意这个时候的options是设置在value上的 488 | value = key.option ? key.option : value; 489 | Object.keys(key).forEach((v) => { 490 | v !== 'option' && this.set(v, key[v], value); 491 | }) 492 | }else if(Array.isArray(key)){ 493 | //key是数组的情况 494 | key.forEach((v) => { 495 | this.set(v, value); 496 | }) 497 | }else{ 498 | //key是字符串的情况 499 | //先对options进行类型的判断 500 | options = util.isPlainObject(options) ? options : {expires:1} 501 | //然后再获取到cookie中最重要的一项设置--expires 502 | let expires = options.expires || this.defaultConfig.expires || 1; 503 | let path = options.path || this.defaultConfig.path || '/'; 504 | let secure = options.secure || this.defaultConfig.secure || false; 505 | let domain = options.domain || this.defaultConfig.domain || ''; 506 | let expiresType = typeof expires; 507 | if(expiresType === 'string'){ 508 | expires = new Date(expires); 509 | }else if(expiresType === 'number'){ 510 | expires = new Date(Date.now() + this.defaultTime * expires); 511 | } 512 | //然后在对expires进行标准化 513 | ('toGMTString' in expires) && (expires = expires.toGMTString()); 514 | //设置cookie 515 | document.cookie = `${util.encode(key)}=${util.encode(value)}; path=${path}; domain=${domain}; expires=${expires}; secure=${secure}`; 516 | } 517 | 518 | } 519 | 520 | get(key){ 521 | //获取cookie的方法--如果不传递参数,则默认是获取所有的cookie,以json对象的形式返回-也可以传递一个参数--获取指定名称的cookie 522 | let cookies = document.cookie; 523 | let cookieResult = {}; 524 | let result = {}; 525 | 526 | //浏览器客户端没有cookie,则直接返回 527 | if(cookies == "") return; 528 | 529 | cookies.split('; ').forEach((value) => { 530 | value.replace(/^(.+)=(.+)$/g, (a, k, v) => { 531 | cookieResult[k] = v; 532 | }) 533 | }) 534 | //利用参数判断返回的情况 535 | //这里主要分三种情况--1、key是字符串,返回对应的cookie值--2、key是数组,返回一个包含这些名称的json对象--3、key不存在,直接返回所有的cookie,json对象格式 536 | if(key && Array.isArray(key)){ 537 | key.forEach((v) => { 538 | result[v] = cookieResult[v]; 539 | }) 540 | }else if(key && typeof key === 'string'){ 541 | result = cookieResult[key]; 542 | }else{ 543 | result = cookieResult; 544 | } 545 | return result; 546 | } 547 | 548 | clear(key){ 549 | //删除cookie的方法 550 | //分三种情况--1、key为undefined:删除所有的cookie 551 | // 2、key为数组:删除数组内指定的cookie 552 | // 3、key为字符串:删除指定名称的cookie 553 | let keyArr = Array.isArray(key) ? key : (key !== undefined ? [key] : Object.keys(this.get())); 554 | keyArr.forEach((v) => { 555 | this.set(v, '', {expires:-1}); 556 | }) 557 | } 558 | 559 | isabled(){ 560 | //判断cookie是否能用的方法 561 | return navigator.cookieEnabled; 562 | } 563 | } 564 | export default Cookie; 565 | ``` 566 | 567 | ### 函数节流 568 | 569 | ```javascript 570 | function throttle(func, wait, options){ 571 | //设置三个变量用于保存信息 572 | var context, //保存上下文 573 | args, //保存参数 574 | result; //保存函数的返回值 575 | 576 | //设置一个保存定时器的timer 577 | var timeout = null; 578 | 579 | //设置上一次函数执行的时间戳 580 | var previous = 0; 581 | 582 | //设置options的默认值 583 | if(!options){ 584 | options = {}; 585 | } 586 | 587 | //设置执行函数 588 | var later = function(){ 589 | //如果options.leading为false则每次出发回调后将previous置为0 590 | previous = options.leading === false ? 0 : Date.now(); 591 | 592 | timeout = null; 593 | 594 | result = func.apply(context, args); 595 | 596 | if(!timeout){ 597 | context = args = null; 598 | } 599 | } 600 | 601 | return function(){ 602 | 603 | //先保存这次函数的执行时间 604 | var now = Date.now(); 605 | 606 | //接着判断是否需要在刚刚开始的时候执行函数 607 | if(!previous && options.leading === false){ 608 | //进到这里面说明就不需要 609 | previous = now; 610 | } 611 | 612 | //接着在获取到时间的差值 613 | var remaining = wait - (now - previous); //主要比较的就是两次函数的执行时间和预先设定的时间的差值 614 | 615 | //保存这个函数的上下文和参数 616 | context = this; 617 | args = arguments; 618 | 619 | //开始根据判断条件进行函数的调用 620 | if(remaining < 0 || remaining > wait){ 621 | //进入到这里就表示函数可以进行调用了 622 | //remaining < 0 一开始就要执行 623 | //remaining > wait 正常的执行条件 624 | 625 | if(timeout){ 626 | //如果存在定时器,说明还有没有执行的定时器,清除掉 627 | clearTimeout(timeout); 628 | timeout = null; 629 | } 630 | 631 | //重置这次函数的执行时间,下次执行的时候需要判断 632 | previous = now; 633 | 634 | //执行函数 635 | result = func.apply(context, args); 636 | 637 | //重置变量,防止内存泄漏 638 | if(!timeout){ 639 | context = args = null; 640 | } 641 | }else if(!timeout && options.trailing !== false){ 642 | //最后一次需要出发的情况 643 | timeout = setTimeout(later,remaining); 644 | } 645 | 646 | //返回结果 647 | return result; 648 | } 649 | 650 | } 651 | ``` 652 | 653 | ### 函数去抖 654 | 655 | ```javascript 656 | function debounce(func, wait, immedicate){ 657 | /* 658 | 参数的基本解释: 659 | func: function 需要进行去抖的函数 660 | wait: 去抖时间 661 | immedicate: 设置去抖函数的触发时机,设置为true则事件发生的时候立即触发。否则在事件结束wait时间之后触发 662 | */ 663 | 664 | //设置几个需要用到的局部变量 665 | var context, //存储this 666 | args, //存储传递给去抖函数的参数 667 | timestamp, //存储每次函数触发的时间 668 | timeout, //存储对定时器的引用 669 | result; //存储原函数的返回值 670 | 671 | //主要就是这个函数,这个函数就是定时器调用的函数,我们需要在这个函数里面做一件十分重要的事就是判断函数触发的时机 672 | 673 | var later = function(){ 674 | 675 | //首先获取时间差 676 | var last = Date.now() - timestamp; 677 | 678 | //再看一下有没有达到函数调用的时间 679 | if(last < wait && last >= 0){ 680 | //重置函数调用 681 | timeout = setTimeout(later, wait - last); 682 | }else{ 683 | //说明可以调用函数了, 684 | //吧timeout设置为null,以便下次判断 685 | timeout = null; 686 | //但是需要先判断一下immedicate,因为如果这个为true,则我们不需要调用了 687 | if(!immedicate){ 688 | //说明不是立即调用 689 | result = func.apply(context, args); 690 | if(!timeout){ 691 | context = args = null; 692 | } 693 | } 694 | } 695 | } 696 | 697 | return function(){ 698 | //闭包的形式,方便传递参数 699 | context = this; 700 | args = arguments; 701 | 702 | //每次函数调用的时间 703 | timestamp = Date.now(); 704 | 705 | var callNow = immedicate && !timeout; //immedicate为true且函数不是第一次调用 706 | 707 | if(!timeout){ 708 | //如果能进到这里,表示的是这个函数不是第一次触发了 709 | //如果是第一次触发,我们需要调用定时器了 710 | timeout = setTimeout(later, wait); 711 | } 712 | if(callNow){ 713 | //如果是立即调用,就直接调用func函数 714 | result = func.apply(context, args); 715 | context = args = null; //释放资源 716 | } 717 | return result; 718 | } 719 | } 720 | ``` 721 | 722 | ### 求数组最大值 723 | 724 | ```javascript 725 | const arrayMax = arr => Math.max(...arr) 726 | ``` 727 | 728 | ### 求数组的最小值 729 | 730 | ```javascript 731 | const arrayMin = arr => Math.min(...arr) 732 | ``` 733 | 734 | ### chunk函数 735 | 736 | ```javascript 737 | const chunk = (arr, size) => Array.from({length: Math.ceil(arr.length / size)}, (v, i) => arr.slice(i * size, i * size + size)) 738 | ``` 739 | 740 | ### compact: 去除数组中值为falsey的元素 741 | 742 | ```javascript 743 | const compact = (arr) => arr.filter(Boolean) 744 | ``` 745 | 746 | ### 计算一个值在数组中出现的次数 747 | 748 | ```javascript 749 | const countOccurrences = (arr, value) => arr.reduce((a, v) => v === value ? a + 1 : a + 0, 0) 750 | ``` 751 | 752 | ### deepFlatten: 拉平数组 753 | 754 | ```javascript 755 | const deepFlatten = (arr) => [].concat(...arr.map(v => Array.isArray(v) ? deepFlatten(v) : v)) 756 | ``` 757 | 758 | ### difference: 返回数组的差值 759 | 760 | ```javascript 761 | const difference = (a, b) => { 762 | const s = new Set(b) 763 | return a.filter(x => !s.has(x)) 764 | } 765 | ``` 766 | 767 | ### 删除数组中的元素,直到回调函数返回true 768 | 769 | ```javascript 770 | const dropElements = (arr, func) => { 771 | while(arr.length > 0 && !func(arr[0])) { 772 | arr.shift() 773 | } 774 | return arr 775 | } 776 | ``` 777 | 778 | ### 返回索引是某个值的倍数的元素 779 | 780 | ```javascript 781 | const everyNth = (arr, nth) => arr.filter((e, i) => i % nth === 0) 782 | ``` 783 | 784 | ### 过滤出数组中没有重复值的元素 785 | 786 | ```javascript 787 | const filterNoneUnique = arr => arr.filter(i => arr.indexOf(i) === arr.lastIndexOf(i)) 788 | ``` 789 | 790 | ### 拉平数组 791 | 792 | ```javascript 793 | const flatten = arr => arr.reduce((a, v) => a.concat(v), []) 794 | ``` 795 | 796 | ### 拉平数组(深拉平) 797 | 798 | ```javascript 799 | const flattenDepth = (arr, depth = 1) => depth != 1 ? arr.reduce((a, v) => a.concat(Array.isArray(v) ? flattenDepth(v, depth - 1) : v), []) : arr.reduce((a, v) => a.concat(v), []) 800 | ``` 801 | 802 | ### 对数组按照特定条件分组 803 | 804 | ```javascript 805 | const groupBy = (arr, func) => arr.map(typeof func === 'function' ? func : val => val[func]) 806 | .reduce((acc, val, i) => { 807 | acc[val] = (acc[val] || []).concat(arr[i]) 808 | return acc 809 | }, {}) 810 | ``` 811 | 812 | ### 返回数组的第一个元素 813 | 814 | ```javascript 815 | const head = arr => arr[0] 816 | ``` 817 | 818 | ### 返回除数组最后一个元素之外的所有元素 819 | 820 | ```javascript 821 | const initial = arr => arr.slice(0, -1) 822 | ``` 823 | 824 | ### 初始化范围数组 825 | 826 | ```javascript 827 | const initializeArrayWithRange = (end, start = 0) => Array.from({length: end - start}).map((v, i) => i + start) 828 | ``` 829 | 830 | ### 初始化并以特定的值填充数组 831 | 832 | ```javascript 833 | const initializeArrayWithValues = (n, value = 0) => Array(n).fill(value) 834 | ``` 835 | 836 | ### 返回数组交集 837 | 838 | ```javascript 839 | const intersection = (a, b) => { 840 | const s = new Set(b) 841 | return a.filter(x => s.has(x)) 842 | } 843 | ``` 844 | 845 | ### 返回数组的最后一个元素 846 | 847 | ```javascript 848 | const last = arr => arr[arr.length - 1] 849 | ``` 850 | 851 | ### 将数组中的值映射到对象 852 | 853 | ```javascript 854 | const mapObject = (arr, fn) => { 855 | const keyValue = [arr, arr.map(fn)] 856 | return keyValue[0].reduce((acc, val, ind) => (acc[val] = keyValue[1][ind], acc), {}) 857 | } 858 | ``` 859 | 860 | ### 返回数组的第n个元素 861 | 862 | ```javascript 863 | const nthElement = (arr, n = 0) => (n > 0 ? arr.slice(n + 1) : arr.slice(n))[0] 864 | ``` 865 | 866 | ### 从对象中选取给定键的键值对 867 | 868 | ```javascript 869 | const pick = (obj, arr) => arr.reduce((acc, curr) => (curr in obj && (acc[curr] = obj[curr]), acc), {}) 870 | ``` 871 | 872 | ### 从数组中筛选指定的值 873 | 874 | ```javascript 875 | const pull = (arr, ...args) => { 876 | let pulled = arr.filter(v => !args.includes(v)) 877 | arr.length = 0 878 | pulled.forEach(v => arr.push(v)) 879 | } 880 | ``` 881 | 882 | ### 从数组中移除使给定函数返回false的元素 883 | 884 | ```javascript 885 | const remove = (arr, func) => Array.isArray(arr) ? arr.filter(func).reduce((acc, val) => { 886 | arr.splice(arr.indexOf(val), 1) 887 | return acc.concat(val) 888 | }, []) : [] 889 | ``` 890 | 891 | ### 返回数组中的随机的元素 892 | 893 | ```javascript 894 | const sample = arr => arr[Math.floor(Math.random() * arr.length)] 895 | ``` 896 | 897 | ### 打乱数组的顺序 898 | 899 | ```javascript 900 | const shuffle = arr => arr.sort(() => Math.random() - 0.5) 901 | ``` 902 | 903 | ### 返回两个数组的交集 904 | 905 | ```javascript 906 | const similiarity = (arr, values) => arr.filter(v => values.includes(v)) 907 | ``` 908 | 909 | ### 返回两个数组的差值 910 | 911 | ```javascript 912 | const symmetricDifference = (a, b) => { 913 | const sA = new Set(a) 914 | const sB = new Set(b) 915 | 916 | return [ 917 | ...a.filter(x => !sB.has(x)), 918 | ...b.filter(x => !sA.has(x)) 919 | ] 920 | } 921 | ``` 922 | 923 | ### 返回数组中第一个之外的元素 924 | 925 | ```javascript 926 | const tail = arr => arr.length > 1 ? arr.slice(1) : arr 927 | ``` 928 | 929 | ### 返回数组的前n个元素 930 | 931 | ```javascript 932 | const take = (arr, n = 1) => arr.slice(0, n) 933 | ``` 934 | 935 | ### 返回数组的并集 936 | 937 | ```javascript 938 | const union = (a, b) => Array.from(new Set([...a, ...b])) 939 | ``` 940 | 941 | ### 筛选数组剔除某些值的元素 942 | 943 | ```javascript 944 | const without = (arr, ...args) => arr.filter(v => !args.includes(v)) 945 | ``` 946 | 947 | ### zip函数 948 | 949 | ```javascript 950 | const zip = (...arrays) => { 951 | const maxLength = Math.max(...arrays.map(x => x.length)) 952 | return Array.from({length: maxLength}).map((_, i) => { 953 | return Array.from({length: arrays.length}, (_, k) => arrays[k][i]) 954 | }) 955 | } 956 | ``` 957 | 958 | ### 判断元素是否在可视区内 959 | 960 | ```javascript 961 | const elementIsVisibleInViewport = (el, partiallyVisible = false) => { 962 | const { top, left, bottom, right } = el.getBoundingClientRect() 963 | return partiallyVisible 964 | ? ((top > 0 && top < innerHeight) || (bottom > 0 && bottom < innerHeight) || (left > 0 && left < innerWidth) || (right > 0 && right < innerWidth)) 965 | : top >= 0 && left >= 0 && bottom <= innerHeight && right <= innerWidth 966 | } 967 | ``` 968 | 969 | ### 获取当前页的滚动位置 970 | 971 | ```javascript 972 | const getScrollPosition = (el = window) => ({ 973 | x: el.pageXOffset ? el.pageXOffset : el.scrollLeft, 974 | y: el.pageYOffset ? el.pageYOffset : el.scrollTop 975 | }) 976 | ``` 977 | 978 | ### 获取url的查询字符串 979 | 980 | ```javascript 981 | const getURLParameters = url => url.match(/([^?=&]+)(=[^&]*)/g).reduce((a, v) => (a[v.slice(0, v.indexOf('='))] = v.slice(v.indexOf('=') + 1), a), {}) 982 | ``` 983 | 984 | ### 页面重定向 985 | 986 | ```javascript 987 | const redirect = (url, asLink = true) => asLink ? window.location.href = url : window.location.replace(url) 988 | ``` 989 | 990 | ### 平滑的滚动到页面的顶部 991 | 992 | ```javascript 993 | const scrollTop = () => { 994 | const c = document.documentElement.scrollTop || document.body.scrollTop 995 | if(c > 0) { 996 | window.requestAnimationFrame(scrollTop) 997 | window.scrollTo(0, c - c / 8) 998 | } 999 | } 1000 | ``` 1001 | 1002 | ### 返回两个日期之间的差异(天) 1003 | 1004 | ```javascript 1005 | const getDaysDiffBetweenDates = (dateInitial, dateFinal) => (dateInitial - dateFinal) / (1000 * 3600 * 24) 1006 | ``` 1007 | 1008 | ### 将JSON对象转换为日期 1009 | 1010 | ```javascript 1011 | const JSONToDate = arr => { 1012 | const dt = new Date(parseInt(arr.toString().substr(6))) 1013 | return `${ dt.getDate() }/${ dt.getMonth() + 1 }/${ dt.getFullYear() }` 1014 | } 1015 | ``` 1016 | 1017 | ### 链式异步函数 1018 | 1019 | ```javascript 1020 | const chainAsync = fns => { 1021 | let curr = 0 1022 | let next = () => fns[curr++](next) 1023 | next() 1024 | } 1025 | ``` 1026 | 1027 | ### compose函数(从右向左执行函数) 1028 | 1029 | ```javascript 1030 | const compose = (...fns) => fns.reduce((f, g) => (...args) => f(g(...args))) 1031 | ``` 1032 | 1033 | ### pipe函数(从左向右执行函数) 1034 | 1035 | ```javascript 1036 | const pipe = (...fns) => fns.reduce((f, g) => (...args) => g(f(...args))) 1037 | ``` 1038 | 1039 | ### 将异步函数转换为一个promise 1040 | 1041 | ```javascript 1042 | const promisify = func => (...args) => new Promise((resolve, reject) => func(...args, (err, result) => err ? reject(err) : resolve(result))) 1043 | ``` 1044 | 1045 | ### 顺序执行一系列的promise 1046 | 1047 | ```javascript 1048 | const runPromiseSeries = ps => ps.reduce((p, next) => p.then(next), Promise.resolve()) 1049 | ``` 1050 | 1051 | ### 延迟异步函数的执行 1052 | 1053 | ```javascript 1054 | const sleep = ms => new Promise(resolve => setTimeout(resolve, ms)) 1055 | ``` 1056 | 1057 | ### 返回一组数据的平均值 1058 | 1059 | ```javascript 1060 | const arrayAverage = arr => arr.reduce((acc, val) => acc + val, 0) / arr.length 1061 | ``` 1062 | 1063 | ### 返回一组数据的总和 1064 | 1065 | ```javascript 1066 | const arraySum = arr => arr.reduce((acc, val) => acc + val, 0) 1067 | ``` 1068 | 1069 | ### Collatz算法(如果n是偶数, 则返回n/2。否则返回3n+1) 1070 | 1071 | ```javascript 1072 | const collatz = n => n % 2 === 0 ? n / 2 : 3 * n + 1 1073 | ``` 1074 | 1075 | ### 将数字转换为数组 1076 | 1077 | ```javascript 1078 | const digitize = n => [...String(n)].map(i => parseInt(i)) 1079 | ``` 1080 | 1081 | ### 计算两点之间的距离 1082 | 1083 | ```javascript 1084 | const distance = (x0, y0, x1, y1) => Math.hypot(x1 - x0, y1 - y0) 1085 | ``` 1086 | 1087 | ### 计算一个数字的阶乘 1088 | 1089 | ```javascript 1090 | const factorial = n => n < 0 ? (() => {throw new TypeError('Negative numbers are not allowed!')})() : n <= 1 ? n : n * factorial(n - 1) 1091 | ``` 1092 | 1093 | ### 包含斐波那契值的数组 1094 | 1095 | ```javascript 1096 | const fibonacci = n => Array(n).fill(0).reduce((acc, val, i) => acc.concat(i > 1 ? acc[i - 1] + acc[i - 2] : i), []) 1097 | ``` 1098 | 1099 | ### 计算两个数字的最大公约数(important) 1100 | 1101 | ```javascript 1102 | const gcd = (x, y) => !y ? x : gcd(y, x % y) 1103 | ``` 1104 | 1105 | ### 计算两个数字的最小公倍数(important) 1106 | 1107 | ```javascript 1108 | const lcm = (x,y) => { 1109 | const gcd = (x, y) => !y ? x : gcd(y, x % y); 1110 | return Math.abs(x*y)/(gcd(x,y)); 1111 | }; 1112 | ``` 1113 | 1114 | ### 返回数字数组的中间值 1115 | 1116 | ```javascript 1117 | const median = arr => { 1118 | const mid = Math.floor(arr.length / 2) 1119 | const nums = arr.sort((a, b) => a - b) 1120 | 1121 | return arr.length % 2 !== 0 ? nums[mid] ? (nums[mid - 1] + nums[mid]) / 2 1122 | } 1123 | ``` 1124 | 1125 | ### 返回指定范围内的随机整数 1126 | 1127 | ```javascript 1128 | const randomIntegerInRange = (min, max) => Math.floor(Math.random() * (max - min + 1)) + min 1129 | ``` 1130 | 1131 | ### 返回指定范围内的随机数 1132 | 1133 | ```javascript 1134 | const randomNumberInRange = (min, max) => Math.random() * (max - min) + min 1135 | ``` 1136 | 1137 | ### 将数字保留指定的位数 1138 | 1139 | ```javascript 1140 | const round = (n, decimals = 0) => Number(`${Math.round(`${n}e${decimals}`)}e-${decimals}`) 1141 | ``` 1142 | 1143 | ### 返回数字数组的标准差 1144 | 1145 | ```javascript 1146 | const standardDeviation = (arr, usePopulation = false) => { 1147 | onst mean = arr.reduce((acc, val) => acc + val, 0) / arr.length; 1148 | return Math.sqrt( 1149 | arr.reduce((acc, val) => acc.concat(Math.pow(val - mean, 2)), []) 1150 | .reduce((acc, val) => acc + val, 0) / (arr.length - (usePopulation ? 0 : 1)) 1151 | ) 1152 | } 1153 | ``` 1154 | 1155 | ### 从json对象中移除指定属性之外的任何特性 1156 | 1157 | ```javascript 1158 | const cleanObj = (obj, keysToKeep = [], childIndicator) => { 1159 | Object.keys(obj).forEach(key => { 1160 | if(key === childIndicator) { 1161 | cleanObj(obj[key], keysToKeep, childIndicator) 1162 | }else if(!keysToKeep.includes(key)) { 1163 | delete obj[key] 1164 | } 1165 | }) 1166 | } 1167 | ``` 1168 | 1169 | ### 从给定的键值对创建对象 1170 | 1171 | ```javascript 1172 | const objectFromPairs = arr => arr.reduce((a, v) => (a[v[0]] = v[1], a), {}) 1173 | ``` 1174 | 1175 | ### 将json对象转化为键值对数组 1176 | 1177 | ```javascript 1178 | const objectToPairs = obj => Object.keys(obj).map(k => [k, obj[k]]) 1179 | ``` 1180 | 1181 | ### 浅复制 1182 | 1183 | ```javascript 1184 | const shallowClone = obj => Object.assign({}, obj) 1185 | ``` 1186 | 1187 | ### 将字符串中每个单词的首字母大写 1188 | 1189 | ```javascript 1190 | const capitalizeEveryWord = str => str.replace(/\b[a-z]/g, char => char.toUpperCase()) 1191 | ``` 1192 | 1193 | ### 转义正则表达式中用到的字符 1194 | 1195 | ```javascript 1196 | const escapeRegExp = str => str.replace(/[.*+?^${}()|[\]\\]/g, '\\$&') 1197 | ``` 1198 | 1199 | ### 将驼峰法字符串转换为指定形式 1200 | 1201 | ```javascript 1202 | const fromCamelCase = (str, separator = '_') => str.replace(/([a-z\d])([A-Z])/g, '$1' + separator + '$2') 1203 | .replace(/([A-Z]+)([A-Z][a-z\d]+)/g, '$1' + separator + '$2').toLowerCase(); 1204 | ``` 1205 | 1206 | ### 为字符串加... 1207 | 1208 | ```javascript 1209 | const truncateString = (str, num) => 1210 | str.length > num ? str.slice(0, num > 3 ? num - 3 : num) + '...' : str; 1211 | ``` 1212 | 1213 | ### hexToRgb 1214 | 1215 | ```javascript 1216 | const hexToRgb = hex => { 1217 | const extendHex = shortHex => '#' + shortHex.slice(shortHex.startWith('#') ? 1 : 0).split('').map(x => x + x).join('') 1218 | const extendedHex = hex.slice(hex.startsWith('#') ? 1 : 0).length === 3 ? extendHex(hex) : hex 1219 | return `rgb(${parseInt(extendedHex.slice(1), 16) >> 16}, ${(parseInt(extendedHex.slice(1), 16) & 0x00ff00) >> 8}, ${parseInt(extendedHex.slice(1), 16) & 0x0000ff})` 1220 | } 1221 | ``` 1222 | 1223 | ### RGBToHex 1224 | 1225 | ```javascript 1226 | const RGBToHex = (r, g, b) => ((r << 16) + (g << 8) + b).toString(16).padStart(6, '0') 1227 | ``` 1228 | 1229 | ### 生成UUID 1230 | 1231 | ```javascript 1232 | const UUIDGenerator = () => 1233 | ([1e7] + -1e3 + -4e3 + -8e3 + -1e11).replace(/[018]/g, c => 1234 | (c ^ crypto.getRandomValues(new Uint8Array(1))[0] & 15 >> c / 4).toString(16) 1235 | ); 1236 | ``` 1237 | 1238 | ### 验证邮箱 1239 | 1240 | ```javascript 1241 | const validateEmail = str => 1242 | /^(([^<>()\[\]\\.,;:\s@"]+(\.[^<>()\[\]\\.,;:\s@"]+)*)|(".+"))@((\[[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\])|(([a-zA-Z\-0-9]+\.)+[a-zA-Z]{2,}))$/.test(str) 1243 | ``` --------------------------------------------------------------------------------