1. 程式人生 > >js監聽瀏覽器關閉事件(區分重新整理和關閉,相容IE9,10,11,Edge,Chrome和Firefox)

js監聽瀏覽器關閉事件(區分重新整理和關閉,相容IE9,10,11,Edge,Chrome和Firefox)

由於各瀏覽器相容性不同,所以首先要先區分各瀏覽器

var userAgent = navigator.userAgent; //取得瀏覽器的userAgent字串  
var isOpera = userAgent.indexOf("Opera") > -1; //判斷是否Opera瀏覽器  
var isIE = userAgent.indexOf("compatible") > -1 && userAgent.indexOf("MSIE") > -1 && !isOpera; //判斷是否IE瀏覽器
var isIE11 = userAgent.indexOf("rv:11.0") > -1; //判斷是否是IE11瀏覽器
var isEdge = userAgent.indexOf("Edge") > -1 && !isIE; //判斷是否IE的Edge瀏覽器

1.chrome和FireFox

if(!isIE && !isEdge && !isIE11) {//相容chrome和firefox
	var _beforeUnload_time = 0, _gap_time = 0;
	var is_fireFox = navigator.userAgent.indexOf("Firefox")>-1;//是否是火狐瀏覽器
	window.onunload = function (){
		_gap_time = new Date().getTime() - _beforeUnload_time;
		if(_gap_time <= 5){
			$.post('webLoginController.do?delSession2');//瀏覽器關閉
		}else{//瀏覽器重新整理
		}
 	}
	window.onbeforeunload = function (){ 
		_beforeUnload_time = new Date().getTime();
		if(is_fireFox){//火狐關閉執行
			$.post('webLoginController.do?delSession2');//瀏覽器關閉
		} 
	};
}

2.IE9, 10,11,Edge
這四個瀏覽器可以用beforeUnload事件監聽瀏覽器關閉,但是無法區分重新整理和關閉。所以我是用如下方法解決的:
思路:
IE9和10
這兩個瀏覽器在重新整理時先觸發beforeunload事件,再觸發unload事件。而在關閉時只觸發beforeunload事件。所以根據這個特點。在beforeunload時呼叫A方法,將"1"存入session的"flagiii"屬性中,並單開一個執行緒延遲一段時間執行B,在unload時再呼叫C將"flagiii"屬性的值改為0;這樣,在A中延遲一段時間後判斷session中的flagiii屬性的值是否為1,為1的話則是關閉,呼叫B方法(來操作你要操作的事情(我要做的是刪除庫中的內容和session))。為0是重新整理,不呼叫B方法。
js:

if(isIE) {//相容ie8,9,10
	window.onbeforeunload = function() {
		//alert(0);
		flagiii = "1";
		$.ajax({
			type: "post",
			url: "webLoginController.do?A",
			data:{"flagiii": flagiii},
			success: function() {

			},
			async:false
		});
				
	}
	window.onunload = onclose;
	function onclose(){
		flagiii = "0";
		$.ajax({
			type: "post",
			url: "webLoginController.do?storageData",
			data:{"flagiii": flagiii},
			success: function() {
					
			}
		});
	}
}

java:

/**
	 * 關閉瀏覽器時清除session相容IE9和IE10瀏覽器
	 * 讓方法延遲10s執行
	 * create by lucy
	 * 2017-12-19
	 */
	@RequestMapping(params = "A")
	public void A(
			@RequestParam("flagiii") String flagiii, 
			final HttpSession session, 
			final HttpServletRequest req
			) {
		session.setAttribute("flagiii", flagiii);
		Thread thread = new Thread(new Runnable(){
			@Override
			public void run() {
				System.out.println("begin");
				try {
					Thread.sleep(10000);
				} catch (InterruptedException e) {
					e.printStackTrace();
				}
				System.out.println("end");
				delData(session, req);
			}			
		});
		thread.start();	
	}
	public void B(HttpSession session,HttpServletRequest req) {
		String flagiii = (String) session.getAttribute("flagiii");
		if("1".equals(flagiii)) {
			boolean isTrue = false;
			String userId = session.getAttribute("userId").toString();
			isTrue = webLoginService.deleteOnline(userId);
			//將安全日誌插入資料庫   map
			SafeLogInsertDBUtils.safeLogInsertDB(req, session, "關閉瀏覽器", true,StringUtil.LOGINOUT);
		}
	}
	/**
	 * 儲存標記(配合delSessionData方法)
	 * @param flagiii
	 * create by lucy
	 * 2017-12-19
	 */
	@RequestMapping(params = "B")
	public void B(
		HttpSession session,
		@RequestParam("flagiii") String flagiii
		) {
		session.setAttribute("flagiii", flagiii); 
	}

IE11和Edge
思路類似於9和10,IE11和Edge瀏覽器在關閉時先觸發beforeunload,然後再觸發unload事件。而重新整理時先觸發beforeunload事件,再觸發unload事件,再觸發load事件。所以先在頁面load後將"0"存入session,在beforeunload中存入"1"在unload事件中呼叫方法,開啟一個新執行緒,延遲10s執行你想做的事。
js:

var flagiii = "0";
function onloadFun() {
	$.ajax({
 		type: "post",
 		url: "webLoginController.do?storageData",
 		data:{"flagiii": flagiii},
 		success: function() {
					
 		}
 	});
}
	    
if(isIE || isIE11 || isEdge) {
	//頁面載入進來後將flagii存入session 
	onloadFun();
}	
	
if(isIE11 || isEdge) {//相容ie11 edge
	window.onbeforeunload = function() {
		flagiii = "1";
		$.ajax({
			type: "post",
			url: "webLoginController.do?storageData",
			data:{"flagiii": flagiii},
			success: function() {
						
			},
			async:false
		});
	}
	window.onunload = onclose;
	function onclose(){
		$.ajax({
			type: "post",
			url: "webLoginController.do?delSessionData",
			data: {"rnd": Math.random()},
			success: function() {
						
			}
		});
	}
}

java:

/**
	 * 儲存標記(配合delSessionData方法)
	 * @param flagiii
	 * create by lucy
	 * 2017-12-19
	 */
	@RequestMapping(params = "storageData")
	@ResponseBody
	public void storageData(
			HttpSession session,
			@RequestParam("flagiii") String flagiii) {
		session.setAttribute("flagiii", flagiii);
	}
	/**
	 * 關閉瀏覽器時清除session相容IE11和Edge瀏覽器
	 * 讓方法延遲30s執行
	 * create by lucy
	 * 2017-12-19
	 */
	@RequestMapping(params = "delSessionData")
	@ResponseBody
	public void delSessionData(final HttpSession session, final HttpServletRequest req) {	
		Thread thread = new Thread(new Runnable(){
			@Override
			public void run() {
				System.out.println("begin");
				try {
					Thread.sleep(10000);
				} catch (InterruptedException e) {
					e.printStackTrace();
				}
				System.out.println("end");
				delData(session, req);
			}			
		});
		thread.start();	
	}

注意: 在beforeunload事件中的ajax請求使用同步(async: false),否則無法傳送。