0%

网易云音乐项目踩坑与套路

只是记录自己在写网易云的项目自己遇到的一些与使用到的一些小套路

MVC

把代码敲两遍,数十次 mvc,你会明白他的强大。

在编写admin.html使用了 MVC 模式使得代码更加的清晰和简单而强大

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
{
let view = {
el: '#selector',
template: `html`,
render(data){
$(this.el).html(this.template)
}
},
let moudel = {
data: {},
}
let controller = {
view: null,
moudel: null,
init(view, moudel){
view = this.view
moudel = this.moudel
this.view.render(this.moudel.data)
this.bindEvent()
},
bindEvent(){},
}
controller.init(view, moudel)
}

浅拷贝与深拷贝

之前感觉这东东的概念啥的并不难,可是是个坑,我很久才发现,在admin.html上传歌曲后没事,但是上传第二首发现之前哪一首歌的名字在屏幕上与现在这一首的名字相同,debug后才发现了这一段代码

1
Object.assign(this.object, ...attributes)

Object.assign这个方法是个坑啊,这方法实行的是浅拷贝,而不是深拷贝。也就是说,如果源对象某个属性的值是对象,那么目标对象拷贝得到的是这个对象的引用。

所以说我改成

1
this.data = {id, ...attribute}

就好了,但你可能说这他么不一样吗?哈哈地址不一样的,我当时也想了很久,我在后面代码传出去了this.data, 可是在使用Object.assign()并不会改变this.data的地址,而现在这方法是让它指向另一块地址,这样就不会导致第二次修改而导致第一次的值改变。

感觉就是最好不用 Object.assign()

不过我选择了另一方法,在使用 this.data时对其进行深拷贝这样就不会是一个地址了

1
let data = JSON.Parse(JSON.Stringify(this.model.data))

发布与订阅模式

为了实现传说中的低耦合高内聚,其实是为了各个模块中的数据能进行方便交互而暴露出一个小口子,定于的时候告知到调用的函数名,要发布的时候使用回调就可以了。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
window.eventHub = {
events:{
//事件名
人明日报:[],
光明日报:[],
},
//订阅
on(eventName, fn){
if(this.events[eventName] === undefined){
this.events[eventName] === []
}
this.events[eventName].push(fn)
},
//发布
emit(eventName, data){
fnList = this.events[eventName]
fnList.map((fn)=>{
fn.call(undefined, data)
})
},
}

字母的错?

说实在JavaScript感觉特坑啊, 有时候你打错了参数,不好意思连浏览器都可能不给你报错,你只有一步一步的去debug,可以说真的要。今天是被它虐得死去活来的。说实在这与自己思路不够清晰有关。

流程图

刚刚开始敲代码的时候,老师就说过画流程图的重要性,可是一直我都是不以为然,可适当代码的量上去了以后就发现自己脑袋中的栈不够用了,不知道前几部干了啥,后几部该咋走,后来用百度脑图把思路先想好在慢慢来感觉条理清晰很多。先想好要干啥在开始干。

为何不能两次上传

第二次自己写这个项目的时候, 将之前的上传区域与创建新歌曲的 mvc 写在了一起,没有分开写,
后来发现歌曲上传一次后就不能再上传,刷新页面后又能上传一次,但是我没发现这重要的一点,一直以为是七牛 sdk 有问题。后来静静思考,是每一次上传后就不能再上传了,肯定是上传后的问题。我后来发现我每次 subit 表单以后都 render() 了 可是每 render() 应该再次调用 qiniuinit() 函数,这样来问题就引刃而解。

jquery on(‘click’) 失效

在制作音乐播放页面的时候去监听页面,一直发现监听无效,辗转多次都未发现原因,后来换了一个元素来进行事件委托就可以,仔细想应该是在对图片应用时的对委托元素的display与visibity进行了修改。

display:none 还是 visibility: hidden

隐藏一个元素可以通过把display属性设置为”none”,或把visibility属性设置为”hidden”。但是请注意,这两种方法会产生不同的结果。

visibility:hidden可以隐藏某个元素,但隐藏的元素仍需占用与未隐藏之前一样的空间。也就是说,该元素虽然被隐藏了,但仍然会影响布局。所以当她再次显现的时候就不会影想布局感觉用这个会好很多。