引见
纪录一些本身写代码过程当中碰到的题目,google来的一些技能和要领。
Iconfont的symbol引入
- Iconfont的symbol引入,最好链接前加https:头,防备遭到package.json里homepage的影响(假如设置了的话)。
- 除非是双色图标,不然不要在线修正其色彩,并批量去色,然后直接经由过程代码修正到本身须要的色彩。在线修正会写死fill属性,css改色彩就不能纯真的经由过程color来修正了。
Input 只显示下划线
能够经由过程设置背景为none,在设置border到达结果。
input{
background: none;
border-bottom: 1px solid #dbdbdb;
border-top: 0px;
border-left: 0px;
border-right: 0px;
}
对象数组依据某属性去重
一个比较精简的写法。
const res = new Map();
return arr.filter((a) => !res.has(a. attr) && res.set(a. attr, 1))
深拷贝
JSON.parse(JSON.stringify(object))
img标签隐蔽占位边框
img标签设置的width和height,假如src为空则会涌现占位框。
img[src=""],img:not([src]) {
opacity: 0;
}
React中router题目
React中router跳转时,旧组件的componentWillUnmount和新组件的constructor并非按递次实行的。举个栗子,即旧组件烧毁window.onresize会把新组件constructor增加的window.onresize监听烧毁掉。但假如是在新组件componentDidMount中经由过程window.addEventListener则不会遭到影响。
非同源文件下载
同源能够经由过程a标签的download属性下载,非同源则以下:
/**
* 猎取 blob
* @param {String} url 目的文件地点
* @return {Promise}
*/
function getBlob(url) {
return new Promise(resolve => {
const xhr = new XMLHttpRequest();
xhr.open('GET', url, true);
xhr.responseType = 'blob';
xhr.onload = () => {
if (xhr.status === 200) {
resolve(xhr.response);
}
};
xhr.send();
});
}
/**
* 保留
* @param {Blob} blob
* @param {String} filename 想要保留的文件名称
*/
function saveAs(blob, filename) {
if (window.navigator.msSaveOrOpenBlob) {
navigator.msSaveBlob(blob, filename);
} else {
const link = document.createElement('a');
const body = document.querySelector('body');
link.href = window.URL.createObjectURL(blob);
link.download = filename;
// fix Firefox
link.style.display = 'none';
body.appendChild(link);
link.click();
body.removeChild(link);
window.URL.revokeObjectURL(link.href);
}
}
/**
* 下载 末了直接挪用download即可
* @param {String} url 目的文件地点
* @param {String} filename 想要保留的文件名称
*/
export function download(url, filename) {
getBlob(url).then(blob => {
saveAs(blob, filename);
});
}
防抖函数
防抖动是将屡次实行变成末了一次实行。
/**
* 防抖函数,返回函数一连挪用时,余暇时刻必需大于或即是 wait,func 才会实行
*
* @param {function} func 回调函数
* @param {number} wait 示意时刻窗口的距离
* @param {boolean} immediate 设置为ture时,是不是马上挪用函数
* @return {function} 返回客户挪用函数
*/
export function debounce(func, wait = 200, immediate = false) {
let timer, context, args
// 耽误实行函数
const later = () => setTimeout(() => {
// 耽误函数实行终了,清空缓存的定时器序号
timer = null
// 耽误实行的情况下,函数会在耽误函数中实行
// 运用到之前缓存的参数和上下文
if (!immediate) {
func.apply(context, args)
context = args = null
}
}, wait)
// 这里返回的函数是每次现实挪用的函数
return function (...params) {
// 假如没有建立耽误实行函数(later),就建立一个
if (!timer) {
timer = later()
// 假如是马上实行,挪用函数
// 不然缓存参数和挪用上下文
if (immediate) {
func.apply(this, params)
} else {
context = this
args = params
}
// 假如已有耽误实行函数(later),挪用的时刻消灭本来的并从新设定一个
// 如许做耽误函数会从新计时
} else {
clearTimeout(timer)
timer = later()
context = this
args = params
}
}
}
撙节函数
撙节是将屡次实行变成每隔一段时刻实行。
/**
* underscore 撙节函数,返回函数一连挪用时,func 实行频次限定为 次 / wait
*
* @param {function} func 回调函数
* @param {number} wait 示意时刻窗口的距离
* @param {object} options 假如想疏忽最先函数的的挪用,传入{leading: false}。
* 假如想疏忽末端函数的挪用,传入{trailing: false}
* 二者不能共存,不然函数不能实行
* @return {function} 返回客户挪用函数
*/
_.throttle = function(func, wait, options) {
var context, args, result;
var timeout = null;
// 之前的时刻戳
var previous = 0;
// 假如 options 没传则设为空对象
if (!options) options = {};
// 定时器回调函数
var later = function() {
// 假如设置了 leading,就将 previous 设为 0
// 用于下面函数的第一个 if 推断
previous = options.leading === false ? 0 : _.now();
// 置空一是为了防备内存走漏,二是为了下面的定时器推断
timeout = null;
result = func.apply(context, args);
if (!timeout) context = args = null;
};
return function() {
// 取得当前时刻戳
var now = _.now();
// 初次进入前者肯定为 true
// 假如须要第一次不实行函数
// 就将上次时刻戳设为当前的
// 如许在接下来盘算 remaining 的值时会大于0
if (!previous && options.leading === false) previous = now;
// 盘算剩余时刻
var remaining = wait - (now - previous);
context = this;
args = arguments;
// 假如当前挪用已大于上次挪用时刻 + wait
// 或许用户手动调了时刻
// 假如设置了 trailing,只会进入这个前提
// 假如没有设置 leading,那末第一次会进入这个前提
// 另有一点,你可能会以为开启了定时器那末应当不会进入这个 if 前提了
// 实在照样会进入的,由于定时器的延时
// 并非正确的时刻,极可能你设置了2秒
// 然则他须要2.2秒才触发,这时刻就会进入这个前提
if (remaining <= 0 || remaining > wait) {
// 假如存在定时器就清算掉不然会挪用二次回调
if (timeout) {
clearTimeout(timeout);
timeout = null;
}
previous = now;
result = func.apply(context, args);
if (!timeout) context = args = null;
} else if (!timeout && options.trailing !== false) {
// 推断是不是设置了定时器和 trailing
// 没有的话就开启一个定时器
// 而且不能不能同时设置 leading 和 trailing
timeout = setTimeout(later, remaining);
}
return result;
};
};
设置git commit 模板
建立 .git-commit-template.txt
写入(头部发起空一行,行尾序列为LF(vscode能够更改)):
# <范例>: (范例的值见下面形貌) <主题> (最多50个字)
# 诠释为何要做这些修改
# |<---- 请限定每行最多72个字 ---->|
# 供应相干文章和别的资本的链接和关键字
# 比方: Github issue #23
# --- 提交 完毕 ---
# 范例值包括
# feat (新特征)
# fix (bug修复)
# docs (文档修改)
# style (格式化, 缺失分号等; 不包括临盆代码更改)
# refactor (重构代码)
# test (增加缺失的测试, 重构测试, 不包括临盆代码更改)
# chore (更新grunt使命等; 不包括临盆代码更改)
# --------------------
# 注重
# 主题和内容以一个空行分开
# 主题限定为最大50个字
# 主题行大写
# 主题行完毕不必标点
# 主题行运用祈使名
# 内容每行72个字
# 内容用于诠释为何和是什么,而不是怎么做
# 内容多行时以'-'分开
# --------------------
然后把该文件丢到你喜好的位置。
//这个敕令只能设置当前分支的提交模板
git config commit.template [模板文件位置]
//这个敕令能设置全局的提交模板
git config --global commit.template [模板文件位置]
完成!
更猛烈的范例束缚能够看这个文雅的提交你的 Git Commit Message。