javascript小實例,阻止瀏覽器默認行爲,真的能阻止嗎?支持IE和標準瀏覽器的阻止默認行爲的方法

看到這標題,是否是有點逆天的感受,總感受好狂拽炫酷,耳邊隱隱約約傳來一個聲音:你這麼叼,你咋不上天呢! ~~ 額,好吧!javascript

話入正題,我爲何會提出這麼一個問題呢?html

阻止瀏覽器默認行爲,真的能阻止嗎?那究竟是什麼樣的方案,我會有這樣的質疑?java

那,就是它了,別看,就是你:chrome

//阻止瀏覽器默認行爲觸發的通用方法  
function stopDefault(e){  
	//防止瀏覽器默認行爲(W3C)  
	if(e && e.preventDefault){  
		e.preventDefault();  
	}  
	//IE中組織瀏覽器行爲  
	else{  
		window.event.returnValue=fale; 
		return false; 
	}  
}  

沒錯,就是你,這個在網上一搜,基本上很是通用的解決方案,之前我也對這種方法深信不疑,以爲這是前輩們的多少次實踐論證出來的東西,應該是精品,可是就在我寫拖拽效果的時候,在阻止瀏覽器默認行爲時,發如今IE8下,竟然嗝屁了,瀏覽器

你不信?那就讓咱們一塊兒來看看,上面的解決方案在IE8如下的表現吧!固然,標準瀏覽器是沒有問題的啦,畢竟e.preventDefault() 方法仍是槓槓的。函數

首先咱們要明確一下,什麼是瀏覽器的默認行爲,舉個栗子:this

頁面上有一行文字,若是我選中,而後拖動文字,那麼文字能夠被拖動,拖動後再鬆手,可能被選中的文字就去搜索了,因爲此效果很差截圖,大家本身去玩一下,那這一行爲就是瀏覽器的默認行爲;spa

再舉個栗子:線程

頁面上有一張圖片,點擊圖片,而後拖動,圖片會好像是複製了一份,而後也是能夠被拖動,這也是瀏覽器的默認行爲,看看IE下的截圖:htm

這個樣子的,大家應該司空見慣了吧,那瀏覽器廠家作的某些默認行爲,咱們爲何要千方百計的去阻止掉呢?由於咱們在作某些效果的時候,瀏覽器的默認行爲會影響咱們的效果,好比說表單中的提交按鈕,理論上的默認效果是我一點擊就會將個人表單提交出去,

但現實狀況可能並不但願它這樣,因此咱們須要阻止一下。

好了,咱們來講說咱們阻止瀏覽器的默認行爲的神器吧,仍是以圖片和文字爲例子,

<img src="1.jpg" id="img1" alt="">
<p id="text">聖誕節開發能順利的煩惱時來得快耐腐蝕的快樂你發了十多年兩三點扣年費是考慮到你發來看你</p>

這是咱們頁面上的一張圖和一行文字,隨便打的

window.onload = function(){
		var oImg = document.getElementById("img1");
		var oText = document.getElementById("text");
		oImg.onmousedown = function(e){
			stopDefault(e);
			 
		}
		oText.onmousedown = function(e){
			stopDefault(e);
		}
	
		//阻止瀏覽器默認行爲觸發的通用方法  
		function stopDefault(e){  
			//防止瀏覽器默認行爲(W3C)  
			if(e && e.preventDefault){  
				e.preventDefault();  
			}  
			//IE中組織瀏覽器行爲  
			else{  
				window.event.returnValue=false; //實際上在IE8如下,會報錯
				return false; 
			}  
		}  
	}

這是用咱們的神器來寫的一個小例子,意思是當鼠標按下去的時候,咱們來阻止瀏覽器的默認行爲,看看都有什麼表現,若是圖片和文字不能被拖動,說明是能夠阻止默認行爲的,若是不能,呵呵,你就慘了~

在標準瀏覽器上,good,沒問題,完美,在IE上,IE9以上good,IE8下,呃呃(此處有音效),嗝屁了,它們依然快樂的處處遊走,跟它們就沒什麼關係,因而可知,上面的神器是不足以來知足咱們的要求的(毀三觀啊)~

那如今的問題就變了,怎樣才能全面兼容阻止瀏覽器的默認行爲呢?這就是標題的後半段要講的內容了(主角來了)!

首先,咱們要確定的是  e.preventDefault()  方法是絕對能夠在標準瀏覽器下阻止默認行爲的,可是(重點來了),咱們今天不用這個方法,而是用  return false 這個熟悉的老朋友,固然關於return ,咱們又能夠講一篇長長的博文,像老太太的裹腳布同樣,

這裏咱們不講多麼的詳細,就提幾點:

return 表達式是結束函數執行,返回調用函數,沒有返回結果,舉個栗子:

function adc(){
	var a=2;
	var b=3;
	var sum = 0;
	return ;
			
	sum = a+b;
	console.log(sum);
}
adc();

看上面的這個函數,若是沒有return,那麼console就會打印sum的值5,可是偏偏有個return,讓函數在return後就不往下執行,而是返回到調用函數,因此就沒有值了,

那麼return false呢,通常是返回錯誤的處理結果;終止處理;阻止提交表單;阻止執行默認的行爲等等,值得注意的是,執行return false,實際上是執行了3個行爲:

一、執行event.preventDefault();  阻止瀏覽器的默認行爲;
二、event.stopPropagation();  阻止冒泡行爲;
三、中止回調函數執行並當即返回。

因此用此方法的時候,必需要考慮,你是否會有阻止冒泡的需求,若是有,咱們就必需要用 event.preventDefault();來阻止瀏覽器的默認行爲了,咱們仍是來舉個栗子吧(一貫的風格就是例子勝於雄辯):

window.onload = function(){
	var oImg = document.getElementById("img1");
	var oText = document.getElementById("text");
		
	oImg.onmousedown = function(e){
		return false; 
	}
	oText.onmousedown = function(e){
		return false; 
	}

}

仍是用上面的例子,改寫一下,看看效果如何, 恩,標準瀏覽器,槓槓的,再看IE,IE9以上依舊如此完美,IE8如下依舊那麼飄逸,好吧,看來咱們要解決的梗就是如何使IE8如下瀏覽器能乖一點!

要解決這個問題,我先介紹一個方法(閃亮登場):

setCapture()  //意思是在窗口設置鼠標捕獲

額,不懂,好吧,我也不懂,那咱們就用例子來描述一下:

<input type="button" value="按鈕一">
<input type="button" value="按鈕二">

頁面上有2個按鈕

window.onload = function(){
		var aInput = document.getElementsByTagName("input");
		//設置全局捕獲,當咱們給一個元素設置全局捕獲後,這個元素就會監聽後續的全部事件,當有事件發生的時候,就會被當前設置了全局捕獲的元素所觸發
		
		/*
			ie : 有,而且有效果
			ff : 有,但沒有效果
			chrome : 沒有,會報錯
		*/
		
		aInput[0].setCapture();
		
		aInput[0].onclick = function(){
		 	alert(1);	
		};
		aInput[1].onclick = function(){
		 	alert(2);	
		}
		
		
	}

分別給2個按鈕設點擊事件,而且給按鈕一開一個小竈,給它設一個全局的鼠標捕獲,咱們來看看,谷歌下,會報錯,不支持,火狐下,沒有報錯,也沒有別的什麼反應,一切正常,說明火狐是支持的,只是沒反應(由於不報錯),IE下,怪異狀況就出現了

不管個人鼠標在哪裏點擊,都會彈出1,就算是點擊按鈕2,也會彈出1,點到窗口外,也會彈出1,這是爲何呢?我查了一下資料,大概的解釋是:

函數功能:該函數在屬於當前線程的指定窗口裏設置鼠標捕獲。一旦窗口捕獲了鼠標,全部鼠標輸入都針對該窗口,不管光標是否在窗口的邊界內。同一時刻只能有一個窗口捕獲鼠標。若是鼠標光標在另外一個線程建立的窗口上,只有當鼠標鍵按下時系統纔將鼠標輸入指向指定的窗口。

通俗的意思是:當某個元素設置了全局鼠標捕獲,那個這個元素就會監聽後續發生的因此事件,當有事件發生的時候,就會被當前設置了全局捕獲的元素觸發,

因此,咱們看上面例子的怪異表現,當鼠標點擊的時候,就會被綁定了全局捕獲的按鈕一所觸發,那會執行按鈕一的點擊事件,因此會彈出1;

那麼它是怎麼來阻止瀏覽器的默認行爲的呢?舉個栗子:

window.onload = function(){
	var oImg = document.getElementById("img1");
	var oText = document.getElementById("text");
		
	oImg.onmousedown = function(e){
		oImg.setCapture();
	}
	oText.onmousedown = function(e){
		oText.setCapture();
	}

}

咱們都知道這個在標準瀏覽器上是不行的,咱們暫時無論,只看IE的,你會發現,在IE上,一會兒就老實了,不再處處跑了,這是爲何呢?用上面的解釋就是,由於此時圖片和文字都設了全局鼠標捕獲,無論頁面上有什麼事件發生,都會轉移到它們身上,咱們又

沒有給它們寫move事件,因此就很乖乖的在那裏不動了,明白了嗎?

那咱們給圖片加個自定義的move事件,看看會怎樣?(此時這裏的圖片是絕對定位的,樣式我就不寫了)

window.onload = function(){
	var oImg = document.getElementById("img1");
	oImg.onmousedown = function(ev){
		var ev = ev || event;	
		var disX = ev.clientX - this.offsetLeft;
		var disY = ev.clientY - this.offsetTop;
		if(oImg.setCapture){
			oImg.setCapture();
		}
		document.onmousemove = function(ev){
			var ev = ev || event;
			oImg.style.left = ev.clientX - disX + 'px';
			oImg.style.top = ev.clientY - disY + 'px';
		};
		document.onmouseup = function(ev){
			document.onmousemove = document.onmouseup = null;
			if(oImg.releaseCapture){  //取消全局捕獲
			  oImg.releaseCapture();	
			} 	
		};
					
		return false;	   
	  }
	
	}

運行一下,感受整個世界都平靜了,再也沒有紛爭了,因此瀏覽器都表現一致,這就是一個簡易的拖拽效果,這就是我給我解決方案,不知道大家是否滿意呢!嘻嘻~~

固然,須要特別注意的是(多囉嗦一句):

一、若是是須要阻止全部的默認事件,那麼咱們用return false 和 obj.setCapture() 方法一塊兒用;

二、若是咱們僅僅只是想阻止瀏覽器的默認行爲,能夠用event.preventDefault() 與 obj.setCapture()方法一塊兒用,這裏是考慮到冒泡;

 

好了,基本上就這些了,阻止冒泡方法我也試了一下,仍是挺兼容的,代碼我也貼一下,換算優惠大贈送吧!

if ( e.stopPropagation ){ //標準瀏覽器 
    e.stopPropagation(); 
}else{ 
    //兼容IE的方式來取消事件冒泡 
    window.event.cancelBubble = true; 
} 

以上方法只是我的意見,若有什麼理解的不對的,或者是有錯誤的地方,歡迎批評指正,也歡迎你們跟我交流技術方面的知識,謝謝你們!

ps:若是你看過我寫的pc拖拽效果,請看的時候參考一下本文,哪裏的阻止默認事件寫錯了,記得修改!

相關文章
相關標籤/搜索