1. DOM0 事件和DOM2级在事件监听使用方式上有什么区别?
- 监听阶段不一样。DOM0级事件的过程:捕获-事件目标,或者事件目标-冒泡。而DOM2级事件的过程:捕获-事件目标-冒泡,或者冒泡-事件目标-捕获。
- 监听方式是否能够改变。DOM0事件无法改变自身的事件过程属于哪一类,只能是根据浏览器的特性来决定。而DOM2级事件多了一个参数,默认为false,执行捕获-事件目标-冒泡。当为true的时候,执行冒泡-事件目标-捕获。
- DOM0事件兼容性较好,但因为写在HTML中,造成HTML和JS的耦合,对维护和修改代码不利,所以一般不使用DOM0而是DOM2。
- DOM0事件将一个方法赋值给元素处理程序的属性,所以这个处理程序是在全局作用域内,这个就决定了它在全局的作用域内只会触发一次,如果有多个相同的处理程序的属性,后者会覆盖前者。而DOM2事件的作用域是元素本身,只要你在不同的元素作用域内,就会分别触发事件,然后执行相应的函数,并且因为这个特性,他可以多次监听,监听的顺序根据它的排列顺序从上到下。例如:
DOM0事件:
<input id="btnClick" type="button" value="Click Here" />
<script>
var btnClick = document.querySelector('#btnClick');
btnClick.onclick = function showMessage() {
alert(this.id);
};
btnClick.onclick = function showMessage() {
alert(this.value);
};
/*
该事件只会执行第二个onclick,输出<input id="btnClick" type="button" value="Click Here" />
*/
</script>
DOM2级事件:
var btnClick = document.querySelector('#btnClick');
btnClick.addEventListener('click',function () {
alert(this.id);
},false);
btnClick.addEventListener('click',function () {
alert(this.value);
},false);
/*
上述两个事件按照先后顺序依次执行。
*/
2.attachEvent与addEventListener的区别?
- 参数不一样, addEventListener多了一个参数,默认为false,执行捕获-事件目标-冒泡。当为true的时候,执行冒泡-事件目标-捕获。attachEvent默认只使用冒泡。
- 第一个参数意义不同,attachEvent使用的是事件函数名称(比如onclick , onmouseover),addEventListener使用的是事件类型(比如click , mouseover)。
- 作用域不同,attachEvent的事件处理程序作用于全局变量,所以this返回undefined而不是元素id。addEventListener作用于元素本身。例如:
- 为一个事件添加多个执行程序时,attachEvent会无序执行,addEventListener会依次添加顺序执行。
3.解释IE事件冒泡和DOM2事件传播机制?
- IE事件冒泡:事件开始时从最具体的元素开始,然后逐级向上传播到较为不具体的元素。
- DOM2事件有三个阶段,捕获-目标事件-冒泡,一开始发生事件捕获,为截取事件提供机会,然后目标接收事件,然后冒泡执行。
4.如何阻止事件冒泡? 如何阻止默认事件?
- stopPropagation()阻止事件进一步捕获或者冒泡
- preventDefault()阻止默认事件的行为
stopPropagation()示例代码如下:
<input id="btnClick" type="button" value="Click Here">
<script>
var btnClick = document.getElementById('btnClick');
btnClick.addEventListener('click',function (e) {
alert(e.type);
e.stopPropagation();
});
var body = document.body;
body.addEventListener('click',function() {
alert('sdfdsfdsf');
});
/*因为冒泡被阻止了,所以body侦听不到click这个事件类型,所以body没有弹窗*/
</script>
preventDefault()示例代码如下:
<a href="//jirengu.com/" id="aClick">饥人谷</a>
<script>
var aClick = document.getElementById('aClick');
aClick.addEventListener('click',function (e) {
e.preventDefault();
});
/*因为阻止了aClick的默认事件,所以点击页面不跳转*/
</script>
5.有如下代码,要求当点击每一个元素li时控制台展示该元素的文本内容。不考虑兼容
<ul class="ct">
<li>这里是</li>
<li>饥人谷</li>
<li>前端6班</li>
</ul>
<script>
var ul = document.querySelector('ul');
ul.addEventListener('click',function (e) {
if(e.target && e.target.nodeName.toLowerCase() == 'li'){
console.log(e.target.innerText);
}
});
</script>
6.补全代码,要求:
- 当点击按钮开头添加时在
<li>这里是</li>
元素前添加一个新元素,内容为用户输入的非空字符串;当点击结尾添加时在最后一个 li 元素后添加用户输入的非空字符串. - 当点击每一个元素li时控制台展示该元素的文本内容。
<ul class="ct">
<li>这里是</li>
<li>饥人谷</li>
<li>前端6班</li>
</ul>
<input class="ipt-add-content" placeholder="添加内容"/>
<button id="btn-add-start">开头添加</button>
<button id="btn-add-end">结尾添加</button>
<script>
var ul = document.querySelector('ul');
var iptCont = document.querySelector('.ipt-add-content');
var btnStart = document.querySelector('#btn-add-start');
var btnEnd = document.querySelector('#btn-add-end');
btnStart.addEventListener('click',function () {
if(iptCont.value){
var li = document.createElement('li');
li.innerText = iptCont.value;
ul.insertBefore(li,ul.firstChild);
}
});
btnEnd.addEventListener('click',function () {
if(iptCont.value){
var li = document.createElement('li');
li.innerText = iptCont.value;
ul.appendChild(li);
}
});
ul.addEventListener('click',function (e) {
if(e.target && e.target.nodeName.toLowerCase() == 'li'){
console.log(e.target.innerText);
}
});
</script>
7.补全代码,要求:当鼠标放置在li元素上,会在img-preview里展示当前li元素的data-img对应的图片。
<ul class="ct">
<li data-img="http://cdn.jirengu.com/book.jirengu.com/img/11.jpg">鼠标放置查看图片1</li>
<li data-img="http://cdn.jirengu.com/book.jirengu.com/img/13.jpg">鼠标放置查看图片2</li>
<li data-img="http://cdn.jirengu.com/book.jirengu.com/img/14.jpg">鼠标放置查看图片3</li>
</ul>
<div class="img-preview"></div>
<script>
var ul = document.querySelector('ul');
var div = document.querySelector('div');
ul.addEventListener('mouseover',function (e) {
var dataImg = e.target.getAttribute('data-img');
div.innerHTML = '![]('+dataImg+')';
});
</script>