需要注意的问题:

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. 互联网DSP广告系统架构及关键技术解析

    互联网DSP广告系统架构及关键技术解析 宿逆 关注 1.9 2017.10.09 17:05* 字数 8206 阅读 10271评论 2喜欢 60 广告和网络游戏是互联网企业主要的盈利模式 广告是广告 ...

  2. PHP rand()和mt_rand()的区别

    rand()和mt_rand()作用都是产生一个随机整数,都有两种使用形式: 1.int rand(void) / int mt_rand(void) 2.int rand(int $min, int ...

  3. postgresql vacuum table

    2down vote according to Documentation VACUUM reclaims storage occupied by dead tuples. But according ...

  4. git bash here真牛!

    git bash here真牛! 在Windows上面安装了git,在文件夹里面空白处右键点击,选择git bash here: 随手敲了几个命令:ls,ls -a,which ls,who, fin ...

  5. 用XMLRPC开服务进行server/client通信

    本文讲一下怎样用python的xmlrpc开服务,进行server/client的通信. 应用场景:1)需多client訪问应用程序给予应答情况--网页服务.  2)数据极大,希望载入一次.后面仅仅用 ...

  6. java中commons-beanutils的介绍

    1.   概述 commons-beanutil开源库是apache组织的一个基础的开源库.为apache中很多类提供工具方法.学习它是学习其它开源库实现的基础. Commons-beanutil中包 ...

  7. The Pragmatic Programmer 读书笔记之中的一个 DRY-Don’t Repeat Youself

     The Pragmatic Programmer读书笔记之中的一个 DRY-Don't Repeat Youself 尽管自己买了非常多软件project方面的书,可是由于时间的问题.一直没有静 ...

  8. 微软的技术态度 -- 从其对于CRT的设计考虑说起(Thought on the CRT - What Microsoft Prefers)

    很多人从C语言学习过来的人都知道,在编写程序时用到的像printf这样的函数,是作为该语言标准库函数提供的,这也是C语言标准中规定的内容.因此,操作系统必须对其保持一定程度上的透明,也就是说,作为一个 ...

  9. coffeescript遍历json对象

    直接给代码: headers = a:"this is a" ,b:"this is b" ,c:"this is c" exheaders ...

  10. go语言笔记——调试还很弱,用gdb来做?可用panic和defer。格式化代码使用gofmt,貌似我的vim插件是自带

    3.3 调试器 应用程序的开发过程中调试是必不可少的一个环节,因此有一个好的调试器是非常重要的,可惜的是,Go 在这方面的发展还不是很完善.目前可用的调试器是 gdb,最新版均以内置在集成开发环境 L ...