JavaScript ES5面向对象实现一个todolist
todo-list
前言
最近阅读了JavaScript设计模式的面向对象篇,但是又苦于实践,便想到了写一个简单的todo-list来巩固自己JavaScript面向对象设计的思想。希望对和我一样的小白有帮助。本文代码使用的是ES5,并非ES6。
要求:了解原型链。
遵守
怕文中有人不明白为什么要这么写,所以这里先说一下一些地方为什么要这么写。
来自《编写可维护的JavaScript》
- 将一些常量和不变的数据,放在配置文件里。
- CSS和JavaScript分离。
- 事件处理和业务逻辑单元分离。
// 如:
var config = {
classShow: 'show',
classHide: 'hide'
};
开始
布局
首先,先将HTML框架搭好,这里,就没有特别的做美化了。
<div>
<input type="text" data-input="work">
<ul data-list="work">
</ul>
</div>
设计对象
这个地方,倒是花了我一部分事件,不知道到底该如何设计,因为自己之前写过Java,Java里封装类的思想是尽可能单一功能,和组件的思想很像。
而最开始,我就陷入了深深的思考中,因为我想将这个简单的todo-list封装成一个对象,如果按单一功能的思想的话,就得将input封装为一个对象,li封装为一个对象,ul封装为一个对象,显然,这是不可能的。
于是,我转变思想,将它们整个封装一个对象。
对象的属性
对象的属性有:input, ul, list。为了实例化多个对象,将name传入函数里。因此, 代码如下:
var TodoList = function(name) {
this.list = document.querySelector('[data-list="' + name + '"]');
this.childs = this.list.querySelectorAll('li');
this.input = document.querySelector('[data-input="' + name + '"]');
}
事件绑定
仔细思考,其实就是一个增加、删除、查找的操作, 并且为了将事件处理和逻辑处理单元分隔开,所以事件绑定仅仅处理的是绑定事件。因此,代码如下:
var TodoList = function(name) {
this.list = document.querySelector('[data-list="' + name + '"]');
this.childs = this.list.querySelectorAll('li');
this.input = document.querySelector('[data-input="' + name + '"]');
// 绑定事件
this.init = function() {
// input按下enter键
this.input.addEventListener('keyup', function(event) {
this.handleKeyup(event);
}.bind(this));
// 事件委托,点击list
this.list.addEventListener('click', function(event) {
this.handleListClick(event);
}.bind(this));
// input的值改变时
this.input.addEventListener('input', function(event) {
this.handleInputChange(event);
}.bind(this));
};
};
/**
*
* 事件与应用单元分离
* handleKeyup
*
* {param} object event
*
*/
TodoList.prototype.handleKeyup = function(event) {
event.preventDefault();
event.stopPropagation();
this.addItem(event.keyCode, event.target);
}
/**
* 事件和应用单元分离
* 点击list,事件冒泡阶段处理, 委托事件
*
* {param} object event
*/
TodoList.prototype.handleListClick = function(event) {
event.preventDefault();
event.stopPropagation();
this.removeItem(event.target);
}
/**
* 事件和应用单元分离
* input内容改变,则模糊查找, 调用findItem()函数
*
* {param} object event
*/
TodoList.prototype.handleInputChange = function(event) {
var value = event.target.value;
event.preventDefault();
event.stopPropagation();
this.findItem(value);
}
在上面,你可能不知道为什么要绑定this,你需要了解一下bind函数的用处。
而调用事件对象的两个API是为了阻止事件的默认行为 以及 防止事件对象传播。
业务逻辑单元的操作
对事件绑定结束后,就需要对
事件绑定成功后,就将进行逻辑单元的代码编写。
看下面的代码:
/**
*
* 增加一个todo-item
* 注意,这里要绑定this
*
* {param} number event.keyCode
* {param} object event.target
*
*/
TodoList.prototype.addItem = function(keyCode, target) {
if(event.keyCode == 13 && event.target.value.trim().length > 0) {
this.append();
this.clearInput();
this.childs = this.list.querySelectorAll('li');
}
}
/**
* 删除一个todo-item
*
* {param} object event.target
*/
TodoList.prototype.removeItem = function(target) {
// 初始化执行的时候,不存在target
if(target) {
if(target.nodeName == 'BUTTON') {
target.parentNode.parentNode.removeChild(target.parentNode);
this.childs = this.list.querySelectorAll('li');
}
}
};
/**
*
* 查找输入字符串是否存在
* 如果不存在,就显示所有的list
* 如果存在,就显示存在的
*
*/
TodoList.prototype.findItem = function(value) {
var find = false;
// 隐藏所有
for(var i = 0;i < this.childs.length;i++) {
this.childs[i].className = config.classHide;
}
// 如果存在就显示
for(var i = 0;i < this.childs.length;i++) {
var nowEl = this.childs[i];
if(nowEl.firstChild.innerText.indexOf(value) != -1) {
nowEl.className = config.classShow;
find = true;
}
}
// 如果都没有就全部显示
if(!find) {
for(var i = 0;i < this.childs.length;i++) {
this.childs[i].className = config.classShow;
}
}
}
/**
*
* 清空输入框
*
*/
TodoList.prototype.clearInput = function() {
this.input.value = '';
}
/**
*
* 为totolist append一个li标签
*
*/
TodoList.prototype.append = function() {
var oLi = document.createElement('li');
var oBtn = document.createElement('button');
var oSpan = document.createElement('span');
oSpan.innerHTML = this.input.value.trim();
oBtn.innerHTML = 'delete';
oLi.appendChild(oSpan);
oLi.appendChild(oBtn);
this.list.appendChild(oLi);
};
实例化对象
var todo = new TodoList('work');
todo.init();
如果你想要查看这个简单的todo-list所有的代码,请点击这里
参考
- 《编写可维护的JavaScript》
- 《JavaScript设计模式》
JavaScript ES5面向对象实现一个todolist的更多相关文章
- JavaScript中面向对象的三大特性(一个菜鸟的不正经日常)
经过几天的学习,把jQuery给啃会了,但是运用的还不算特别熟练,总感觉自己在JavaScript方面的基础十分欠缺,所以继续拾起JavaScript,开始更好的编程之旅~ 今天学的是JavaScri ...
- 浅谈JavaScript的面向对象和它的封装、继承、多态
写在前面 既然是浅谈,就不会从原理上深度分析,只是帮助我们更好地理解... 面向对象与面向过程 面向对象和面向过程是两种不同的编程思想,刚开始接触编程的时候,我们大都是从面向过程起步的,毕竟像我一样, ...
- JavaScript的面向对象编程(OOP)(一)——类
在学习JavaScript面向对象的编程之前,需要知道,并了解面向对象的一些基本的常识.初学者中大多数都以为面向对象中,面向对象的编程是很重要和占据很大一部分精力.笔者在之前也是认为OOP是面向对象的 ...
- javascript进阶——面向对象特性
面向对象的javascript是这门语言被设计出来时就考虑的问题,熟悉OOP编程的概念后,学习不同的语言都会发现不同语言的实现是不同的,javascript的面向对象特性与其他具有面向对象特性的语言的 ...
- javascript的面向对象详解
每次说到javascript到面向对象,总感觉自己心里懂,但是却不知道该怎么说,这就是似懂非懂到表现,于是乎,每次一说,就要到处去查找资料,零零碎碎到看了一些,感觉有懂了,但是过段时间,好像又不知道是 ...
- 浅谈JavaScript的面向对象程序设计(四)
本文继续讲解JavaScript的面向对象程序设计.继承是面向对象语言中的一个基本概念,面向对象语言支持两种继承实现方式:接口继承和实现继承.接口继承只继承方法签名,而实现继承则继承实际的方法.但是在 ...
- JavaScript的面向对象原理之原型链详解
一.引言 在16年的10月份,在校内双选会找前端实习的时候,hr问了一个问题:JavaScript的面向对象理解吗?我张口就说“JavaScript是基于原型的!”.然后就没什么好说的了,hr可能不知 ...
- 从 prototype.js 深入学习 javascript 的面向对象特性
从 prototype.js 深入学习 javascript 的面向对象特性 js是一门很强大的语言,灵活,方便. 目前我接触到的语言当中,从语法角度上讲,只有 Ruby 比它更爽. 不过我接触的动态 ...
- javascript 的面向对象特性参考
最近在看用javascript+css实现rich client.javascript 也是一个蛮有意思的语言.特别是其面向对象的实现和其他“标准”的OO launguage有很大的不同.但是,都是动 ...
随机推荐
- SecureCRT文件传输模式
前言 如下图所示,SecureCRT6.5.0 有4种文件传输模式. 1)ASCII:最快的传输模式,但只能传文本 2)Xmodem:非常古老的传输协议速度较慢,但由于使用了CRC错误侦测方法,传输的 ...
- 使用ocupload和POI一键上传Excel并解析导入数据库
使用的工具如下: JQuery ocupload jquery.ocupload-1.1.2.js Apache POI poi-3.9.jar 如果是Maven项目添加依赖如下: <depe ...
- mybatis基础,mybatis核心配置文件properties元素
peroperties元素 可外部配置且可动态替换的,既可以在典型的 Java 属性文件中配置,亦可通过 properties 元素的子元素来传递 为dataSource元素配置 <proper ...
- Sersync实时同步
sersync会对目录进行监控,将变化的目录或文件同步到远程服务器.sersync是递归监控的,如果有多级目录 ,都会同步到远程服务器. sersync依赖于rsync进行同步,在同步主服务器上开启s ...
- 3390: [Usaco2004 Dec]Bad Cowtractors牛的报复
3390: [Usaco2004 Dec]Bad Cowtractors牛的报复 Time Limit: 1 Sec Memory Limit: 128 MBSubmit: 69 Solved: ...
- lnmp pathinfo问题
location / { if (!-e $request_filename) { rewrite ^/(.*)$ /index.php/$1 ...
- Linux文件权限rwx简单了解
Ⅰ 了解Linux下的文件权限 如上图所示,ll命令详细展示当前目录下的文件或者子目录信息 红框标注的即为此文件或者目录的权限 [第一行文件10.c的权限以-开头,用来说明这是一个文件:第四行cod ...
- VAO VBO IBO大乱炖
最近对程序中绘制卡顿的问题忍无可忍,终于决定下手处理了.程序涉及的绘制比较多,除了点.线.三角形.多边形.圆柱体之外,还有自组格式模型.开始想全部采用显示列表优化,毕竟效率最高,虽然显示列表存在编译之 ...
- [笔记]LR和SVM的相同和不同
之前一篇博客中介绍了Logistics Regression的理论原理:http://www.cnblogs.com/bentuwuying/p/6616680.html. 在大大小小的面试过程中,经 ...
- eclipse扩容
-vmD:/jdk-6u17-windows-i586/jdk1.6.0_17/bin/javaw.exe-startupplugins/org.eclipse.equinox.launcher_1. ...