国产xxxx99真实实拍_久久不雅视频_高清韩国a级特黄毛片_嗯老师别我我受不了了小说

資訊專欄INFORMATION COLUMN

JS基礎(chǔ)篇--事件綁定及深入

yearsj / 3553人閱讀

摘要:學(xué)習(xí)要點(diǎn)傳統(tǒng)事件綁定的問題事件處理函數(shù)事件處理函數(shù)事件對象的其他補(bǔ)充事件綁定分為兩種一種是傳統(tǒng)事件綁定內(nèi)聯(lián)模型,腳本模型,一種是現(xiàn)代事件綁定級模型。現(xiàn)代事件綁定在傳統(tǒng)綁定上提供了更強(qiáng)大更方便的功能。事件和事件事件和事件,有關(guān)加載方面的事件。

學(xué)習(xí)要點(diǎn):

1.傳統(tǒng)事件綁定的問題
2.W3C事件處理函數(shù)
3.IE事件處理函數(shù)
4.事件對象的其他補(bǔ)充

事件綁定分為兩種:一種是傳統(tǒng)事件綁定(內(nèi)聯(lián)模型,腳本模型),一種是現(xiàn)代事件綁定(DOM2級模型)。現(xiàn)代事件綁定在傳統(tǒng)綁定上提供了更強(qiáng)大更方便的功能。

一 傳統(tǒng)事件綁定的問題

傳統(tǒng)事件綁定中的內(nèi)聯(lián)模型不做討論,基本很少去用。先來看一下腳本模型,腳本模型將一個函數(shù)賦值給一個事件處理函數(shù)。傳統(tǒng)綁定如:

window.onload=function(){
    var box=document.getElementById("box");
    box.onclick = function(){
        alert("Lee");
    };
};


問題一:一個事件處理函數(shù)觸發(fā)兩次事件

如果一個頁面有兩個或者多個js,并且第一個js是第一個程序開發(fā)的,第二個js是第二個程序員開發(fā)的。第一個window.onload被覆蓋了,如

window.onload=function(){
    alert("Lee");
};

window.onload=function(){
    alert("Mr.lee");
}  

結(jié)果只是打印了 Mr.lee

其實(shí)是有辦法解決這個問題的,看下面這兩種形式。
a:

alert(window.onload);//一開始沒有注冊window.onload,那么就是null

window.onload=function(){
    alert("Lee");
};

alert(window.onload);//如果已經(jīng)有window.onload,打印的是函數(shù)function

window.onload=function(){
    alert("Mr.lee");
} 

b:

alert(typeof window.onload);//一開始沒有window.onolad,舊版火狐顯示undefined,新版顯示object,

window.onload=function(){
    alert("Lee");
};

alert(typeof window.onload);//如果已經(jīng)有window.onload,所有瀏覽器都會顯示function

window.onload=function(){
    alert("Mr.lee");
}

所以解決辦法有了。

   window.onload=function(){
    alert("Lee");
};

if(typeof window.onload=="function"){
    var saved=null;//保存上一個事件對象
    saved=window.onload;
}

//saved 就是window.onload,saved()相當(dāng)于window.onload(),但是window.onload()不能執(zhí)行的
//所以saved()相當(dāng)于window.onload=function(){}

window.onload=function(){
    if(saved){
        saved();//執(zhí)行上一個事件 window.onload=function(){}
    }
    alert("Mr.lee"); //執(zhí)行本事件
}

問題二:事件切換器
切換一個id為box的div,讓里面的背景red與blue直接切換,并且切換之前彈框一次,如:

window.onload=function(){
    var box=document.getElementById("box");
    box.className="red";
    box.onclick=function(){
        alert("Lee"); //只執(zhí)行了一次
        blue.call(this);//通過匿名函數(shù)執(zhí)行某一函數(shù),那么里面的this就是代表的window,所以可以通過call傳遞
    };
}

function blue(){
    this.className="blue";
    this.onclick=red;
    
}

function red(){
    this.className="red";
    this.onclick=blue;
}

上面的代碼雖然實(shí)現(xiàn)了切換功能,但是彈框只執(zhí)行了一次。

//添加事件函數(shù)
//obj相當(dāng)于window
//type相當(dāng)于onload
//fn相當(dāng)于function(){}
function addEvent(obj,type,fn){
    //用于保存上一個事件
    var saved=null;
    if(typeof obj["on"+type]=="function"){
        saved=obj["on"+type];//保存上一個事件
    }
    obj["on"+type]=function(){
        if(saved){
            saved();
        }
        fn.call(this);
    }
    
}
addEvent(window,"load",function(){
    var box=document.getElementById("box");
    //addEvent(box,"click",function(){ //目的達(dá)到,每次都執(zhí)行了,沒有被覆蓋
    //    alert("ss");
    //});
    addEvent(box,"click",blue);
});

function red(){
    this.className="red";
    addEvent(box,"click",blue);
}

function blue(){
    this.className="blue";
    addEvent(box,"click",red);
}

//當(dāng)不停的切換的時候,瀏覽器突然卡死,并且報(bào)錯:too much recursion,太多的遞歸
//因?yàn)榉e累了太多的保存的事件
//解決方案,就是用完的事件,就立刻移除掉

按照上面的代碼出現(xiàn)了注釋中的錯誤,解決的辦法如下:

//添加事件函數(shù)
//obj相當(dāng)于window
//type相當(dāng)于onload
//fn相當(dāng)于function(){}
function addEvent(obj,type,fn){
    //用于保存上一個事件
    var saved=null;
    if(typeof obj["on"+type]=="function"){
        saved=obj["on"+type];//保存上一個事件
    }
    obj["on"+type]=function(){
        if(saved){
            saved();
        }
        fn.call(this);
    }
    
}


//當(dāng)不停的切換的時候,瀏覽器突然卡死,并且報(bào)錯:too much recursion,太多的遞歸
//因?yàn)榉e累了太多的保存的事件
//解決方案,就是用完的事件,就立刻移除掉


//移除事件函數(shù)
function removeEvent(obj,type){
    if(obj["on"+type]){
        obj["on"+type]=null;
    }
}


addEvent(window,"load",function(){
    var box=document.getElementById("box");
    //addEvent(box,"click",function(){ //目的達(dá)到,每次都執(zhí)行了,沒有被覆蓋
    //    alert("ss");
    //});
    addEvent(box,"click",blue);
});

function red(){
    this.className="red";
    removeEvent(this,"click");
    addEvent(box,"click",blue);
}

function blue(){
    this.className="blue";
    removeEvent(this,"click");
    addEvent(box,"click",red);
}
二 W3C事件處理函數(shù) addEventListener()與removeEventListener()

W3C事件處理函數(shù)兩個,addEventListener()與removeEventListener()。

//W3C自帶的兩個添加事件和刪除事件

1.覆蓋問題,解決

window.addEventListener("load",function(){
    alert("Lee");
},false);

window.addEventListener("load",function(){
    alert("Mr.Lee");
},false);

window.addEventListener("load",function(){
    alert("Mrs.Lee");
},false);

2.相同函數(shù)屏蔽的問題,解決

window.addEventListener("load",init,false);
window.addEventListener("load",init,false);
window.addEventListener("load",init,false);
function init(){
    alert("Lee");
}

3.是否可以傳遞this,解決
例子1:

window.addEventListener("load",function(){
    var box=document.getElementById("box");
    box.addEventListener("click",function(){
        alert(this);
    },false);
},false);

例子2:

window.addEventListener("load",function(){
    var box=document.getElementById("box");
    box.addEventListener("click",blue,false);
},false);

function red(){
    this.className="red";
    this.removeEventListener("click",red,false);
    this.addEventListener("click",blue,false);
}

function blue(){
    this.className="blue";
    this.removeEventListener("click",blue,false);
    this.addEventListener("click",red,false);
}

4.添加一個額外的方法,會不會被覆蓋,或者只能執(zhí)行一次,解決

window.addEventListener("load",function(){
    var box=document.getElementById("box");
    box.addEventListener("click",function(){
        alert("Lee");
    },false);
    box.addEventListener("click",blue,false);
},false);

綜上所述:W3C是比較完美的解決了這些問題,非常好用,但是IE8和之前的瀏覽器并不支持,而是采用了自己的事件,當(dāng)然IE9已經(jīng)完全支持了W3C的這兩個事件處理函數(shù)。

W3C可以設(shè)置冒泡和捕獲方式。

支持W3C標(biāo)準(zhǔn)的瀏覽器在添加事件時用addEventListener(event,fn,useCapture)方法,基中第3個參數(shù)useCapture是一個Boolean值,用來設(shè)置事件是在事件捕獲時執(zhí)行,還是事件冒泡時執(zhí)行。而不兼容W3C的瀏覽器(IE)用attachEvent()方法,此方法沒有相關(guān)設(shè)置,不過IE的事件模型默認(rèn)是在事件冒泡時執(zhí)行的,也就是在useCapture等于false的時候執(zhí)行,所以把在處理事件時把useCapture設(shè)置為false是比較安全,也實(shí)現(xiàn)兼容瀏覽器的效果。

事件捕獲階段:事件從最上一級標(biāo)簽開始往下查找,直到捕獲到事件目標(biāo)(target)。
事件冒泡階段:事件從事件目標(biāo)(target)開始,往上冒泡直到頁面的最上一級標(biāo)簽。
事件的傳播是可以阻止的:
在W3c中,使用stopPropagation()方法
在IE下設(shè)置cancelBubble = true

三.IE事件處理函數(shù) attachEvent()和detachEvent()

IE實(shí)現(xiàn)了與DOM中類似的兩個方法:attachEvent()和detachEvent()。這兩個方法接受相同的參數(shù):事件名稱和函數(shù)。

在使用這兩組函數(shù)的時候,先把區(qū)別說一下:1.IE不支持捕獲,只支持冒泡;2.IE添加事件不能屏蔽重復(fù)的函數(shù);3.IE中的this指向的是window而不是DOM對象。4.在傳統(tǒng)事件上,IE是無法接受到event對象的,但使用了attchEvent卻可以,但有些區(qū)別。

1.覆蓋問題,解決了,但有不同,結(jié)果是Mrs.Lee,Mr.Lee,最后是Lee

window.attachEvent("onload",function(){
    alert("Lee");
});

window.attachEvent("onload",function(){
    alert("Mr.Lee");
});
window.attachEvent("onload",function(){
    alert("Mrs.Lee");
});

2.相同函數(shù)屏蔽的問題,未解決。

window.attachEvent("onload",init);
window.attachEvent("onload",init);

function init(){
    alert("Lee");
}

3.是否可以傳遞this,不能,this指的是window。需要用call方法。

window.attachEvent("onload",function(){
    var box=document.getElementById("box");
    box.attachEvent("onclick",function(){
        //alert(this===box);
        alert(this===window);  //true
    });
});

下面還有辦法就是通過window.event.srcElement。代碼如下:

window.attachEvent("onload",function(){
    var box=document.getElementById("box");
    box.attachEvent("onclick",blue);
});

function red(){
    var that=window.event.srcElement;
    that.className="red";
    that.detachEvent("onclick",red);
    that.attachEvent("onclick",blue);
}

function blue(){
    var that=window.event.srcElement;
    that.className="blue";
    that.detachEvent("onclick",blue);
    that.attachEvent("onclick",red);
}

4.添加一個額外的方法,會不會被覆蓋,或者只能執(zhí)行一次,解決。

在傳統(tǒng)綁定上,IE是無法像W3C那樣通過傳參接受event對象,但是使用attachEvent()卻可以。

 window.attachEvent("onload",function(){
    var box=document.getElementById("box");
    box.onclick=function(evt){ //傳統(tǒng)方法IE無法通過參數(shù)獲取evt
        alert(evt);//undefined
    }
    box.attachEvent("onclick",function(evt){
        alert(evt);//object
        alert(evt.type);//click
        alert(evt.srcElement.tagName);//DIV
        alert(window.event.srcElement.tagName);//DIV
    });
});
跨瀏覽器的兼容

跨瀏覽器添加事件

function addEvent(obj,type,fn){
    if(obj.addEventListener){
        obj.addEventListener(type,fn,false);
    }else if(obj.attachEvent){
        obj.attachEvent("on"+type,fn);
    }
}

跨瀏覽器移除事件

function removeEvent(obj,type,fn){
    if(obj.removeEventListener){
        obj.removeEventListener(type,fn,false);
    }else if(obj.detachEvent){
        obj.detachEvent("on"+type,fn);
    }
}

跨瀏覽器獲取目標(biāo)對象

function getTarget(evt){
    if(evt.target){
        return evt.target;
    }else if(window.event.srcElement){
        return window.event.srcElement;
    }
}

調(diào)用方式:

addEvent(window,"load",function(){
    var box=document.getElementById("box");
    addEvent(box,"click",blue);
});


function red(evt){
    var that=getTarget(evt);
    that.className="red";
    removeEvent(that,"click",red);
    addEvent(that,"click",blue);
}

function blue(evt){
    var that=getTarget(evt);
    that.className="blue";
    removeEvent(that,"click",blue);
    addEvent(that,"click",red);
}
四.事件對象的其他補(bǔ)充 relatedTarget事件

w3c中的一個relatedTarget事件。
例如:

addEvent(window,"load",function(){
    var box=document.getElementById("box");
    addEvent(box,"mouseover",function(evt){
        alert(evt.relatedTarget); //得到移入box最近的那個DOM對象
    });
    
    addEvent(box,"mouseout",function(evt){
        alert(evt.relatedTarget); //從box移出最近的那個DOM對象
    });
});

IE提供了兩組分別用于移入移出的屬性fromElement和toElement,分別對應(yīng)mouseover和mouseout。

addEvent(window,"load",function(){
    var box=document.getElementById("box");
    addEvent(box,"mouseover",function(){
        alert(window.event.fromElement.tagName); //得到移入box最近的那個DOM對象
    });
    
    addEvent(box,"mouseout",function(){
        alert(window.event.toElement.tagName); //從box移出最近的那個DOM對象
    });
});

PS:fromElement和toElement如果分別對應(yīng)相反的鼠標(biāo)事件,沒有任何意義。

剩下要做的就是跨瀏覽器兼容操作:

function getTarget(evt){
    var e=evt || window.event;
    if(e.srcElment){ //IE
        if(e.type=="mouseover"){
            return e.fromElement.tagName;
        }else if(e.type="mouseout"){
            return e.toElement.tagName;
        }
    }else if(e.relatedTarget){ //w3c
        return e.relatedTarget;
    }
}
屏蔽跳轉(zhuǎn)操作

取消事件的默認(rèn)行為有一種不規(guī)范的做法,就是返回false。

link.onclick=function(){
    alert("Lee");
    return false;
}

PS:雖然return false;可以實(shí)現(xiàn)這個功能,但是有漏洞。
第一:必須寫到最后,這樣導(dǎo)致中獎的代碼執(zhí)行后,有可能執(zhí)行不到return false;
第二:return false 寫到最前那么之后的自定義操作就失效了。
所以最好的辦法應(yīng)該是在最前面就阻止默認(rèn)行為,并且后面的代碼還可以執(zhí)行。

link.onclick=function(evt){
    evt.preventDefault;//w3c,阻止默認(rèn)行為
    alert("Lee");
}

link.onclick=function(evt){
    window.event.returnValue=false;//IE,阻止默認(rèn)行為
    alert("Lee");
}

那么跨瀏覽器的兼容:

function preDef(evt){
    var e=evt || window.event;
    if(e.preventDefault){
        e.preventDefault();
    }else{
        e.returnValue=false;
    }
}
右鍵菜單contextmenu

兼容:

function preDef(evt){
    var e=evt || window.event;
    if(e.preventDefault){
        e.preventDefault();
    }else{
        e.returnValue=false;
    }
}

addEvent(window,"load",function(){
    var body=document.getElementsByTagName("body")[0];
    addEvent(body,"contextmenu",function(evt){
        preDef(evt);
    })
});

PS:contextmenu事件很常用,這直接導(dǎo)致瀏覽器兼容性較為穩(wěn)定。

卸載前事件:beforeunload

這個事件可以幫助在離開本頁的時候給出相應(yīng)的提示,“離開”或者“返回”操作。

addEvent(window,"beforeonload",function(){
    preDef(evt);
});
鼠標(biāo)滾輪(mousewheel)和DOMMouseScroll

用于獲取鼠標(biāo)上下滾輪的距離

addEvent(document,"mousewheel",function(evt){ //非火狐
    alert(getWD(evt));
});

addEvent(document,"DOMMouseScroll",function(evt){ //火狐
    alert(getWD(evt));
});

function getWD(evt){
    var e=evt|| window.event;
    if(e.wheelDelta){
        return e.wheelDelta;
    }else if(e.detail){ //火狐
        return -evt.detail*30;
    }
}

PS:通過瀏覽器檢測可以確定火狐只執(zhí)行DOMMouseScroll。

DOMContentLoaded事件和readystatechange事件

DOMContentLoaded事件和readystatechange事件,有關(guān)DOM加載方面的事件。

文章版權(quán)歸作者所有,未經(jīng)允許請勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。

轉(zhuǎn)載請注明本文地址:http://specialneedsforspecialkids.com/yun/78841.html

相關(guān)文章

  • javascript知識點(diǎn)

    摘要:模塊化是隨著前端技術(shù)的發(fā)展,前端代碼爆炸式增長后,工程化所采取的必然措施。目前模塊化的思想分為和。特別指出,事件不等同于異步,回調(diào)也不等同于異步。將會討論安全的類型檢測惰性載入函數(shù)凍結(jié)對象定時器等話題。 Vue.js 前后端同構(gòu)方案之準(zhǔn)備篇——代碼優(yōu)化 目前 Vue.js 的火爆不亞于當(dāng)初的 React,本人對寫代碼有潔癖,代碼也是藝術(shù)。此篇是準(zhǔn)備篇,工欲善其事,必先利其器。我們先在代...

    Karrdy 評論0 收藏0
  • 面試寶典

    摘要:有談?wù)劽嬖嚺c面試題對于前端面試的一些看法。動態(tài)規(guī)劃算法的思想及實(shí)現(xiàn)方法幫大家理清動態(tài)規(guī)劃的解決思路以及原理方法前端經(jīng)典面試題從輸入到頁面加載發(fā)生了什么這是一篇開發(fā)的科普類文章,涉及到優(yōu)化等多個方面。極客學(xué)院前端練習(xí)題道練習(xí)題,面試季練練手。 由數(shù)據(jù)綁定和排序引入的幾個 JavaScript 知識點(diǎn) 在 JavaScript 的數(shù)據(jù)綁定和做簡單的表格排序中遇到的幾個知識點(diǎn) [[JS 基礎(chǔ)...

    neu 評論0 收藏0
  • 深入理解js

    摘要:詳解十大常用設(shè)計(jì)模式力薦深度好文深入理解大設(shè)計(jì)模式收集各種疑難雜癥的問題集錦關(guān)于,工作和學(xué)習(xí)過程中遇到過許多問題,也解答過許多別人的問題。介紹了的內(nèi)存管理。 延遲加載 (Lazyload) 三種實(shí)現(xiàn)方式 延遲加載也稱為惰性加載,即在長網(wǎng)頁中延遲加載圖像。用戶滾動到它們之前,視口外的圖像不會加載。本文詳細(xì)介紹了三種延遲加載的實(shí)現(xiàn)方式。 詳解 Javascript十大常用設(shè)計(jì)模式 力薦~ ...

    caikeal 評論0 收藏0
  • 前端進(jìn)階系列-目錄

    摘要:然而在最近的面試中通過學(xué)習(xí)和思考,找到了前進(jìn)的方向,也得到一些大公司的錄用機(jī)會。算是從初級前端畢業(yè),進(jìn)階了吧。在這里先寫個目錄。趕時間的同學(xué)可以按照我的目錄先自行準(zhǔn)備提升,希望推薦文章和交流。 背景 之前我分享了文章大廠前端面試考什么?,你們一定很想看答案吧?說實(shí)話,答案我是有,在準(zhǔn)備面試的時候會時不時翻看,但內(nèi)容比較多,比較凌亂,不能指望我在一篇文章中寫完。 我是從非計(jì)算機(jī)專業(yè)自學(xué)前...

    cod7ce 評論0 收藏0
  • JavasScript重難點(diǎn)知識

    摘要:忍者級別的函數(shù)操作對于什么是匿名函數(shù),這里就不做過多介紹了。我們需要知道的是,對于而言,匿名函數(shù)是一個很重要且具有邏輯性的特性。通常,匿名函數(shù)的使用情況是創(chuàng)建一個供以后使用的函數(shù)。 JS 中的遞歸 遞歸, 遞歸基礎(chǔ), 斐波那契數(shù)列, 使用遞歸方式深拷貝, 自定義事件添加 這一次,徹底弄懂 JavaScript 執(zhí)行機(jī)制 本文的目的就是要保證你徹底弄懂javascript的執(zhí)行機(jī)制,如果...

    forsigner 評論0 收藏0

發(fā)表評論

0條評論

最新活動
閱讀需要支付1元查看
<