题目1: DOM0 事件和DOM2级在事件监听使用方式上有什么区别?
<body>
<input id="btn1" type="button" value="DOM0事件">
<input id="btn2" type="button" value="DOM2事件">
<script>
// 以点击事件为例
// DOM0 级
var oBtn1 = document.getElementById("btn1");
oBtn1.onclick = function() {
console.log("点击一下");
}
oBtn1.onclick = function() {
console.log("再次点击一下");
}
/* 如上面这样写的话,控制台最后显示的是"再次点击一下", "点击一下"被覆盖掉了。 */
oBtn1.onclick = null; // 取消点击事件
// DOM2 级
/* addEventListener 和 removeEventListener
它们接受三个参数: (1) 事件类型 (2)事件处理方法 (3)布尔参数,如果是true表示在捕获阶段调用事件处理程序,如果是false则是在事件冒泡阶段处理。*/
var oBtn2 = document.getElementById("btn2");
oBtn2.addEventListener('click', function() {
console.log("点击一下");
}, false);
oBtn2.addEventListener('click', function() {
console.log("再次点击一下");
}, false);
/* 点击DOM2事件按钮,控制台显示"点击一下", "再次点击一下"。*/
/* 当移除事件处理程序的时候可以这样写 */
var handler = function() {
alert(this.id);
}
oBtn2.addEventListener('click', handler, false);
oBtn2.removeEventListener('click', handler, false); // 移除处理程序
</script>
</body>
题目2: attachEvent与addEventListener的区别?
<body>
<input id="btn" type="button" value="点我">
<script>
/* IE并不支持addEventListener和removeEventListener方法,而是实现了两个类似的方法
(1) attachEvent
(2) detachEvent
这两个方法都接收两个相同的参数(1)事件处理程序名称 (2) 事件处理程序方法
IE6~10 支持, IE11就不再支持了。 同时addEventListener被支持IE9+
*/
var oBtn = document.getElementById('btn');
var handler = function() {
alert("hello world");
}
oBtn.attachEvent('onclick', handler); // 注意是带on的。
oBtn.detachEvent('onclick', handler);
</script>
</body>
主要几个区别
1、 参数个数不相同
2、 第一个参数意义不同
3、 事件处理程序的作用域不相同, addEventListener的作用域是元素本身,this是指的触发元素,而attachEvent事件处理程序会在全局变量内运行,this是window。
4、 为一个事件添加多个事件处理程序时,执行顺序不同,addEventListener添加会按照
添加顺序执行,而attachEvent添加多个事件处理程序时顺序无规律(添加的方法少的时候大多是按添加顺序的反顺序执行的,但是添加的多了就无规律了),所以添加多个的时候,不依赖执行顺序的还好,若依赖于函数执行顺序,最好自己处理,不要指望浏览器。
题目3: 解释IE事件冒泡和DOM2事件传播机制?
IE事件冒泡: 即事件最开始由最具体的元素(文档中嵌套层次最深的那个节点)接受,然后
逐级向上传播至最不具体的那个节点(文档)。
DOM2级事件规定事件流包括三个阶段: 事件捕获阶段,处于目标阶段和事件冒泡阶段。首先发生的是事件捕获,为截获事件提供了机会。然后是实际的目标接受到事件。最后一个阶段是冒泡阶段。
举列说明
<style>
.container {
width: 200px;
height: 200px;
border: 1px solid #aaa;
}
.box {
height: 100px;
background: red;
}
</style>
<body class="body">
<div class="container">
<div class="box">
<button class="btn">点我</button>
</div>
</div>
<script>
function handler() {
console.log(this.className);
}
// 事件冒泡
document.body.addEventListener('click', handler, false);
document.querySelector('.container').addEventListener('click', handler, false);
document.querySelector('.box').addEventListener('click', handler, false);
document.querySelector('.btn').addEventListener('click', handler, false);
// 控制台依次显示 "btn" "box" "container" "body"
// 可以看出事件在一级一级的向上冒泡。
// 事件捕获 将 false 替换成 true。
document.body.addEventListener('click', handler, true);
document.querySelector('.container').addEventListener('click', handler, true);
document.querySelector('.box').addEventListener('click', handler, true);
document.querySelector('.btn').addEventListener('click', handler, true);
// 这个时候控制台依次显示 "body" "container" "box" "btn" 从最不具体的到最为具体的
</script>
</body>
题目4:如何阻止事件冒泡? 如何阻止默认事件?
function stopPropagation(e) {
if(e.stopPropagation)
e.stopPropagation();
else
e.cancelBubble = true; // 兼容IE
}
function preventDefault(e) {
if(e.preventDefault)
e.preventDefault();
else
e.returnValue = false; // 兼容IE
}
function getEvent(e) {
return e || window.event;
}
题目5:有如下代码,要求当点击每一个元素li时控制台展示该元素的文本内容。不考虑兼容
<ul class="ct">
<li>这里是</li>
<li>饥人谷</li>
<li>前端6班</li>
</ul>
<script>
//todo ...
</script>
<script>
var ct = document.querySelector('.ct');
ct.addEventListener('click', function(e) {
var target = e.target;
if(target.tagName.toLowerCase() === 'li') {
console.log(target.innerText);
}
}, false);
</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>
//你的代码
</script>
<script>
function $(id) {
return document.querySelector(id);
}
function $$(id) {
return document.querySelectorAll(id);
}
// 开头添加
$("#btn-add-start").addEventListener('click', function() {
var newNode = document.createElement('li');
if($(".ipt-add-content").value.length !== 0) {
newNode.innerText = $(".ipt-add-content").value;
$(".ct").insertBefore(newNode, $(".ct").firstChild);
}
}, false);
// 结尾添加
$("#btn-add-end").addEventListener('click', function() {
var newNode = document.createElement('li');
if($(".ipt-add-content").value.length !== 0) {
newNode.innerText = $(".ipt-add-content").value;
$(".ct").appendChild(newNode);
}
}, false);
// 点击每个元素li时控制台展示该元素的文本内容
$(".ct").addEventListener('click', function(e) {
var target = e.target;
if (target.tagName.toLowerCase() === 'li') {
console.log(target.innerText);
}
}, false);
</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>
//你的代码
</script>
<script>
var ct = document.getElementsByClassName('ct')[0];
var imgPreview = document.getElementsByClassName('img-preview')[0];
function show(e) {
var e = e || window.event;
var target = e.target || e.srcElement;
src = target.getAttribute('data-img');
imgPreview.innerHTML = "![]( + src + )";
}
addEvent(ct, 'click', show);
function addEvent(node, type, handler) {
if(!node) return false;
if(node.addEventListener) {
node.addEventListener(type, handler, false);
return true;
}else if(node.attachEvent) {
node['e' + type + handler] = handler;
node[type + handler] = function() {
node['e' + type + handler](window.event);
};
node.attachEvent('on' + type, node[type + handler]);
return true;
}
return false;
}
</script>
网友评论