例子html
若是想要用户点击按钮就能打印“hello world”,html中的格式该如何写?在A、B、C之间不定项选择 若是想要用户点击按钮就能打印“hello world”,js中的格式应该如何写?在X、Y、Z之间不定项选择程序员
答案: B、C 和 X编程
注意数组
不能觉得html中怎么写js中就应该怎样写,它们是2种不一样的语言浏览器
在html中onclick到底再作什么? ---> onclick = "要执行的代码",一旦用户点击,浏览器就eval("要执行的代码"),若是再控制台eval('print')和直接在控制台中写print没有任何的区别,若是要执行print还须要在后面加括号print()或者print.call()数据结构
在js中一旦用户点击,那么浏览器就帮咱们执行(以X为例子)调用函数 X.onclick.call(函数里面的this,函数的arguments[0]),因此X.onclick的返回类型必定为函数,那么X.onclick = print
中的print的类型为函数对象就能对上了,然而Y.onclick = print()
中的print()
它的返回类型是undefined,因此选择Y是错的。一样的Z.onclick = print.call()
中的print.call()
它的返回类型也为undefined,因此Z也是错的。即在html中是须要加()的由于须要的是要执行代码,在js中是不要加()的由于须要的是函数,不须要调用它,须要等浏览器去调用它函数
做为程序员必定要关注返回的数据类型而不是用眼睛去编程this
Dom Leveal2中的写法:code
实例cdn
xxx.addEventListener()
和xxx.onclick = function(){}
这种形式的区别是什么?
注意
后者只是元素的一个属性而已,一个元素只有一个onclick属性。一旦给这个元素绑定2个onclick属性那就完了,最后写的会覆盖以前写的,若是是多人合做的项目,别人也用onclick监听了该元素,那么就不敢轻易的给元素加onclick属性,万一不当心覆盖了别人的代码,这样就很不友好了!
前者就不会出现这种问题了,它属于数据结构中的队列,先进先出,叫事件监听队列
运行结果为打印2,事件监听队列,就是数据结构中的队列,先进先出,回顾一下整个过程:
首先是f1进入队列,而后是f2进入队列,而后f1又离开了队列,而后f3又进入队列,而后f3又离开了队列,最后只剩下f2在队列中了
以上就是.one()
内部实现的原理,进入队列一次,执行完代码后又当即移出事件监听队列,因此使用.one()
进行一次事件监听后第二次再怎么点都没反应了,由于它已经不在事件监听队列中了,一旦没有btn.removeEventListener('click',f1)
这句话,持续的点击按钮会一直的输出打印1
总结:
事件队列模型:
不一样的事件有不一样的事件队列,click有click本身的队列,mouseenter有它本身的队列,它们站本身的队 ,先进的先出,队列能够理解我数组,每次add就向这个数组容器里添加一个函数,每次remove就向这个 数组删除一个数,当用户触发事件的时候就会依次的按照进入数组(队列)的顺序调用一遍,remove就是不 想处理这个事件,就从事件队列(数组)中离开
容器里添加一个函数
Q1:当点击儿子的时候是否点击了爸爸和爷爷
答案是yes
Q2:当点击儿子的时候,3个函数是否调用
答案是yes
Q3:请问f1,f2,f3的执行顺序
w3c:均可以
Q4:不传第三个参数或者传false
执行顺序:儿子--->爸爸--->爷爷
几个falsy值: 0 NaN '' null undefined false
Q5: 传第三个参数为true
执行顺序: 爷爷 ---> 爸爸 ---> 儿子
先捕获再冒泡
若是捕获阶段有插入函数就调用函数,若是没有插入函数就不调用函数;
冒泡阶段也是同样,若是有插入函数就调用函数,若是没有插入函数就不调用函数;
那么如何知道插入的是捕获阶段仍是冒泡阶段呢?
就是经过第三个参数true或false来选择,若是传的是false,就跑到右边的冒泡阶段,若是传的是true就
跑到左边的捕获阶段
一个特殊状况要单独记:
若是被点击的元素既有捕获阶段又有冒泡阶段,那么最终的执行顺序是书写的顺序去执行