1. DOM0 事件和DOM2级在事件监听使用方式上有什么区别?
- DOM0事件监听:Dom0级事件处理程序是将一个函数赋值给一个事件处理程序属性,而通过将事件处理程序设置为null删除绑定在元素上的事件处理程序。这种方法无法给一个事件添加多个事件处理程序,后面的程序会覆盖前面的程序。
<script>
//指定时间处理程序
var btn = document.querySelector("#btn");
btn.onclick = function()
{
alert(this.id)
};
//删除事件处理程序
btn.onclick= null;
</script>
- DOM2事件监听:而Dom2级定addEventListener()removeEventListener()
用于处理指定和删除事件处理程序。所有Dom节点都包含这两个方法,并且它们都接受3个参数,要处理的事件名、作为事件处理程序的函数和一个布尔值。最后这个布尔值参数如果是true,表示在捕获阶段调用事件处理程序;如果是false,表示在冒泡阶段调用事件处理程序。
<script>
var btn = document.querySelector("#btn");
var handle = function()
{
alert(this.id);
}
//指定事件处理程序
btn.addEventListener("click", handle,false);
//删除事件处理程序
btn.removeEventListener("click",handle,false);
</script>
注意:removeEventListener()函数来移除事件处理程序时,移除时的参数必须与添加处理程序时使用的参数相同,这也意味着通过addEventListener()添加的匿名函数将无法移除.(只能用上面的方法写)如:
<script>
var btnClick = document.getElementById('btnClick');
btnClick.addEventListener('click', function() {
alert(this.id);
}, false);
btnClick.addEventListener('click', function() {
alert('Hello!');
}, false);
//无法移除
btnClick.removeEventListener('click',function(){
},fasle)
</script>
区别:使用Dom2级方法添加事件处理程序的主要好处是可以添加多个事件处理程序,而Dom0级为一个事件添加多个事件处理程序时,后面的程序会覆盖前面的。
2. attachEvent与addEventListener的区别?
在添加事件处理程序时addEventListener和attachEvent(ie)主要有几个区别
1. 参数个数不相同,这个最直观,addEventListener有三个参数,attachEvent只有两个,attachEvent添加的事件处理程序只能发生在冒泡阶段,addEventListener第三个参数可以决定添加的事件处理程序是在捕获阶段还是冒泡阶段处理(我们一般为了浏览器兼容性都设置为冒泡阶段)
2. 第一个参数意义不同,addEventListener第一个参数是事件类型(比如click,load),而attachEvent第一个参数指明的是事件处理函数名称(onclick,onload)
3. 事件处理程序的作用域不相同,addEventListener的作用域是元素本身,this是指的触发元素,而attachEvent事件处理程序会在全局变量内运行,this是window,而不是元素id
4. 为一个事件添加多个事件处理程序时,执行顺序不同addEventListener添加会按照添加顺序执行,而attachEvent添加多个事件处理程序时顺序无规律(添加的方法少的时候大多是按添加顺序的反顺序执行的,但是添加的多了就无规律了),所以添加多个的时候,不依赖执行顺序的还好,若是依赖于函数执行顺序,最好自己处理,不要指望浏览器
3. 解释IE事件冒泡和DOM2事件传播机制?
1.IE的事件流叫做事件冒泡(event bubbling),即事件开始时由最具体的元素接收,然后逐级向上传播到较为不具体的节点(文档)
2.Netscape的事件捕获(event capturing):不太具体的节点更早接收事件,而最具体的元素最后接收事件,和事件冒泡相反
3.DOM事件流:DOM2级事件规定事件流包括三个阶段,事件捕获阶段,处于目标阶段,事件冒泡阶段,最先发生的是事件捕获,为截取事件提供机会,然后是实际目标接收事件,最后是冒泡阶段(如图)
4. 如何阻止事件冒泡? 如何阻止默认事件?
- 阻止事件冒泡:
<script>
var stopPropagation= function(event){
if(event.stoppropagation()){
event.stopPropagation();
}else{
event.cancelBubble = true;
}
}//兼容ie
</script>
- 阻止默认事件:
<script>
var preventDefault= function(event){
if(event.preventDefault()){
event.preventDefault();
}else{
event.returnValue= false;
}
}//兼容ie
</script>
代码练习
要求当点击每一个元素li时控制台展示该元素的文本内容。不考虑兼容
代码1补全代码,要求:当点击按钮开头添加时在li这里是</li>元素前添加一个新元素,内容为用户输入的非空字符串;当点击结尾添加时在li前端6班/li后添加用户输入的非空字符串.当点击每一个元素li时控制台展示该元素的文本内容。
代码2要求:当鼠标放置在li元素上,会在img-preview里展示当前li元素的data-img对应的图片。
代码3在 github 上创建个人项目,把视频里事件兼容的函数写法放入项目,在 Readme.md里描述项目(选做题目)
<body>
<script type="text/javascript">
function addEvent(node, type, fn) {
if (!node) return false;
if (node.addEventListener) {
node.addEventListener(type, fn, false);
return true;
}
else if (node.attachEvent) {
node['e' + type + fn] = fn;
node[type + fn] = function() {
node['e' + type + fn](window.event);
};
node.attachEvent('on' + type, node[type + fn]);
return true;
}
return false;
}
function removeEvent(node, type, fn) {
if (!node) return false;
if (node.removeEventListener) {
node.removeEventListener(type, fn, false);
return true;
}
else if (node.detachEvent) {
node.detachEvent('on' + type, node[type + fn]);
node[type + fn] = null;
}
return false;
}
</script>
</body>
addEvent
如果是支持标准浏览器事件addEventListener则使用该函数添加监听事件,否则是否支持IE的attachEvent事件如果支持则使用该函数,两者都不支持则return退出。
removeEvent
如果是支持标准浏览器事件removeEventListener则使用该函数移除监听事件,否则是否支持IE的datachEvent事件如果支持则使用该函数,两者都不支持则return退出。