题目1: DOM0 事件和DOM2级在事件监听使用方式上有什么区别?
在DOM0
级处理程序,事件名以on
开头,比如click
事件处理程序就是onclick
,load
事件就是onload
。
通过js来添加DOM0事件处理程序时,首先要获得一个要操作对象的引用,然后通过其事件处理程序属性(这些属性通常全部小写),指定事件处理程序。
var btn = document.getElementById("myBtn");
btn.onclick = function(){
alert('call o'clock event');
}
DOM0
级事件处理程序可以认为是元素的方法。删除DOM0
级事件处理程序,将相应属性设置null
即可。
btn.onclick = null;
DOM2中定义了两个方法addEventListener()
和removeEventListener()
,分别用于添加事件处理程序和删除处理程序。
二者区别:
使用DOM2级方法添加事件处理程序的主要好处是可以添加多个事件处理程序,而DOM0级为一个事件添加多个事件处理程序时,后面的程序会覆盖前面的。
题目2: attachEvent与addEventListener的区别?
在早起的IE浏览器中没有实现addEventListener()和removeEventListener(),但提供了两个替代方法attachEvent()和detachEvent()。
attachEvent与addEventListener的区别:
- 参数个数不相同。addEventListener有三个参数,attachEvent有两个参数,attachEvent添加的事件处理程序只能发生在冒泡阶段,addEventListener第三个参数可以决定添加的事件处理程序是在捕获阶段还是在冒泡阶段处理
- 第一个参数意义不同,addEventListener第一个参数是事件类型(比如click, load),而attachEvent第一个参数指明的是事件处理函数的名称(onclick, onload)
- 事件处理程序的作用域不同,addEventListener的作用域是元素本身,this指的是触发元素,attachEvent事件处理程序会在全局变量内运行,this是window。
- 为一个事件添加多个事件处理程序时,执行顺序不同,addEventListener添加会按照添加顺序执行,而attachEvent添加多个事件处理程序时顺序无规律。
题目3: 解释IE事件冒泡和DOM2事件传播机制?
事件冒泡:子元素嵌套在父元素内部,点击子元素的时候一定同时表示点击了父元素,这个时候,先触发子元素的事件处理器,然后再触发父元素的事件处理器,如果父元素的父元素还有处理器,就一直向上触发,一直到 body 元素。就像鱼吐泡泡一样,从水下向水面走,每向上走一层就会查看这一层有没有事件处理器,如果有的话就会触发,如果没有的话就继续向上寻找,直到顶层的 body,才结束寻找事件。
DOM2级事件流,总共分为三个阶段:事件捕获, 目标元素,事件冒泡。DOM 2级规范将事件捕获和事件冒泡都收入自己的囊中,所以你可以在一个元素上同时注册事件捕获和事件冒泡,也就是说你可以选择父级元素事件处理器后触发,也可以选择先触发,甚至可以选择先触发父级元素的捕获事件,再触发父级元素的冒泡事件。可以通过设置addEventListener第三个参数来控制。
题目4:如何阻止事件冒泡? 如何阻止默认事件?
document.querySelector('a').onclick= function(e){
e.preventDefault() //阻止默认事件
e.stopPropagation() //阻止事件进一步捕获或冒泡
console.log(this.href)
}
题目5:有如下代码,要求当点击每一个元素li时控制台展示该元素的文本内容。不考虑兼容
<ul class="ct">
<li>这里是</li>
<li>饥人谷</li>
<li>前端6班</li>
</ul>
<script>
var lists = document.querySelectorAll('.ct>li');
lists.forEach(function(list){
list.addEventListener('click', function(){
console.log(this.innerText);
});
});
</script>
题目6: 补全代码,要求:
- 当点击按钮开头添加时在<li>这里是</li>元素前添加一个新元素,内容为用户输入的非空字符串;当点击结尾添加时在最后一个 li 元素后添加用户输入的非空字符串.
- 当点击每一个元素li时控制台展示该元素的文本内容。
<ul class="ct">
<li>这里是</li>
<li>饥人谷</li>
<li>任务班</li>
</ul>
<input class="ipt-add-content" placeholder="添加内容"/>
<button id="btn-add-start">开头添加</button>
<button id="btn-add-end">结尾添加</button>
<script>
var lists = document.querySelector('.ct');
var input = document.querySelector('.ipt-add-content');
document.getElementById('btn-add-start').addEventListener('click', function() {
var addLi = document.createElement('li');
addLi.innerText = input.value;
if (input.value != '') {
lists.insertBefore(addLi, lists.firstChild);
}
})
document.getElementById('btn-add-end').addEventListener('click', function() {
var addLi = document.createElement('li');
addLi.innerText = input.value;
if (input.value != '') {
lists.appendChild(addLi);
}
})
lists.addEventListener('click', function(e) {
if(e.target.tagName.toLowerCase() === 'li') {
console.log(e.target.innerText);
}
});
</script>
7. 补全代码,要求:当鼠标放置在li元素上,会在img-preview里展示当前li元素的data-img对应的图片。
<ul class="ct">
<li data-img="1.png">鼠标放置查看图片1</li>
<li data-img="2.png">鼠标放置查看图片2</li>
<li data-img="3.png">鼠标放置查看图片3</li>
</ul>
<div class="img-preview"></div>
<script>
var lists = document.querySelectorAll('.ct>li');
var imgDisplay = document.querySelector('.img-preview');
lists.forEach(function(list){
list.addEventListener('mouseenter', function(){
var url = this.getAttribute('data-img');
var img = document.createElement('img');
img.setAttribute('src', url);
imgDisplay.appendChild(img);
})
})
</script>