javascript和html的交互是通过事件实现的
1.dom文档对象模型是树形结构
事件流
描述从页面中接收对象的顺序。
事件流包括三个阶段:事件捕获阶段,处于目标阶段,事件冒泡阶段。如下图
2.事件捕获阶段是从不太具体的节点(window)逐级向下传播到最具体的元素(为截获事件提供了机会)。然后是实际的目标接收到事件。最后通过事件冒泡对事件做出响应并一级一级向上传回到window(根节点)
3.阻止事件冒泡主要是通过preventDefault()取消事件的默认行为,stopPropagation()取消事件的进一步捕获或冒泡。
4.事件冒泡的应用是事件代理,利用事件冒泡,只指定一个事件处理程序,就可以管理某一类型的所有事件。
事件代理的优点:1.代码简洁 2.减少浏览器内存占用
5.页面上有这么一个节点树,div>ul>li>a;比如给最里面的a加一个click点击事件,那么这个事件就会一层一层的往外执行,执行顺序a>li>ul>div,有这样一个机制,那么我们给最外面的div加点击事件,那么里面的ul,li,a做点击事件的时候,都会冒泡到最外层的div上,所以都会触发,这就是事件委托,委托它们父级代为执行事件。
6.为什么要用事件委托:
1.减少事件数量
2.避免内存外泄
3.预测未来元素
在JavaScript中,添加到页面上的事件处理程序数量将直接关系到页面的整体运行性能,因为需要不断的与dom节点进行交互,访问dom的次数越多,引起浏览器重绘与重排的次数也就越多,就会延长整个页面的交互就绪时间,这就是为什么性能优化的主要思想之一就是减少DOM操作的原因;如果要用事件委托,就会将所有的操作放到js程序里面,与dom的操作就只需要交互一次,这样就能大大的减少与dom的交互次数,提高性能;
7.适合用事件委托的事件:click,mousedown,mouseup,keydown,keyup,keypress。
<ul id="ul1">
<li>111</li>
<li>222</li>
<li>333</li>
<li>444</li>
</ul>
window.onload = function(){
var oUl = document.getElementById("ul1");
var aLi = oUl.getElementsByTagName('li');
for(var i=0;i<aLi.length;i++){
aLi[i].onclick = function(){
alert(123);
}
}
}
window.onload = function(){
var oUl = document.getElementById("ul1");
oUl.onclick = function(){
alert(123);
}
}
Event对象提供了一个属性叫target,可以返回事件的目标节点,我们成为事件源,也就是说,target就可以表示为当前的事件操作的dom,但是不是真正操作dom,当然,这个是有兼容性的,这里我们用nodeName来获取具体是什么标签名,这个返回的是一个大写的,我们需要转成小写再做比较(习惯问题):
window.onload = function(){
var oUl = document.getElementById("ul1");
oUl.onclick = function(ev){
var ev = ev || window.event;
var target = ev.target || ev.srcElement;
if(target.nodeName.toLowerCase() == 'li'){
alert(123);
alert(target.innerHTML);
}
}
}
<div id="box">
<input type="button" id="add" value="添加" />
<input type="button" id="remove" value="删除" />
<input type="button" id="move" value="移动" />
<input type="button" id="select" value="选择" />
</div>
window.onload = function(){
var oBox = document.getElementById("box");
oBox.onclick = function (ev) {
var ev = ev || window.event;
var target = ev.target || ev.srcElement;
if(target.nodeName.toLocaleLowerCase() == 'input'){
switch(target.id){
case 'add' :
alert('添加');
break;
case 'remove' :
alert('删除');
break;
case 'move' :
alert('移动');
break;
case 'select' :
alert('选择');
break;
}
写一个通用的事件绑定
function bindEvent(elem,type,selector,fn){
if(fn==null){
fn=selector;
selector=null;}
elem.addEventListener(type,function(e){
var target;
if(selector){target=e.target; //代理
if(target.matches(selector))
{fn.call(target,e)}
}else{fn(e);
}
})
}
事件处理程序
对事件进行响应的函数就叫事件处理程序。
事件对象函数中的局部变量event.通过event变量,可以直接访问事件对象。在这个函数内部,this的值等于事件的目标元素。
可以通过HTML指定事件处理程序(不推荐)
可以通过JS指定事件处理程序
DOM0级事件处理程序:
var btn=document.getElementById("mybtn");
btn.onclick=function(){
alert(this,id); //this为当前元素,mybtn,可以通过this访问元素的任何属性和方法。
btn.onclick=null;//删除事件处理程序
};
DOM2级事件处理程序:
addEventListener(),removeEventListener()(true,在捕获阶段调用事件处理程序,false,在冒泡阶段调用事件处理程序)
var btn=document.getElementById("mybtn");
btn.addEventListener("click",function(){ //匿名函数无法移除
alert(this.id);},false);
var btn=document.getElementById("mybtn");
var hander=function(){alert(this.id);};
btn.addEventListener("click",hander,false);
btn.removeEventListener("click",hander,false);
事件对象
在触发DOM上的某个事件,会产生事件对象event,这个对象中包含了所有与事件有关的信息。包括导致事件的元素,事件的类型,其他与特定事件相关的信息。
event对象包含与创建它的特定事件有关的属性和方法。
preventDefault()取消事件的默认行为
stopPropagation()取消事件的进一步捕获或冒泡。
属性:currentTarget当前正在处理事件的那个元素(this始终等于currentTarget的值)target:事件的目标 type被触发事件的类型。
事件类型
UI事件(load unload resize scroll) 焦点事件 鼠标事件 滚轮事件 文本事件 键盘事件 合成事件
JS的错误有几种
Load time errors加载网页时,语法错误等状况,称为加载时间错误。动态生成错误
Runtime errors在HTML中滥用命令导致的错误
Logical errors在具有不同操作的函数上执行了错误逻辑发生的错误
onload 和document.onready
window.onload是js原生的事件,(function())是Jquery的方法(等价于(function(){})是Jquery的方法(等价于(function())是Jquery的方法(等价于(document).ready(function(){})),两者主要有以下几点差别:
1、window.onload:在页面所有资源加载完后执行,如果有多个定义则只执行最后一个
2、(function()):在Dom节点创建完成后执行,如果有多个定义则依次执行可以看出(function(){}):在Dom节点创建完成后执行,如果有多个定义则依次执行
可以看出(function()):在Dom节点创建完成后执行,如果有多个定义则依次执行可以看出(function(){})在window.onload前执行
事件绑定和普通事件有什么区别
普通添加事件的方法:
var btn = document.getElementById("hello");
btn.onclick = function(){
alert(1);
}
btn.onclick = function(){
alert(2);//执行上面的代码只会alert 2
}
事件绑定方式添加事件:
var btn = document.getElementById("hello");
btn.addEventListener("click",function(){
alert(1);
},false);
btn.addEventListener("click",function(){
alert(2);
},false);执行上面的代码会先alert 1 再 alert 2
普通添加事件的方法不支持添加多个事件,不支持DOM事件流,最下面的事件会覆盖上面的,而事件绑定(addEventListener)方式添加事件可以添加多个。支持DOM事件流的,进行事件绑定传参不需要on前端
IE和DOM事件流的区别
1.执行顺序不一样,IE采用冒泡型事件, DOM使用先捕获后冒泡型事件
2.函数不一样.事件监听函数不一样。IE9以前:attachEvent(“onclick”)、detachEvent(“onclick”)DOM事件流是addEventListener
3.事件加不加on
4.this指向问题
25、当一个DOM节点被点击时候,我们希望能够执行一个函数,应该怎么做?
直接在DOM里绑定事件:
在JS里通过onclick绑定:xxx.onclick = test
通过事件添加进行绑定:addEventListener(xxx, ‘click’, test)