写一个addEventListener以及removeEventListener
第一步:对象属性赋值为函数,对象内部函数控制年龄这一参数变化,同时成长事件也执行。
class Person{
constructor(){
this.name = '';
this.age = 0;
this.growup()//不断成长
this.growEvent = null//成长经历的事情
}
setName(val){
this.name = val
}
growup(){
let _this = this;
setInterval(()=>{
_this.age++;
if(_this.growEvent instanceof Function){//判断是不是函数
_this.growEvent()
}
},100)
}
}
let hx = new Person()
hx.setName('韩信')
hx.growEvent = function(){
if(this.age == 18){
console.log('开始参军啦')
}
}
继续思考:成长事件只能接受一个函数,那么如果是多个函数呢?韩信要打仗,要建功立业的呀。可以很快的想到growEvent换成数组来接受多个函数。
那么,growEvent就要靠Push进数组了,而不是粗暴的赋值了。成长事件执行的时候也不再是上门的_this.growEvent,而是循环了。
class Person{
constructor(){
this.name = '';
this.age = 0;
this.growup()//不断成长
this.growEvent = []//需要接受多个函数
}
setName(val){
this.name = val
}
growup(){
let _this = this;
setInterval(()=>{
_this.age++;
_this.growEvent.forEach(cb=>{
if(cb instanceof Function){
cb.call(this)//需要注意更改this指向,不然指向window
}
})
},100)
}
}
let hx = new Person()
hx.setName('韩信')
hx.growEvent.push(function(){
if(this.age == 18){
console.log('开始参军啦')
}
})
hx.growEvent.push(function(){
if(this.age == 20){
console.log('当上小队长啦')
}
})
上面的这种方式成长事件采用直接Push的方式看着好像有点辣眼睛,那么我们可以添加一个addEventListener方法来帮我们Push
class Person{
constructor(){
this.name = '';
this.age = 0;
this.growup()//不断成长
this.growEvent = []//需要接受多个函数
}
setName(val){
this.name = val
}
growup(){
let _this = this;
setInterval(()=>{
_this.age++;
_this.growEvent.forEach(cb=>{
if(cb instanceof Function){
cb.call(this)//需要注意更改this指向,不然指向window
}
})
},100)
}
addEventListener(cb){
if(cb instanceof Function){
this.growEvent.push(cb)
}
}
}
let hx = new Person()
hx.setName('韩信')
hx.addEventListener(function(){
if(this.age == 18){
console.log('开始参军啦')
}
})
hx.addEventListener(function(){
if(this.age == 20){
console.log('当上小队长啦')
}
})
写到了这里看上去好像有点那啥的样子了。那么,假设成长事件需要一个名字呢?比如,hx,addEventListener("marry",funciton(){})
那我们就需要继续对growEvent继续改装,改成对象形式,每个属性的属性值都是一个数组。
在Push事件,以及执行事件的时候也要更改一下。
class Person{
constructor(){
this.name = '';
this.age = 0;
this.growup()//不断成长
this.growEvent = {}//需要接受多个函数
}
setName(val){
this.name = val
}
growup(){
let _this = this;
setInterval(()=>{
_this.age++;
for(let i in _this.growEvent){
if(_this.growEvent[i] && _this.growEvent[i] instanceof Array){
_this.growEvent[i].forEach(cb=>{
if(cb instanceof Function){
cb.call(this)//需要注意更改this指向,不然指向window
}
})
}
}
},100)
}
addEventListener(name,cb){
if(name && cb instanceof Function){
if(this.growEvent[name]){
this.growEvent[name].push(cb)
}else{
this.growEvent[name] = []
this.growEvent[name].push(cb)
}
}
}
}
let hx = new Person()
hx.setName('韩信')
hx.addEventListener('army',function(){
if(this.age == 18){
console.log('开始参军啦')
}
})
hx.addEventListener('lead',function(){
if(this.age == 20){
console.log('当上小队长啦')
}
})
hx.addEventListener('lead',function(){
if(this.age == 25){
console.log('当上大队长啦')
}
})
那么接下来要做的是如何removeEventListener 呢?一种方式是粗暴的直接清空数组,把多个事件同时清除。
class Person{
constructor(){
this.name = '';
this.age = 0;
this.growup()//不断成长
this.growEvent = {}//需要接受多个函数
}
setName(val){
this.name = val
}
growup(){
let _this = this;
setInterval(()=>{
_this.age++;
for(let i in _this.growEvent){
if(_this.growEvent[i] && _this.growEvent[i] instanceof Array){
_this.growEvent[i].forEach(cb=>{
if(cb instanceof Function){
cb.call(this)//需要注意更改this指向,不然指向window
}
})
}
}
},100)
}
addEventListener(name,cb){
if(name && cb instanceof Function){
if(this.growEvent[name]){
this.growEvent[name].push(cb)
}else{
this.growEvent[name] = []
this.growEvent[name].push(cb)
}
}
}
removeEventListener(name){
if(name && this.growEvent.hasOwnProperty(name)){
this.growEvent[name] = []
}
}
}
let hx = new Person()
hx.setName('韩信')
hx.addEventListener('army',function(){
if(this.age == 18){
console.log('开始参军啦')
}
})
hx.addEventListener('lead',function(){
if(this.age == 20){
console.log('当上小队长啦')
}
})
hx.addEventListener('lead',function(){
if(this.age == 25){
console.log('当上大队长啦')
}
})
hx.removeEventListener('army');
上面这样的话,韩信就不会开始参军了,直接当小队长起步。
但是这样做的话还是有点不好,包括js里的原生事件也是,移除监听的时候,是需要函数名称的。具名函数无论是在回调还是递归里都非常有用。
class Person{
constructor(){
this.name = '';
this.age = 0;
this.growup()//不断成长
this.growEvent = {}//需要接受多个函数
}
setName(val){
this.name = val
}
growup(){
let _this = this;
setInterval(()=>{
_this.age++;
for(let i in _this.growEvent){
if(_this.growEvent[i] && _this.growEvent[i] instanceof Array){
_this.growEvent[i].forEach(cb=>{
if(cb instanceof Function){
cb.call(this)//需要注意更改this指向,不然指向window
}
})
}
}
},100)
}
addEventListener(name,cb){
if(name && cb instanceof Function){
if(this.growEvent[name]){
this.growEvent[name].push(cb)
}else{
this.growEvent[name] = []
this.growEvent[name].push(cb)
}
}
}
removeEventListener(name,cbName){
if(name && this.growEvent.hasOwnProperty(name)){
this.growEvent[name] = this.growEvent[name].filter(cb=>{
return cb != cbName
})
}
}
}
let hx = new Person()
hx.setName('韩信')
hx.addEventListener('army',function(){
if(this.age == 18){
console.log('开始参军啦')
}
})
hx.addEventListener('lead',fn)
function fn(){
if(this.age == 20){
console.log('当上小队长啦')
}
}
hx.addEventListener('lead',function(){
if(this.age == 25){
console.log('当上大队长啦')
}
})
hx.removeEventListener('lead',fn);
这样的话,韩信就没有当小队长这个过程啦!
写一个addEventListener以及removeEventListener的更多相关文章
- 事件监听addEventListener()和removeEventListener() ---------1
一直想写一个原生事件监听的记录,方便以后看,不愿意写主要是事件监听的单词太长,记起来好难记每次都要查,这次把知道的写完了,来这里查好了,以后要是理解的更透彻了,就再补全好了 首先,DOM0级事件和DO ...
- (转)addEventListener()与removeEventListener()详解
转自:http://www.111cn.net/wy/js-ajax/48004.htm addEventListener()与removeEventListener()用于处理指定和删除事件处理程序 ...
- 如何写一个跨浏览器的事件处理程序 js
如何 写一个合格的事件处理程序,看如下代码: EventUtil可以直接拿去用 不谢 <!DOCTYPE html> <html> <head> <title ...
- addEventListener()与removeEventListener(),追加事件和删除追加事件
addEventListener()与removeEventListener()用于追加事件和删除追加.所有的DOM节点中都包含这两种方法,并且它们都接受3个参数:要处理的事件名.作为事件处理程序的函 ...
- 手写一个虚拟DOM库,彻底让你理解diff算法
所谓虚拟DOM就是用js对象来描述真实DOM,它相对于原生DOM更加轻量,因为真正的DOM对象附带有非常多的属性,另外配合虚拟DOM的diff算法,能以最少的操作来更新DOM,除此之外,也能让Vue和 ...
- 兼容8事件绑定与解绑addEventListener、removeEventListener和ie的attachEvent、detachEvent
兼容8事件绑定与解绑addEventListener.removeEventListener和ie的attachEvent.detachEvent ;(function(){ // 事件绑定 bi ...
- 分享:计算机图形学期末作业!!利用WebGL的第三方库three.js写一个简单的网页版“我的世界小游戏”
这几天一直在忙着期末考试,所以一直没有更新我的博客,今天刚把我的期末作业完成了,心情澎湃,所以晚上不管怎么样,我也要写一篇博客纪念一下我上课都没有听,还是通过强大的度娘完成了我的作业的经历.(当然作业 ...
- js高级程序设计笔记之-addEventListener()与removeEventListener(),事件解除与绑定
js高级程序设计笔记之-addEventListener()与removeEventListener(),事件解除与绑定 addEventListener()与removeEventListener( ...
- 用vue写一个仿app下拉刷新的组件
如果你用vue弄移动端的页面,那么下拉刷新还是比较常见的场景,下面来研究如何写一个下拉刷新的组件(先上图); 由于节省大家的时间,样式就不贴出来了. html结构也不必介绍了,直接看代码吧-.- &l ...
随机推荐
- mysql主从数据库错误处理
方法一:忽略错误后,继续同步 该方法适用于主从库数据相差不大,或者要求数据可以不完全统一的情况,数据要求不严格的情况 解决: stop slave; #表示跳过一步错误,后面的数字可变set glob ...
- 织梦dede模板中调用会员信息标签的方法
织梦CMS v5.7调用文章所属会员信息标签 打开官方默认模板article_artcile.htm,我们可以提取出如下代码: {dede:memberinfos} 会员头像:<a href=& ...
- wampserver启动时图标不变绿的解决方法
有2种可能: 1.你安装wamp的时候安装路径中有中文,把路径全部改为英文. 2.其他软件占用了80端口号,解决方法是在服务中找微软的sql server或者其他服务,关掉服务后重启就行了.
- Quartz使用(1) - 初识quartz
1. 背景 由于最新的工作项目中,需要使用quartz框架,以完成相关的任务的定时执行.经过两周的调研与使用,本系列博客会参考官网及网上相关博客,结合工作项目中的使用,详细介绍quartz的各个方面. ...
- 【补充】docker基础学习
docker 基础知识 之前写了一篇docker未授权访问的文章,现在来补充一下docker基础知识,以便更好的学习docker上的漏洞. docker是一款轻量级的虚拟化的产品,它属于层级化的架构. ...
- c#ArrayList 对象集合 按某字段(属性)排序
主程序代码 newsCompare newsCompare = new ItemManage.newsCompare(); newsList.Sort(newsCompare); 自定义类代码(按照C ...
- Python数据报协议以及sockersever模块的使用
一.基于UDP协议的套接字 UDP协议 UDP 是User Datagram Protocol的简称, 中文名是用户数据报协议,是OSI(Open System Interconnection,开放式 ...
- 学习路线 roadmap
我的学习路线为HTML > CSS > Javsscript:Javascript是前端一切学习的基础.HTML和css一起学习. JavaScript基础: Js基础教程.js内置对象常 ...
- CST,CET,UTC,GMT,DST,Unix时间戳几种常见时间概述与关系
1.UTC: Universal Time Coordinated 协调世界时,又称世界标准时间 多数的两地时间表都以GMT来表示,但也有些两地时间表上看不到GMT字样,出现的反而是UTC这3个英文字 ...
- artTemplate教程
artTemplate教程 官方文档 一个简单的例子 <!DOCTYPE html> <html lang="zh"> <head> <m ...