前端路由
- 那种spa应用,都是前端路由
- 后端路由成为服务器路由,对于服务器来说,会根据请求的相应的url,来找到相应的映射函数,然后执行该函数,将函数的返回值发送给客户端
- 对于前端路由来说,后端的路由映射函数通常是进行DOM的显示和隐藏操作
优缺点
后端路由优点: 安全性好,
SEO
好缺点: 加大服务器压力,不利于用户体验
前端路由优点: 开发方便,只需要修改路径就可以啦,没有网络延迟,用户体验好
缺点: 浏览器的前进,退后的时候会重新发送请求,没有合理的缓存,同样不利于
SEO
前端路由实现方案
-
hash
window.location.hash
-
history API
history.pushState()
history.replaceState()
window.history.back() 后退
window.history.forward() 前进
window.history.go(1) 前进1部,-2退后两次
那怎么监控history
每当同一个文档浏览历史出现变化时都会触发popState事件,只需要监控事件
window.addEventListener('popstate',function(event){
})
但是仅仅调用pushState
或replaceState
方法,并不会触发该事件
那怎么让pushState
或replaceState
事件
const _wr=function(type){
let orig=history[type]
return function(){
let rv=orig.apply(this,arguments)
let e= new Event(type)
e.arguments=arguments
window.dispatchEvent(e)
return rv
}
}
//重写方法
history.pushState = _wr('pushState');
history.replaceState = _wr('replaceState');
//实现监听
window.addEventListener('replaceState', function(e) {
console.log('THEY DID IT AGAIN! replaceState 111111');
});
window.addEventListener('pushState', function(e) {
console.log('THEY DID IT AGAIN! pushState 2222222');
});
学习angular的时候收集的一些资料
https://mlog.club/articles/3454
https://alligator.io/angular/
https://laixiazheteng.com/subject
https://blog.kevinyang.net/categories/Angular/
http://www.ngbeijing.cn/
https://rxjs-dev.firebaseapp.com/guide/observable
https://ithelp.ithome.com.tw/users/20090728/ironman/1600 Angular深入浅出三十天
https://github.com/ymfe/yapi
Array.prototype.entries()
返回一个新的Array Iterator 对象,该对象包含数组中每个索引的键/值对
let arr = ['a', 'b', 'c'] let a = arr.entries() console.log(a.next().value) // [0,'a'] console.log(a.next().value) // [1,'b'] console.log(a.next().value) // [2,'c']
串联瀑布流
const wait = value => new Promise(resolve => {
setTimeout(() => resolve(value), 3000)
})
const fetchFoo = () => wait('foo')
const fetchBar = () => wait('bar')
const fetchBaz = () => wait('baz')
const fetchDataSlowly = async time => {
// 串联瀑布流
const foo = await fetchFoo()
const bar = await fetchBar()
const baz = await fetchBaz()
return {foo, bar, baz, time: Date.now() - time}
}
fetchDataSlowly(Date.now())
.then(({foo, bar, baz, time}) => {
console.log('fetched slowly:', foo, bar, baz, time
)
})
并联瀑布流
const wait = value => new Promise(resolve => {
setTimeout(() => resolve(value), 3000)
})
const fetchFoo = () => wait('foo')
const fetchBar = () => wait('bar')
const fetchBaz = () => wait('baz')
const fetchDataQuickly = async time => {
// 并行瀑布流
const [
foo,
bar,
baz
] = await Promise.all([
fetchFoo(),
fetchBar(),
fetchBaz()
])
return {foo, bar, baz, time: Date.now() - time}
}
fetchDataQuickly(Date.now())
.then(({ foo, bar, baz, time}) => {
console.log('fetched quickly:', foo, bar, baz, time);
});
Object.fromEntries
类似
Array
,Map
把键值对转换为一个对象let map=new Map([['a',1],['b',2],['c',3]]) console.log(Object.fromEntries(map)) // { a: 1, b: 2, c: 3 } let arr = [['a', 1], ['b', 2], ['c', 3]] console.log(Object.fromEntries(arr)) // { a: 1, b: 2, c: 3 }
平滑滚动到浏览器窗口的可见区域
const smoothScroll = element =>
document.querySelector(element).scrollIntoView({
behavior:'smooth'
});
//平滑滚动到ID为id的元素elementID
smoothScroll('#elementID');
undefined和null的区别
undefined==null //true
1+null //1
1+undefined //NaN
发现一道有意思的算法题
AAAABBCCCdFFFd
4A2B3C1d3F
const encodingStr = str => {
if (str.length === 0) {
return ''
}
let currChar = str.charAt(0)
let count = 1
let encoding = ''
for (let i = 1; i < str.length; i++) {
const char = str.charAt(i)
if (char === currChar) {
count++
} else {
encoding += count + currChar
count = 1
currChar = char
}
}
return encoding
}
console.log(encodingStr('AAAABBCCCdFFFd'))
正则
叠词分割
let str = 'AAAABBCCCddFFFdddege'
console.log(str.match(/(.)1*/g))
[
'AAAA', 'BB',
'CCC', 'dd',
'FFF', 'ddd',
'e', 'g',
'e'
]
Element.animate
js动画
参数
* 关键帧是一个对象,代表关键帧的一个集合
* 代表动画持续时间的整数数字(毫秒单位),也可以是一个时间对象
> duration 每次迭代的毫秒数
> iterations 动画重复次数
export class TextThreeComponent implements OnInit, AfterViewInit {
constructor() {
}
public action = [{
transform: 'rotate(0) translate3D(-50%, -50%, 0)',
color: '#000'
},
{
color: '#431236',
offset: 0.3
},
{
transform: 'rotate(360deg) translate3D(-50%, -50%, 0)',
color: '#000'
}
];
public animation;
timing = {
duration: 3000,
iterations: Infinity
};
ngAfterViewInit() {
this.animation=document.querySelector('.ccc').animate(this.action, this.timing)
}
ngOnInit(): void {}
}
play.onclick =()=> animation.play(); //播放
pause.onclick =()=> animation.pause(); // 暂停
reverse.onclick =()=> animation.reverse(); // 反向