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. Zabbix简介及安装

    前言 未经监控就上线的系统,就是裸奔,耍流氓. 监控对我们来说太重要了,监控工具也有很多,像,Cacti,Nagios,Ganglia,Zabbix等等,今天我们要介绍的是Zabbix,它的功能很强大 ...

  2. vue1升级到vue2的问题

    router 不能用map方法了,需要改router的结构改为 routers= [ { // 当没有匹配路由时默认返回的首页        path:'/index',        compone ...

  3. C#读取和写入XML文件

    关于xml是属于一个比较重要的东西,在平时开发的过程中,这块内容最主要的是要掌握XML内容的读取和写入操作. 一.什么是XML? XML 指可扩展标记语言(EXtensible Markup Lang ...

  4. 计算机网络之HTTP(上)基础知识点

    计算机网络,应该是我们编程开发.产品上线到正常的运行维护需要考虑的基本条件之一.之前我记录了一篇很简单的计算机的组成(http://www.cnblogs.com/zhangxiongcn/p/636 ...

  5. JavaScript:void(0);的作用

    JavaScript中void是一个操作符,该操作符指定要计算一个表达式但是不返回值. void 操作符用法格式如下: 1. javascript:void (expression) 2. javas ...

  6. 解决https证书验证不通过的问题

    1.报错信息 java.security.cert.CertificateException: No name matching api.weibo.com found; nested excepti ...

  7. wap问答系统工作总结

    一直想找个锻炼自己的机会,但是又很恐慌,怕自己能力太差,把握不住机会,把事情弄糟. 终于,要做wap问答系统了,本来说是几个人一块儿做,我分析了下页面,发现共同的部分还是比较多的,有点想法,要不我接过 ...

  8. Selenium 运行时出现错误(java.lang.NoClassDefFoundError: com/google/common/base/Function)

    已经写好了java脚本,点击运行的过程中如果出现如下的错误提示时: java.lang.NoClassDefFoundError: com/google/common/base/Function 问题 ...

  9. Git基础教程(二)

    继续上篇Git基础教程(一),在开篇之前,先回顾一下上篇中的基本命令. 配置命令:git config --global * 版本库初始化:git init 向版本库添加文件:git add * 提交 ...

  10. Java面试03|并发及锁

    1.synchronized与Lock的区别 使用synchronized这个关键字实现的同步块有一些缺点: (1)锁只有一种类型 (2)线程得到锁或者阻塞 (3)Lock是在Java语言层面基于CA ...