w簡書的markdown不支持[toc]? ??
不知不覺,從開始做android的項目后就很少寫JS了,最近項目中需要用到大量的H5,也來湊湊HTML5開發的熱鬧。。。當然前提要學好JS,好記性不如爛筆頭,開始學著寫點筆記,提升學習效率~
這里只是記錄一些比較容易忘記,API之類的需要時再去查閱
[toc]
事件對象
接受對象的差異性
W3C可直接通過參數接收事件對象,而IDE自己定義了一個Event對象,通過window.event
獲取。
兼容獲取事件對象的代碼
<input type="button" id="btn" value="提交"/>
<script>
var btn = document.getElementById("btn");
btn.onclick = function(event){
var e = event || widnow.event;
alert(e);
}
</script>
鼠標事件
鼠標事件的兼容性問題
onmousemove:鼠標移動
onmousedown:鼠標點擊
onmouseup:鼠標松開
onmouseover:鼠標移動到元素區域內
onmouseout :鼠標移出元素
在這三個事件對象中,有一個button屬性,表示按下或者釋放的按鈕,遺忘的是對于這個button屬性,坑爹的IE也與W3C不同(怪不得你爹不要你了)
W3C中的button屬性
IE中的button屬性
可以看出,IE和W3C在button屬性上各個數值所表示的按鈕和狀態都不一樣,但是一般我們只需要兼容W3C那三種就好了
兼容代碼
function getButton(evt) {
var e = evt || window.event;
if (evt) {
return e.button;
} else
if (window.event) {
switch(e.button) {
case 1 :
return 0;
case 4 :
return 1;
case 2 :
return 2;
}
}
}
document.onmouseup = function (evt) {
if (getButton(evt) == 0) {
alert('按下了左鍵!');
} else if (getButton(evt) == 1) {
alert('按下了中鍵!');
} else if (getButton(evt) == 2) {
alert('按下了右鍵!' ); }
};
鼠標事件-可視區和坐標的獲取
可通過clienX,screex獲取,這個就不記錄了,查一下文檔即可
鍵盤事件
onkeydown
onkeypress:只對能在屏幕上輸出字符的按鈕有效果
onkeyup
屬性:
keyCode:鍵碼---獲取一個代碼,與鍵盤特定的鍵對應,與ASCII碼中對應的編碼相同(不區分大小寫)
charCode:字符編碼 --- 只有在keypress中才包含值,對應的是鍵所代碼的字符的ASCII編碼(區分大小寫)
document.onkeypress = function (event) {
alert("charCode == "+ event.charCode); //得到相應的 charCode
};
document.onkeydown = function (event) {
alert("keyCode == "+ event.keyCode); //得到相應的 keyCode
};
兼容性問題:
不同瀏覽器中,獲取的keyCode(鍵碼)和charCode(字符編碼)有可能不一樣,要謹慎操作
事件對象的其他屬性
事件冒泡
事件流:當幾個具有事件的元素疊在一起的時候,那么你點擊一個元素后,所有層疊在你點擊范圍內的元素都會觸發事件。
來個簡單的圖感受一下。
Button,紫色和藍色的DIV都具有點擊事件,因為Button在最內層,當點擊button時,click事件會從內往外觸發----這就是事件冒泡(特征:從里往外觸發)
事件捕獲:與事件冒泡相反,是從外往內觸發
阻止冒泡
從前面的==事件的其他屬性==中看到,關于阻止事件冒泡IE和W3C有不同的屬性
IE:是通過cancelBubble = true 取消事件冒泡
W3C:調用stopProgagation()方法取消事件冒泡
阻止的兼容方法
function stopPro(event) {
var e = event || window.event;
window.event ? e.cancelBubble = true : e.stopPropagation(); }
事件的綁定
事件的綁定有兩種方式
一,傳統的事件綁定,分為內聯模型,腳本模型
二,DOM2級的現代事件綁定
傳統的事件綁定
內聯模型
基本上很少用,維護起來簡直想殺人。。。
下面這兩種形式
<input value="點擊" id="btn" type="button" onclick="alert('aaa')">
<input value="點擊" id="btn" type="button" onclick="btnOnclick()">
腳本模型
即用JavaScript獲取DOM設置事件
傳統事件綁定的問題
一、多次綁定會被覆蓋
很直觀的問題,重復綁定會覆蓋掉前面的
/*缺點1:綁定多次會被覆蓋 */
window.onload = function(){
alert("onload 111111");
}
window.onload = function(){
alert("onload 2222222");
}
二、this的指向問題
var myDiv = document.getElementById("myDiv");
myDiv.onclick = toBlue;
function toBlue(){
alert(this);//第一次就是DivElement 第二次就是window了
this.className = "blue";
this.onclick = toRed;
}
function toRed(){
this.className = "red";
this.onclick = function(){
toBlue();
}
}
三、too much recursion的問題
當你不停的add事件時,可能會報出too much recursion的錯誤,這是因為你積累了太多的保存事件,太多遞歸導致瀏覽器卡死。
解決方法:用完的事件,立即處理掉
var myDiv = document.getElementById("myDiv");
//可以通過[]的形式獲取綁定事件
myDiv['onclick'] = function(){
alert("aaa");
};
/**
* obj : 要移出的元素
* type: 要移出的事件類型 click等
**/
function removeEvent(obj,type){
if(obj['on'+type]) obj['on'+type] = null;
}
W3C事件處理
DOM2級中,定義了addEventListener和removeEventListener方法。最后一個參數 true:表示捕獲,false:表示冒泡
一,解決了this的指向問題,再也不怕too much recursion了
我們將上面this指向的代碼稍微修改一下
var myDiv = document.getElementById("myDiv");
myDiv.addEventListener('click',toBlue);
function toBlue(){
alert(this);//都是DivElement
this.className = "blue";
this.addEventListener('click',toRed);
}
function toRed(){
this.className = "red";
myDiv.addEventListener('click',function(){
toBlue();
});
}
二,解決重復綁定覆蓋的問題
var myDiv = document.getElementById("myDiv");
myDiv.addEventListener('click',function(){
alert("event 11111");
})
/**
* 不再覆蓋,兩個都會執行,共存
* */
myDiv.addEventListener('click',function(){
alert("event 222222");
})
IE的事件處理函數
IE9就全面支持W3C的事件函數了,這里就做個簡單的了解
提供了兩個方法:
attachEvent()
detachEvent()
幾個不同點
1,IE不支持捕獲,只支持冒泡
2,IE不能屏蔽重復的函數
3,IE中this指向的是window對象
4,之前說到,IE在傳統事件中接收不到event事件對象的
但是attchEvent可以做到。。。真是讓人爪機
不想裝個IE瀏覽器,這就不測試了,做個簡單的記錄,方便以后用到的時候查詢
添加/刪除事件,得到事件對象的兼容代碼
//添加事件兼容
function addEvent(obj, type, fn) {
if (obj.addEventListener) {
obj.addEventListener(type, fn);
} else
if (obj.attachEvent) {
obj.attachEvent('on' + type, fn); }
}
//移除事件兼容
function removeEvent(obj, type, fn) {
if (obj.removeEventListener) {
obj.removeEventListener(type, fn);
} else if (obj.detachEvent) {
obj.detachEvent('on' + type, fn);
}
}
//得到事件目標
function getTarget(evt) { if (evt.target) {
return evt.target;
} else if (window.event.srcElement) {
return window.event.srcElement; }
}
事件其他補充(主要是兼容方面)
獲取移入和移出的DOM對象的兼容問題
W3C版:事件對象屬性:relatedTarget
IE版:fromElement 和 toElement,分別對應 mouseover 和 mouseout。
不同的實現,又需要兼容的代碼~
function getTarget(evt) {
var e = evt || window.event;
if (e.srcElement) {//如果支持,就是IE瀏覽器(srcElement:事件目標)
if (e.type == 'mouseover') {
return e.fromElement;
} else if (e.type == 'mouseout') {
return e.toElement;}
} else if (e.relatedTarget) {
//如果支持 relatedTarget,表示 W3C ;
return e.relatedTarget;
}
}
取消事件默認行為的兼容性問題
場景:取消超鏈接的默認行為.
解決方法一:
設置 return false。
缺點:
1)、必須寫在最后,那么中間的代碼執行后,
可能執行不到return false;(例如中間報錯了,但是頁面依舊會跳轉)
2)、如果寫在最前面,那么就無法做一些跳轉判斷了(通過一段邏輯判斷后才決定是否跳轉)
` <a id="aLink" >aaaa</a>`
var aLink = document.getElementById("aLink");
aLink.onclick = function(){
/**
*
* */
var person = function(){
}
var p = new Person();
p.show();//這里沒有show方法,報錯了,所以后面的return false沒有執行到,頁面依舊跳轉了
return false;
}
解決方法二:取消事件的默認行為
W3C:event.preventDefault(); IE:
window.event.returnValue = false;
頭疼,又需要兼容。。。
兼容代碼
function preDef(event) {
var e = event || window.event;
if(e.preventDefault) {
e.preventDefault();
}else {
e.returnValue= false;
}
}
oncontextmenu事件
可用于取消右鍵事件,提升瀏覽器性能
window.document.oncontextmenu = function(event){
var e = event || window.event;
if(e.preventDefault) {
e.preventDefault();
}else {
e.returnValue= false;
}
}