工具函数
收录一些常用的,获取约束源码获取到的一些优质的工具函数,当然工具函数早在 JavaScript ES5 之前的就已经有了,可以学习目前比较流行的库 Lodash 来使用和思考工具的函数的意义。
UA 先关
// Browser environment sniffing
export const inBrowser = typeof window !== 'undefined';
export const inWeex = typeof WXEnvironment !== 'undefined' && !!WXEnvironment.platform;
export const weexPlatform = inWeex && WXEnvironment.platform.toLowerCase();
export const UA = inBrowser && window.navigator.userAgent.toLowerCase();
export const isIE = UA && /msie|trident/.test(UA);
export const isIE9 = UA && UA.indexOf('msie 9.0') > 0;
export const isEdge = UA && UA.indexOf('edge/') > 0;
export const isAndroid = (UA && UA.indexOf('android') > 0) || weexPlatform === 'android';
export const isIOS = (UA && /iphone|ipad|ipod|ios/.test(UA)) || weexPlatform === 'ios';
export const isChrome = UA && /chrome\/\d+/.test(UA) && !isEdge;
export const isPhantomJS = UA && /phantomjs/.test(UA);
export const isFF = UA && UA.match(/firefox\/(\d+)/);
驼峰命名命名与非驼峰命名的相互转化
// 首字母小写
const lowerCase = (str = '') => {
const reg = /\b(\w)|\s(\w)/g;
return str.replace(reg, (m) => m.toLowerCase());
};
// 首字母大写
const upperCase = (str = '') => {
const reg = /\b(\w)|\s(\w)/g;
return str.replace(reg, (m) => m.toUpperCase());
};
// 中划线转驼峰
const toHump = (name = '') => {
return name.replace(/\-(\w)/g, (all, letter) => {
return letter.toUpperCase();
});
};
// 驼峰转换中划线
const toLine = (name = '') => {
return name.replace(/([A-Z])/g, '-$1').toLowerCase();
};
防抖和节流
防抖
函数防抖:将几次操作 合并 为一此操作进行。原理是维护一个计时器,规定在delay时间后触发函数,但是在delay时间内再次触发的话,就会取消之前的计时器而重新设置。这样一来,只有最后一次操作能被触发。
// 防抖
function debounce(fn, wait) {
var timeout = null;
return function() {
if(timeout !== null) clearTimeout(timeout);
timeout = setTimeout(fn, wait);
}
}
// 处理函数
function handle() {
console.log(Math.random());
}
// 滚动事件
window.addEventListener('scroll', debounce(handle, 1000));
节流
函数节流(throttle):当持续触发事件时,保证一定时间段内只调用一次事件处理函数。节流通俗解释就比如我们水龙头放水,阀门一打开,水哗哗的往下流,秉着勤俭节约的优良传统美德,我们要把水龙头关小点,最好是如我们心意按照一定规律在某个时间间隔内一滴一滴的往下滴。如下图,持续触发scroll事件时,并不立即执行handle函数,每隔1000毫秒才会执行一次handle函数。
函数节流主要有两种实现方法:时间戳和定时器。接下来分别用两种方法实现throttle~
节流时间戳
var throttle = function(func, delay) {
var prev = Date.now();
return function() {
var context = this;
var args = arguments;
var now = Date.now();
if (now - prev >= delay) {
func.apply(context, args);
}
}
}
function handle() {
console.log(Math.random());
}
window.addEventListener('scroll', throttle(handle, 1000));
节流定时器
// 节流throttle代码(定时器):
var throttle = function(func, delay) {
var timer = null;
return function() {
var context = this;
var args = arguments;
if (!timer) {
timer = setTimeout(function() {
func.apply(context, args);
timer = null;
}, delay);
}
}
}
function handle() {
console.log(Math.random());
}
window.addEventListener('scroll', throttle(handle, 1000));
节流throttle代码(时间戳+定时器)
// 节流throttle代码(时间戳+定时器):
var throttle = function(func, delay) {
var timer = null;
var startTime = Date.now();
return function() {
var curTime = Date.now();
var remaining = delay - (curTime - startTime);
var context = this;
var args = arguments;
clearTimeout(timer);
if (remaining <= 0) {
func.apply(context, args);
startTime = Date.now();
} else {
timer = setTimeout(func, remaining);
}
}
}
function handle() {
console.log(Math.random());
}
window.addEventListener('scroll', throttle(handle, 1000));
将类数组对象转换成真数组
使用数组 slice api 能将类数组对象转换成真实的数组, 例如获取到的 dom 的 nodeList 对象
function convertToArray(nodes){
var array = null;
try {
array = Array.prototype.slice.call(nodes, 0); //针对非 IE 浏览器
} catch (ex) {
array = new Array();
for (var i=0, len=nodes.length; i < len; i++){
array.push(nodes[i]);
}
}
return array;
}