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的更多相关文章

  1. JavaScript中面向对象的三大特性(一个菜鸟的不正经日常)

    经过几天的学习,把jQuery给啃会了,但是运用的还不算特别熟练,总感觉自己在JavaScript方面的基础十分欠缺,所以继续拾起JavaScript,开始更好的编程之旅~ 今天学的是JavaScri ...

  2. 浅谈JavaScript的面向对象和它的封装、继承、多态

    写在前面 既然是浅谈,就不会从原理上深度分析,只是帮助我们更好地理解... 面向对象与面向过程 面向对象和面向过程是两种不同的编程思想,刚开始接触编程的时候,我们大都是从面向过程起步的,毕竟像我一样, ...

  3. JavaScript的面向对象编程(OOP)(一)——类

    在学习JavaScript面向对象的编程之前,需要知道,并了解面向对象的一些基本的常识.初学者中大多数都以为面向对象中,面向对象的编程是很重要和占据很大一部分精力.笔者在之前也是认为OOP是面向对象的 ...

  4. javascript进阶——面向对象特性

    面向对象的javascript是这门语言被设计出来时就考虑的问题,熟悉OOP编程的概念后,学习不同的语言都会发现不同语言的实现是不同的,javascript的面向对象特性与其他具有面向对象特性的语言的 ...

  5. javascript的面向对象详解

    每次说到javascript到面向对象,总感觉自己心里懂,但是却不知道该怎么说,这就是似懂非懂到表现,于是乎,每次一说,就要到处去查找资料,零零碎碎到看了一些,感觉有懂了,但是过段时间,好像又不知道是 ...

  6. 浅谈JavaScript的面向对象程序设计(四)

    本文继续讲解JavaScript的面向对象程序设计.继承是面向对象语言中的一个基本概念,面向对象语言支持两种继承实现方式:接口继承和实现继承.接口继承只继承方法签名,而实现继承则继承实际的方法.但是在 ...

  7. JavaScript的面向对象原理之原型链详解

    一.引言 在16年的10月份,在校内双选会找前端实习的时候,hr问了一个问题:JavaScript的面向对象理解吗?我张口就说“JavaScript是基于原型的!”.然后就没什么好说的了,hr可能不知 ...

  8. 从 prototype.js 深入学习 javascript 的面向对象特性

    从 prototype.js 深入学习 javascript 的面向对象特性 js是一门很强大的语言,灵活,方便. 目前我接触到的语言当中,从语法角度上讲,只有 Ruby 比它更爽. 不过我接触的动态 ...

  9. javascript 的面向对象特性参考

    最近在看用javascript+css实现rich client.javascript 也是一个蛮有意思的语言.特别是其面向对象的实现和其他“标准”的OO launguage有很大的不同.但是,都是动 ...

随机推荐

  1. SecureCRT文件传输模式

    前言 如下图所示,SecureCRT6.5.0 有4种文件传输模式. 1)ASCII:最快的传输模式,但只能传文本 2)Xmodem:非常古老的传输协议速度较慢,但由于使用了CRC错误侦测方法,传输的 ...

  2. 使用ocupload和POI一键上传Excel并解析导入数据库

    使用的工具如下:  JQuery ocupload jquery.ocupload-1.1.2.js Apache POI poi-3.9.jar 如果是Maven项目添加依赖如下: <depe ...

  3. mybatis基础,mybatis核心配置文件properties元素

    peroperties元素 可外部配置且可动态替换的,既可以在典型的 Java 属性文件中配置,亦可通过 properties 元素的子元素来传递 为dataSource元素配置 <proper ...

  4. Sersync实时同步

    sersync会对目录进行监控,将变化的目录或文件同步到远程服务器.sersync是递归监控的,如果有多级目录 ,都会同步到远程服务器. sersync依赖于rsync进行同步,在同步主服务器上开启s ...

  5. 3390: [Usaco2004 Dec]Bad Cowtractors牛的报复

    3390: [Usaco2004 Dec]Bad Cowtractors牛的报复 Time Limit: 1 Sec  Memory Limit: 128 MBSubmit: 69  Solved:  ...

  6. lnmp pathinfo问题

    location / {              if (!-e $request_filename) {              rewrite  ^/(.*)$  /index.php/$1  ...

  7. Linux文件权限rwx简单了解

    Ⅰ  了解Linux下的文件权限 如上图所示,ll命令详细展示当前目录下的文件或者子目录信息 红框标注的即为此文件或者目录的权限 [第一行文件10.c的权限以-开头,用来说明这是一个文件:第四行cod ...

  8. VAO VBO IBO大乱炖

    最近对程序中绘制卡顿的问题忍无可忍,终于决定下手处理了.程序涉及的绘制比较多,除了点.线.三角形.多边形.圆柱体之外,还有自组格式模型.开始想全部采用显示列表优化,毕竟效率最高,虽然显示列表存在编译之 ...

  9. [笔记]LR和SVM的相同和不同

    之前一篇博客中介绍了Logistics Regression的理论原理:http://www.cnblogs.com/bentuwuying/p/6616680.html. 在大大小小的面试过程中,经 ...

  10. eclipse扩容

    -vmD:/jdk-6u17-windows-i586/jdk1.6.0_17/bin/javaw.exe-startupplugins/org.eclipse.equinox.launcher_1. ...