题目1: DOM0 事件和DOM2级在事件监听使用方式上有什么区别?
所谓的0级dom与2级dom事件就是不同版本间的差异,具体的说就是,对于不同的dom级别,在形式上和功能上都是有差异的。
形式上区别:
- dom0 事件是指定的事件处理程序被认为是元素的方法。
就是将一个函数赋值给一个事件处理程序属性,(每个元素包括window和document都有自己处理程序的属性)。
例如: onclick onmouseover onmouseout 等,都是on+type
这个时候的事件处理程序在元素的作用域中执行。
···
<button id="btn">提交</button>
<button id="btn2" class="bbb">注册</button>
···
var btn= document.getElementById('btn')
btn.onclick= function(){ //DOM0的表示形式 属性名要+ on
console.log('提交成功')
}
提交成功
var btn= document.getElementById('btn2')
btn.addEventListener('click',function(e){ //DOM2的表示形式
console.log(this)
console.log(e)
console.log('注册成功了')
});
<button id="btn2" class="bbb">注册</button>
MouseEvent {isTrusted: true, screenX: 72, screenY: 84, clientX: 72, clientY: 18…}
注册成功了
- ’DOM2级事件’定义了两个方法,用于处理指定和删除事件处理程序的操作:addEventListener()和removeEventListener();
所有的DOM节点都包含这两种方法。
它们都接受3个参数:要处理的事件名,事件处理程序的函数,和一个布尔值。
最后一个参数:如果为true,表示在捕获阶段调用事件处理程序,如果是false,表示在冒泡阶段调用事件处理程序。
功能上区别:
dom0 是一个函数赋值给一个时间处理程序属性(onclick等),多次赋值后面的会覆盖前面。
dom2 中传递多个参数,调用多次回调函数,添加多个事件,函数不会出现覆盖
题目2: attachEvent与addEventListener的区别?
区别 | attachEvent | addEventListener |
---|---|---|
参数个数不同 | 有2个参数(函数名称,function(){}) | 有3个参数(事件类型,function(){}, true/false) |
第一个参数的意义不同 | 事件处理函数的名称on+type | 事件的类型type |
事件的作用域不同 | 全局变量内运行,this->window | 元素本身,this->触发元素 |
一个事件有多个事件处理时的执行顺序不同 | 无规律顺序 | 按照添加顺序执行 |
事件处理阶段 | 只在冒泡阶段 | true ,在捕获阶段处理 ;默认为false ,在冒泡阶段处理 |
题目3: 解释IE事件冒泡和DOM2事件传播机制?
先解释几个词:
事件: 由用户或浏览器自身执行的某种动作,是某种行为或者触发,比如: 点击click 鼠标滑过mouseover ...
javascript 和html就是通过事件实现交互的。
事件处理程序(事件监听器):执行的某种的动作(点击、加载、鼠标等其他行为),响应这个动作(事件)的方法
IE事件冒泡 是 事件开始由具体的元素,逐级向上传播到不具体的元素(由具体到不具体)
DOM2事件传播机制
DOM2级事件规定事件流包含3个阶段:
(1)事件捕获阶段: 由外层不具体的 逐级 向内传播到具体的元素(由外到内)
(2)处于目标阶段 ,事件本身
(3)事件冒泡阶段: 由具体的逐级向外到不具体的元素(由内到外)
- 事件流: 从页面接收事件的顺序。
题目4:如何阻止事件冒泡? 如何阻止默认事件?
阻止事件冒泡
类似中断 ,取消事件冒泡后, 事件不会继续往外传播,外面监听不到
cancelBubble=true用于ie的阻止冒泡事件,
event.stopPropagation()用于firefox和chrome等其他浏览器。
.box{
background: red;
width: 200px;
height: 200px;
}
.box1{
background: green;
width: 120px;
height: 100px;
}
p{
background: yellow
}
<div class="box">
<div class="box1">
<p>你好</p>
</div>
</div>
var p= document.querySelector('p');
p.addEventListener('click',function(e){
console.log('p 标签')
//console.log(e) //返回事件的相关信息 ,包括事件元素、事件类型等
})
var box1= document.querySelector('.box1');
box1.addEventListener('click',function(e){
e.stopPropagation(); //阻止事件冒泡
console.log('box1 djakd')
})
var box= document.querySelector('.box');
box.addEventListener('click',function(){
console.log('box djkah')
})
冒泡的过程: p——>div.box1——> div.box
对box1的事件阻止冒泡后,不会输出 box的内容
输出:
p 标签
box1 djakd
阻止默认操作
作用是取消一个目标元素的默认行为。
既然是说默认行为,当然是元素必须有默认行为才能被取消,如果元素本身就没有默认行为,调用当然就无效了。
什么元素有默认行为呢?如链接<a>跳转src地址,提交按钮<input type=”submit”>提交form等。
e.preventDefault()用于firefox和chrome等其他浏览器。
IE 则是使用 e.returnValue = false;
首先是默认事件,preventDefault() 才能生效
<a id="link" href="baidu.com" >官网</a>
document.querySelector('#link').addEventListener('click',function(e){
e.preventDefault();// 阻止跳转页面
console.log('没有跳转')
})
效果: 点击链接,没有跳转
输出:
没有跳转
题目5:有如下代码,要求当点击每一个元素li时控制台展示该元素的文本内容。不考虑兼容
ul,li{
list-style: none;
}
ul{
border: 1px solid;
padding: 0;
}
ul li{
border: 1px solid #ccc;
margin: 8px 2px
}
<ul class="ct">
<li>这里是</li>
<li>饥人谷</li>
<li>前端6班</li>
</ul>
<script>
var ct= document.querySelector('.ct');
ct.addEventListener('click',function(e){
var b=e.target.innerText;
console.log(b)
})
</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 ct= document.querySelector('.ct');
ct.addEventListener('click',function(e){ //e事件对象用来找到目标元素,表示li
// console.log(e)
var b=e.target; //target属性: 目标元素(标签)li
if(b.tagName.toLowerCase()==='li'){//避免点击到li以外的区域,做一个判断,当当前的对象的目标元素是li时,
console.log(b.innerText) // 输出控制台 目标元素的内容
}
})
var ipt= document.querySelector('.ipt-add-content')
var btn= document.querySelector('#btn-add-start');
btn.addEventListener('click',function(){
var li= document.createElement('li');// 添加一个新的li
if(ipt.value.length>0){
li.innerText= ipt.value; // 获取输入框的内容给当前的这个li
//在添加li 到开始位置
ct.insertBefore(li,ct.firstElementChild); //添加的新节点,添加的节点位置之前 //ct.firstElementChild 为ul的开头第一个子元素
}
})
var btn= document.querySelector('#btn-add-end');
btn.addEventListener('click',function(){
var li= document.createElement('li')
if(ipt.value.length>0){
li.innerText= ipt.value;
ct.appendChild(li);
}
})
</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>
var ct= document.querySelector('.ct');
var images= document.querySelector('.img-preview')
ct.addEventListener('mouseover',function(e){
var danli=e.target;
if(danli.tagName.toLowerCase()==='li'){
// console.log(this)
var path=danli.getAttribute('data-img')
//如果传入的元素是文本的话 可以直接用 innerText传入
// 但是 如果是图片的话, 没法获取文本
// 所以可以用innerHTML=‘可以将这个标签加到HTML中,即而可以运行’
// console.log(path)
images.innerHTML='![](' + path + ')'
// console.log(images.innerHTML)
}
})