需要注意的问题:

1、其他模块若是使用构造函数MP3创建对象,唯一不同的就是他们传入的音乐库是不一样的,所以构造函数中存在一个songList属性,其他一样的就被添加到了构造函数的原型对象之中

2、原型对象是直接替换的,所以会失去constructor属性,我们最好给这个属性重新赋值

3、我们new的过程中,就可以将传入的音乐库进行提取然后渲染到浏览器上,所以在属性中我们在new过程中就去执行render()方法

4、还有在CURD的方法调用中,只要修改了原来的songList库就必须再次调用render()方法

<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
<style>
* {
padding: 0;
margin: 0;
} .clearfix::after {
content: '';
visibility: hidden;
display: block;
clear: both;
} .container {
width: 800px;
margin: 0 auto;
border: 1px solid #000;
} .songslist-top {
height: 50px;
line-height: 50px;
} .songslist-header span {
display: inline-block;
float: left;
width: 350px;
height: 50px;
line-height: 50px;
text-align: center;
background-color: lightblue;
border-right: 1px solid black;
} .songslist-header span:nth-child(3) {
border-right: none;
width: 98px;
} .songslist-single {
height: 50px;
line-height: 50px;
} .songslist-single .songslist-name {
display: block;
float: left;
width: 350px;
text-align: center; } .songslist-single .songslist-singer {
width: 350px;
display: block;
float: left;
text-align: center;
}
</style>
</head>
<body>
<div class="container">
<div class="songslist-top">
歌曲名:<input type="text">&nbsp;&nbsp;&nbsp;&nbsp;
歌手名:<input type="text">&nbsp;&nbsp;&nbsp;&nbsp;
<input type="button" value="添加">&nbsp;&nbsp;&nbsp;&nbsp;
<input type="button" value="修改">&nbsp;&nbsp;&nbsp;&nbsp;
<input type="button" value="删除">&nbsp;&nbsp;&nbsp;&nbsp;
</div>
<div class="songslist-header clearfix">
<span>歌曲名</span>
<span>歌手名</span>
<span>操作</span>
</div>
<div class="songslist-main clearfix">
<div class="songslist-single">
<span class="songslist-name">dd</span>
<span class="songslist-singer">dd</span>
</div>
</div>
</div>
<script> function MP3(songs) {
//songList属性用来存储歌曲信息
//当创建歌曲管理工具实例的时候,如果有参数传进来就将参数赋值给songList,如果没有就给一个空数组
this.songList = songs || [];
this._init();
} MP3.prototype = {
////由于是替换原型对象,所以constructor属性会丢失,所以需要手动设置
constructor: MP3,
_init: function () {
this.render();
},
//数据驱动,只要歌曲列表发生改变,就调用render方法,将页面上信息进行刷新渲染
render: function () {
//获取到歌曲列表的父盒子
var listDiv = document.getElementsByClassName("songslist-main")[0];
//定义这个数组用来拼接字符串
var strArr = [];
//遍历歌曲列表中所有的歌曲信息
for (var i = 0; i < this.songList.length; i++) {
var song = this.songList[i];
//使用每一个歌曲信息,拼接单独的歌曲html字符串
strArr.push('<span class="songslist-single">' +
'<span class="songslist-name">' + song.name + '</span>' +
'<span class="songslist-singer">' + song.singer + '</span>' +
'</span>');
}
//将所有的歌曲信息html字符串进行组合
var str = strArr.join("");
//直接将父盒子的内容修改为已经拼接好的字符串
listDiv.innerHTML = str;
},
//查询
selectSong: function (songName) {
for (var i = 0; i < this.songList.length; i++) {
var song = this.songList[i];
if (song.name == songName) {
return song;
}
}
return null;
},
//增加
addSong: function (songName, singer) {
//判断是否有传入参数,而且要判断传入参数是否为空字符串 // if(!songName||!singer){
// throw "请以正确方式添加歌曲!";
// } if (songName == undefined || singer == undefined || songName == "" || singer == "") {
throw "请以正确方式添加歌曲!";
}
//使用传入的参数,构建一个歌曲对象
var temp = {name: songName, singer: singer}
//将歌曲对象添加到songList中
this.songList.push(temp);
//在根据歌曲列表重新渲染页面
this.render();
return temp;
},
//删除
removeSong: function (songName) {
//调用seleteSong方法找到指定歌曲
var song = this.selectSong(songName);
//获取这个歌曲在歌曲列表中索引
var index = this.songList.indexOf(song);
//判断这个索引是不是为-1 也就是与没有找到
if (index != -1) {
//如果直到了,就直接将其从数组中删除
this.songList.splice(index, 1);
//因为数组改变了,所以再次重新渲染
this.render();
return true;
} else {
return false;
}
},
//修改
updateSong: function (songName, singer) {
var song = this.selectSong(songName);
if (song == null) {
return null;
} else {
song.singer = singer;
this.render();
return song;
}
}
};
var arr = [
{name: '哎呦', singer: '石磊'},
{name: '青春之歌', singer: '石磊'},
{name: '最后一首歌', singer: '石磊'},
{name: '我把青春另存了', singer: '石磊'},
];
var mp3 = new MP3(arr);
var songName = document.getElementsByTagName('input')[0];
var songerName = document.getElementsByTagName('input')[1];
var addBtn = document.getElementsByTagName('input')[2];
var updateBtn = document.getElementsByTagName('input')[3];
var removeBtn = document.getElementsByTagName('input')[4];
console.log(addBtn);
addBtn.onclick = function () {
var song = songName.value;
var singer = songerName.value;
if (song.trim() !== "" && singer.trim() !== "") {
mp3.addSong(song, singer);
}
}
updateBtn.onclick=function () {
var song = songName.value;
var singer = songerName.value;
if (song.trim() !== "" && singer.trim() !== "") {
mp3.updateSong(song, singer);
}
}
removeBtn.onclick = function () {
var song = songName.value;
if (song.trim() !== "") {
mp3.removeSong(song);
}
}
</script>
</body>
</html>

JS高级——面向对象方式解决歌曲管理问题的更多相关文章

  1. JS高级——面向对象方式解决tab栏切换问题

    注意事项 1.给li元素注册事件,函数里面的this指的li元素,那么我们可以在注册事件之前将Tab对象用that=this进行保存 2.使用沙箱模式,所以暴露给外面的变量使用的是window.tab ...

  2. js高级-面向对象继承

    一.工厂模式创建对象及优缺点 继承就是把公共的部分抽象出来作为父类,基类.吃饭,跑步等 var a = {}; //批量创建不方便,不能重复设置公共属性的代码 //工厂模式出现了,创建10个Cat对象 ...

  3. JS高级 - 面向对象1(this,Object ,工厂方式,new )

    面向对象三要素: 封装 继承 多态 1.this 详解,事件处理中this的本质 window this -- 函数属于谁 <script type="text/javascript& ...

  4. JS高级 - 面向对象4(json方式面向对象)

    把方法包在一个Json里 var p1 = { name: "唐三", sex: "男", dreamdu: { URL: "www.dreamdu. ...

  5. JS高级 - 面向对象5(继承,引用)

    <script type="text/javascript"> //------------------Person类 //(Person)的构造函数 function ...

  6. JS高级 - 面向对象3(面向过程改写面向对象)

    改写: 1.前提:所有东西都在 onload 里 2.改写:不能有函数嵌套,可以有全局变量 onload --> 构造函数 全局变量 --> 属性 函数 --> 方法 4.改错: t ...

  7. JS高级---面向对象的编程思想(贪吃蛇梳理)

    面向对象的编程思想(贪吃蛇梳理) 模拟贪吃蛇游戏,做的项目 地图: 宽,高,背景颜色,因为小蛇和食物都是相对于地图显示的, 这里小蛇和食物都是地图的子元素, 随机位置显示, 脱离文档流的, 地图也需要 ...

  8. JS高级 - 面向对象2(prototype定义)

    定义和用法 prototype 属性允许您向对象添加属性和方法 注意: Prototype 是全局属性,适用于所有的Javascript对象. 语法 object.prototype.name=val ...

  9. JS高级. 04 增删改查面向对象版歌曲管理、递归、

    增 数组.push() 删 数组.splice(开始删除索引,删除几个) 在当前对象中调用当前对象的方法中和属性,必须用this调用 nodeType判断节点类型 节点.nodeType ==  1: ...

随机推荐

  1. 最大公约数GCD

    基准时间限制:1 秒 空间限制:131072 KB 分值: 0 难度:基础题 输入2个正整数A,B,求A与B的最大公约数. Input 2个数A,B,中间用空格隔开.(1<= A,B <= ...

  2. WINDOWS下调用GetTokenInformation的奇怪之处--两次调用

    就是用getLastErr可以得到错误号,同时,会将需要的长度写到参数里,再进行第二次调用,以此来节约内存空间. 神奇的长见识了. 相关说法如下: ====================== The ...

  3. kendo grid 点击新增没有反映

    在datasource中缺少 editable: "inline",这一行

  4. Python3基础(十一) 类的拓展

    在类的初印象中,我们已经简单的介绍了类,包括类的定义.类对象和实例对象.本文将进一步学习类的继承.迭代器.发生器等等. 一.类的继承 单继承 派生类的定义如下: class DerivedClassN ...

  5. Ajax跨域、Json跨域、Socket跨域和Canvas跨域等同源策略限制的解决方法

    同源是指同样的协议.域名.port,三者都同样才属于同域.不符合上述定义的请求,则称为跨域. 相信每一个开发者都曾遇到过跨域请求的情况,尽管情况不一样,但问题的本质都能够归为浏览器出于安全考虑下的同源 ...

  6. NATS连线协议具体解释

    NATS连线协议具体解释 作者:chszs,未经博主同意不得转载.经许可的转载需注明作者和博客主页:http://blog.csdn.net/chszs NATS的连线协议是一个简单的.基于文本的公布 ...

  7. 寒城攻略:Listo 教你用 Swift 写IOS UI 项目生活记事本

    刚才用 Swift 写了一个记事本的应用,仅仅是简单的 UI 方向的开发,先来上产品的界面: 如今 Listo 给分享源码: 共同进步,开源中国.转载请声明出处

  8. TTS-零基础入门-10分钟教你做一个语音功能

    在本片博客正式開始之前,大家先跟我做一个简单的好玩的 小语音. 新建一个文本文档,然后再文档里输入这样 一句话  CreateObject("SAPI.SpVoice").Spea ...

  9. cojs1101. [Vijos1369] 难解的问题==codevs 2188 最长上升子序列

    [题目描述] 在你的帮助下,蔚蓝来到了埃及.在金字塔里,蔚蓝看到了一个问题,传说,能回答出这个问题的人就能受到埃及法老的祝福,可是蔚蓝日夜奋战,还是想不出来,你能帮帮他么?(XXX: 胡扯,教主怎么可 ...

  10. The bytes/str dichotomy in Python 3

    The bytes/str dichotomy in Python 3 - Eli Bendersky's website https://eli.thegreenplace.net/2012/01/ ...