1.DOM0 事件和DOM2級在事件監(jiān)聽使用方式上有什么區(qū)別?
DOM0事件是將一個函數(shù)賦值給一個事件處理程序?qū)傩裕?/p>
var btn=document.getElementById("myBtn");
btn.omclick=function(){
alert(this.id);//"myBtn"
};
使用DOM0級方法指定的事件處理程序被認為是元素的方法。此時事件處理程序是在元素的作用域中運行,程序中的this引用當前元素。DOM0的優(yōu)勢在于基本上所有的瀏覽器都支持,劣勢在于因為是給元素的屬性賦值的方式來添事件處理程序,所以再次向同一個元素添加另一個事件處理程序,上一個處理程序會被覆蓋。
DOM2事件定義了兩個方法,addEventListener()和removeEventListener(),用于處理指定和刪除事件處理程序的操作,所有DOM節(jié)點都包含這兩個方法,并且它們都接受三個參數(shù):處理事件名、處理事件程序的函數(shù)、布爾值;布爾值是true表示在捕獲階段調(diào)用事件處理程序,如果是false,表示在冒泡階段調(diào)用事件處理程序:
var btn = document.getElementById("myBtn");
btn.addEventListener("click",function(){
alert(this.id);
},flase);
與DOM0方法一樣,這里的處理程序也是在其依附的元素作用域中運行。DOM2方法的好處是可以添加多個事件處理程序
2.attachEvent與addEventListener的區(qū)別?
-
適應(yīng)的瀏覽器版本不同
attachEvent方法適用于IEaddEventListener方法適用于Mozilla/Webkit -
參數(shù)個數(shù)不相同
addEventListener有三個參數(shù),attachEvent只有兩個,attachEvent添加的事件處理程序只能發(fā)生在冒泡階段,addEventListener第三個參數(shù)可以決定添加的事件處理程序是在捕獲階段還是冒泡階段處理(我們一般為了瀏覽器兼容性都設(shè)置為冒泡階段) -
第一個參數(shù)意義不同
addEventListener第一個參數(shù)是事件類型(比如click,load),而attachEvent第一個參數(shù)指明的是事件處理函數(shù)名稱(onclick,onload) -
事件處理程序的作用域不相同
addEventListener的作用域是元素本身,this是指的觸發(fā)元素,而attachEvent事件處理程序會在全局變量內(nèi)運行,this是window -
為一個事件添加多個事件處理程序時,執(zhí)行順序不同
addEventListener添加會按照添加順序執(zhí)行,而attachEvent添加多個事件處理程序時順序無規(guī)律
3. 解釋IE事件冒泡和DOM2事件傳播機制?
IE事件冒泡
事件最開始時由最具體的元素(文檔中嵌套層次最深的那個節(jié)點)接收,然后逐級向上傳播到較為不具體的節(jié)點(文檔)。以下面的HTML頁面為例:
<!DOCTYPE html>
<html>
<head>
<title>exp</title>
</head>
<body>
<div id="my">Click me</div>
</body>
</html>
如果你點擊了頁面中的<div>元素,那么這個click事件會按照如下順序傳播:
(1)<div>
(2)<body>
(3)<html>
(4)document
也就是說,click事件首先在<div>元素上發(fā)生,而這個元素就是我們點擊的元素。然后,click事件沿著DOM樹向上傳播,在每一級節(jié)點上都會發(fā)生,直至傳播到document對象。過程如下圖:

DOM2事件傳播機制
"DOM2級事件"規(guī)定的時間溜包括三個階段:事件捕獲階段,處于目標階段和事件冒泡階段。首先發(fā)生的是事件捕獲,為截獲事件提供了機會。然后是實際的目標接收到事件。最后一個階段是冒泡階段,可以在這個階段對事件做出響應(yīng)。以前面簡單的HTML頁面為例。單擊<div>元素會按照下圖所示順序觸發(fā)事件。

4.如何阻止事件冒泡? 如何阻止默認事件?
阻止默認事件
阻止事件的默認行為,可以使用preventDefault()方法,前提是cancelable值為true,比如我們可以阻止鏈接導(dǎo)航這一默認行為
document.getElementsByTagName('a').onclick = function (e) {
e.preventDefault();
}
阻止事件冒泡
stopPropagation()方法可以停止事件在DOM層次的傳播,即取消進一步的事件捕獲或冒泡
var handler = function (e) {
alert(e.type);
e.stopPropagation();
}
addEvent(document.body, 'click', function () { alert('Clicked body')});
var btnClick = document.getElementById('btnClick');
addEvent(btnClick, 'click', handler);
上述代碼的body 的alert('Clicked body')不會i執(zhí)行,因為內(nèi)部的事件冒泡被阻止了。
5.有如下代碼,要求當點擊每一個元素li時控制臺展示該元素的文本內(nèi)容。不考慮兼容
<ul class="ct">
<li>這里是</li>
<li>饑人谷</li>
<li>前端6班</li>
</ul>
<script>
var ct= document.getElementsByClassName('ct');
console.log(ct);
ct[0].addEventListener("click",function(e){
var target= e.target;
if(target.tagName.toLowerCase() === "li"){
console.log(target.innerText);
}
})
</script>
6. 補全代碼,要求:
- 當點擊按鈕開頭添加時在
<li>這里是</li>元素前添加一個新元素,內(nèi)容為用戶輸入的非空字符串;當點擊結(jié)尾添加時在最后一個 li 元素后添加用戶輸入的非空字符串. - 當點擊每一個元素li時控制臺展示該元素的文本內(nèi)容。
<ul class="ct">
<li>這里是</li>
<li>饑人谷</li>
<li>任務(wù)班</li>
</ul>
<input class="ipt-add-content" placeholder="添加內(nèi)容" />
<button id="btn-add-start">開頭添加</button>
<button id="btn-add-end">結(jié)尾添加</button>
<script>
var ct = document.getElementsByClassName('ct');
var ipt = document.getElementsByClassName('ipt-add-content');
var star_btn = document.getElementById('btn-add-start');
var end_btn = document.getElementById('btn-add-end');
console.log(ipt);
ct[0].addEventListener("click", function(e) {
var target = e.target;
if (target.tagName.toLowerCase() === "li") {
console.log(target.innerText);
}
});
end_btn.addEventListener("click", function() {
if ((/\S/.test(ipt[0].value))) {
var node = document.createElement('li');
node.innerText = ipt[0].value;
ct[0].appendChild(node);
}
});
star_btn.addEventListener("click", function() {
if ((/\S/.test(ipt[0].value))) {
var node = document.createElement('li');
node.innerText = ipt[0].value;
ct[0].insertBefore(node, ct[0].firstChild);
}
});
</script>
7.補全代碼,要求:當鼠標放置在li元素上,會在img-preview里展示當前l(fā)i元素的data-img對應(yīng)的圖片。
<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 ct = document.querySelector('.ct');
var preview = document.querySelector('.img-preview');
var img_node = document.createElement('img');
preview.appendChild(img_node);
ct.addEventListener('mouseover',function(e){
var target = e.target;
if(target.tagName.toLowerCase()==="li"){
var img_data = target.getAttribute('data-img');
img_node.setAttribute('src',img_data);
}
});
ct.addEventListener('mouseout',function(e){
img_node.setAttribute('src','');
});
</script>