リンクがクリックされたためではなく、ブラウザーまたはブラウザーのタブが閉じられているかどうかを検出するクロスブラウザーJavaScript / jQueryコードはありますか?
sessionStorage
プロパティを使用します。ブラウザを閉じると期限切れになります。w3schools.com/jsref/prop_win_sessionstorage.asp
リンクがクリックされたためではなく、ブラウザーまたはブラウザーのタブが閉じられているかどうかを検出するクロスブラウザーJavaScript / jQueryコードはありますか?
sessionStorage
プロパティを使用します。ブラウザを閉じると期限切れになります。w3schools.com/jsref/prop_win_sessionstorage.asp
回答:
私が正しく理解できたら、いつタブ/ウィンドウが効果的に閉じられるかを知りたいと思います。そうですね、AFAIKはJavascript
その種のものを検出する唯一の方法ですonunload
&onbeforeunload
イベント。
残念なことに(または幸いなことに?)、これらのイベントは、サイトlink
またはブラウザの戻るボタンを離したときにも発生します。だから、これが私ができる最良の答えです。JavaScriptで純粋に純粋に検出できるとは思いませんclose
。私がここで間違っている場合は修正してください。
String
しonbeforeunload
ます。カスタム戻り値をから削除しただけです。したがって、アンロードする前にカスタムメッセージを表示することはできなくなりました。
unload
かを知るにはどうすればよいですか?
何らかの理由で、Webkitベースのブラウザはダイアログボックスの仕様に準拠していません。ほぼクロスワーキングの例は、以下の例に近いものになります。
window.addEventListener("beforeunload", function (e) {
var confirmationMessage = "\o/";
(e || window.event).returnValue = confirmationMessage; //Gecko + IE
return confirmationMessage; //Webkit, Safari, Chrome
});
すべてのブラウザを処理するためのこの例。
シンプルなソリューション
window.onbeforeunload = function () {
return "Do you really want to close?";
};
<body onbeforeunload="ConfirmClose()" onunload="HandleOnClose()">
var myclose = false;
function ConfirmClose()
{
if (event.clientY < 0)
{
event.returnValue = 'You have closed the browser. Do you want to logout from your application?';
setTimeout('myclose=false',10);
myclose=true;
}
}
function HandleOnClose()
{
if (myclose==true)
{
//the url of your logout page which invalidate session on logout
location.replace('/contextpath/j_spring_security_logout') ;
}
}
//これはIE7で機能します。タブを閉じている場合、または1つのタブのみでブラウザーを閉じている場合
window.onunload = "alert('wait')"
してwindow.onbeforeunload = "alert('wait... chrome!')"
使用しましたが、タブを閉じてもどちらも起動しませんでした。
window.onunload = "alert('wait')"
そして、そのようなものは実際には機能しないはずです。「関数は、EventオブジェクトのreturnValueプロパティに文字列値を割り当て、同じ文字列を返す必要があります」。MDNの記事を
ブラウザまたはタブが閉じたときにユーザーを自動的にログアウトする必要がありましたが、ユーザーが他のリンクに移動したときはログアウトしませんでした。また、それが発生したときに確認プロンプトを表示したくありませんでした。これにしばらく、特にIEとEdgeで苦労した後、この回答によるアプローチを基にした後、私がやったこと(IE 11、Edge、Chrome、Firefoxでの作業を確認)。
まず、beforeunload
JSのイベントハンドラーでサーバーのカウントダウンタイマーを開始します。IEとEdgeが正しく動作するには、ajax呼び出しが同期している必要があります。を使用return;
して、確認ダイアログが次のように表示されないようにする必要もあります。
window.addEventListener("beforeunload", function (e) {
$.ajax({
type: "POST",
url: startTimerUrl,
async: false
});
return;
});
タイマーを開始すると、cancelLogout
フラグがfalseに設定されます。ユーザーがページを更新するか、別の内部リンクに移動するcancelLogout
と、サーバーのフラグがtrueに設定されます。タイマーイベントが経過すると、cancelLogout
フラグをチェックして、ログアウトイベントがキャンセルされたかどうかを確認します。タイマーがキャンセルされている場合は、タイマーが停止します。ブラウザまたはタブが閉じられた場合、cancelLogout
フラグはfalseのままになり、イベントハンドラはユーザーをログアウトさせます。
実装メモ:ASP.NET MVC 5を使用しており、オーバーライドされたController.OnActionExecuted()
メソッドでログアウトをキャンセルしています。
OnActionExecuted
ですか?
申し訳ありませんが、既存の回答の1つにコメントを追加することはできませんでしたが、一種の警告ダイアログを実装したい場合に備えて、イベントハンドラー関数には引数-イベントがあることをお伝えしたいと思います。あなたのケースでは、event.preventDefault()を呼び出してページを自動的に離れることを禁止し、独自のダイアログを発行できます。私はこれを、標準の醜くて安全でないalert()を使用するよりも優れたオプションと考えています。私は、kendoWindowオブジェクト(TelerikのKendo UI、kendoGridとkendoEditorを除いて、ほぼ完全にオープンソースです)に基づいて、独自のダイアログボックスセットを個人的に実装しました。jQuery UIからダイアログボックスを使用することもできます。ただし、そのようなことは非同期であり、ハンドラーをすべてのボタンのonclickイベントにバインドする必要がありますが、これはすべて実装するのが非常に簡単です。
ただし、実際のクローズイベントの欠如はひどいことに同意します。たとえば、実際のクローズの場合にのみバックエンドでセッション状態をリセットしたい場合、それは問題です。
同様のタスクについては、使用できます sessionStorage
して、ブラウザのタブが閉じられるまでデータをローカルに保存。
sessionStorage
唯一つのセッション(ブラウザのタブを閉じたときにデータが削除された)のためのオブジェクトデータを格納します。(W3Schoolsの)
これがペンです。
<div id="Notice">
<span title="remove this until browser tab is closed"><u>dismiss</u>.</span>
</div>
<script>
$("#Notice").click(function() {
//set sessionStorage on click
sessionStorage.setItem("dismissNotice", "Hello");
$("#Notice").remove();
});
if (sessionStorage.getItem("dismissNotice"))
//When sessionStorage is set Do stuff...
$("#Notice").remove();
</script>
$(window).unload( function () { alert("Bye now!"); } );
beforeunload
アラートを表示したい場合は試してください。このように:$(window).on('beforeunload', function(){ alert ('Bye now')});
それを使ってみてください:
window.onbeforeunload = function (event) {
var message = 'Important: Please click on \'Save\' button to leave this page.';
if (typeof event == 'undefined') {
event = window.event;
}
if (event) {
event.returnValue = message;
}
return message;
};
$(function () {
$("a").not('#lnkLogOut').click(function () {
window.onbeforeunload = null;
});
$(".btn").click(function () {
window.onbeforeunload = null;
});
});
私はすべてのブラウザで動作する方法を見つけました。
次のバージョンでテスト済み:Firefox 57、Internet Explorer 11、Edge 41、最新のChromeの1つ(私のバージョンは表示されません)
注:onbeforeunloadは、ページを可能な限り何らかの方法(リフレッシュ、ブラウザを閉じる、リダイレクト、リンク、送信など)で終了した場合に発生します。ブラウザーを閉じるときにのみ発生させる場合は、イベントハンドラーをバインドします。
$(document).ready(function(){
var validNavigation = false;
// Attach the event keypress to exclude the F5 refresh (includes normal refresh)
$(document).bind('keypress', function(e) {
if (e.keyCode == 116){
validNavigation = true;
}
});
// Attach the event click for all links in the page
$("a").bind("click", function() {
validNavigation = true;
});
// Attach the event submit for all forms in the page
$("form").bind("submit", function() {
validNavigation = true;
});
// Attach the event click for all inputs in the page
$("input[type=submit]").bind("click", function() {
validNavigation = true;
});
window.onbeforeunload = function() {
if (!validNavigation) {
// -------> code comes here
}
};
});
まだ誰も言及していないため(8年以上後):WebSocketは、閉じたタブを検出するもう1つの効果的な方法です。タブが開いていてホストを指している限り、クライアントはホストへのアクティブなWebSocket接続を維持できます。
警告:このソリューションは、WebSocketがすでに行っていることからの追加の大きなオーバーヘッドを必要としない場合にのみ、プロジェクトでのみ実行可能であることに注意してください。
適切なタイムアウト期間内(たとえば2分)に、サーバー側はWebSocketが切断された後にクライアントが去ったと判断し、アップロードされた一時ファイルの削除など、必要なアクションを実行できます。(私の非常に特殊なユースケースでは、私の目標はlocalhostアプリサーバーを終了することでした、WebSocket接続がドロップしてすべてのCGI / FastCGIアクティビティが終了してから3秒後にことでした。他のキープアライブ接続は影響しません。)
(この回答で推奨されているように)onunloadイベントハンドラーがビーコンで適切に機能するようにするのに問題がありました。タブを閉じるとビーコンはトリガーされないように見え、タブを開くと問題を引き起こす可能性のある方法でビーコンがトリガーされました。WebSocketは、タブが閉じられ、アプリケーション内のページを切り替えると遅延ウィンドウ内で新しいWebSocket接続が開かれるのとほぼ同時に接続が閉じられるため、実行中に発生した問題をより明確に解決しました。
//Detect Browser or Tab Close Events
$(window).on('beforeunload',function(e) {
e = e || window.event;
var localStorageTime = localStorage.getItem('storagetime')
if(localStorageTime!=null && localStorageTime!=undefined){
var currentTime = new Date().getTime(),
timeDifference = currentTime - localStorageTime;
if(timeDifference<25){//Browser Closed
localStorage.removeItem('storagetime');
}else{//Browser Tab Closed
localStorage.setItem('storagetime',new Date().getTime());
}
}else{
localStorage.setItem('storagetime',new Date().getTime());
}
});
こんにちは。ブラウザのローカルストレージとタイムスタンプを使用して、「ブラウザとタブを閉じるイベントの検出」クリックを達成できました。このソリューションを使用することで、皆さんの問題が解決されることを願っています。
最初の調査の結果、ブラウザーを閉じると、ブラウザーがすべてのタブを1つずつ閉じてブラウザーを完全に閉じることがわかりました。したがって、タブを閉じるまでの時間遅延はほとんどないことがわかりました。そのため、この時間遅延を主な検証ポイントとして、ブラウザーとタブのクローズイベントの検出を実現できました。
Chromeブラウザバージョン76.0.3809.132でテストしましたが、動作していました
:)あなたが私の答えが役に立ったと思ったら投票してください...
window.onbeforeunload = function() {
console.log('event');
return false; //here also can be string, that will be shown to the user
}
here also can be string, that will be shown to the user
Firefoxでは機能しませんが、
このような「アンロード」イベントのイベントハンドラーでwindow.closedの助けを借りてそれをチェックすることは可能ですが、タイムアウトの使用が必要です(したがって、遅延が発生したり、ウィンドウが閉じられない場合、結果は保証されません):
JSFiddleの例(Safari、FF、Chrome、Edge、IE11でテスト済み)
var win = window.open('', '', 'width=200,height=50,left=200,top=50');
win.document.write(`<html>
<head><title>CHILD WINDOW/TAB</title></head>
<body><h2>CHILD WINDOW/TAB</h2></body>
</html>`);
win.addEventListener('load',() => {
document.querySelector('.status').innerHTML += '<p>Child was loaded!</p>';
});
win.addEventListener('unload',() => {
document.querySelector('.status').innerHTML += '<p>Child was unloaded!</p>';
setTimeout(()=>{
document.querySelector('.status').innerHTML += getChildWindowStatus();
},1000);
});
win.document.close()
document.querySelector('.check-child-window').onclick = ()=> {
alert(getChildWindowStatus());
}
function getChildWindowStatus() {
if (win.closed) {
return 'Child window has been closed!';
} else {
return 'Child window has not been closed!';
}
}
私は上記のソリューションをすべて試しましたが、特にプロジェクトにいくつかのTelerikコンポーネントがあり、ポップアップウィンドウに[閉じる]ボタンがあり、それが 'beforeunload'イベントを呼び出しているためです。また、ページにTelerikグリッドがある場合(つまり、グリッド内のボタンを意味します)、ボタンセレクターが正しく機能しません。そのため、上記の提案を使用できませんでした。最後にこれは私のために働いた解決策です。_Layout.cshtmlのbodyタグにonUnloadイベントを追加しました。このようなもの:
<body onUnload="LogOff()">
次に、LogOff関数を追加して、Asp.Net MVCの組み込みメソッドであるAccount / LogOffにリダイレクトします。これで、ブラウザーまたはタブを閉じると、LogOffメソッドにリダイレクトされ、ユーザーは戻ったときにログインする必要があります。ChromeとFirefoxの両方でテストしました。そしてそれはうまくいきます!
function LogOff() {
$.ajax({
url: "/Account/LogOff",
success: function (result) {
}
});
}
window.onbeforeunload = function ()
{
if (isProcess > 0)
{
return true;
}
else
{
//do something
}
};
この関数は、ブラウザーでのプロセス中にウィンドウを閉じるかページを更新すると、確認ダイアログボックスを表示します。この関数はすべてのブラウザーで機能します。ajaxプロセスでisProcess varを設定する必要があります。
window.addEventListener("beforeunload", function (e) {
var confirmationMessage = "tab close";
(e || window.event).returnValue = confirmationMessage; //Gecko + IE
sendkeylog(confirmationMessage);
return confirmationMessage; //Webkit, Safari, Chrome etc.
});
sendkeylog
?
@jAndyが述べたように、ウィンドウが閉じられたことを検出するための適切なJavaScriptコードはありません。@Synoの提案から始めました。
私はそのような状況を通過しました、そしてあなたがこれらのステップに従えばあなたはそれを検出することができるでしょう。
Chrome 67以降とFirefox 61以降でテストしました。
var wrapper = function () { //ignore this
var closing_window = false;
$(window).on('focus', function () {
closing_window = false;
//if the user interacts with the window, then the window is not being
//closed
});
$(window).on('blur', function () {
closing_window = true;
if (!document.hidden) { //when the window is being minimized
closing_window = false;
}
$(window).on('resize', function (e) { //when the window is being maximized
closing_window = false;
});
$(window).off('resize'); //avoid multiple listening
});
$('html').on('mouseleave', function () {
closing_window = true;
//if the user is leaving html, we have more reasons to believe that he's
//leaving or thinking about closing the window
});
$('html').on('mouseenter', function () {
closing_window = false;
//if the user's mouse its on the page, it means you don't need to logout
//them, didn't it?
});
$(document).on('keydown', function (e) {
if (e.keyCode == 91 || e.keyCode == 18) {
closing_window = false; //shortcuts for ALT+TAB and Window key
}
if (e.keyCode == 116 || (e.ctrlKey && e.keyCode == 82)) {
closing_window = false; //shortcuts for F5 and CTRL+F5 and CTRL+R
}
});
// Prevent logout when clicking in a hiperlink
$(document).on("click", "a", function () {
closing_window = false;
});
// Prevent logout when clicking in a button (if these buttons rediret to some page)
$(document).on("click", "button", function () {
closing_window = false;
});
// Prevent logout when submiting
$(document).on("submit", "form", function () {
closing_window = false;
});
// Prevent logout when submiting
$(document).on("click", "input[type=submit]", function () {
closing_window = false;
});
var toDoWhenClosing = function() {
//write a code here likes a user logout, example:
//$.ajax({
// url: '/MyController/MyLogOutAction',
// async: false,
// data: {
// },
// error: function () {
// },
// success: function (data) {
// },
//});
};
window.onbeforeunload = function () {
if (closing_window) {
toDoWhenClosing();
}
};
};
resize
、ウィンドウがぼやけていると、常にバインドし続けるということです。100倍ぼやけた場合、リスナーは100人になり、ブラウザの速度が低下します。
これを試してください、これはあなたのために働くと確信しています。
<script src="http://ajax.googleapis.com/ajax/libs/jquery/1.4.2/jquery.min.js"></script>
<script type='text/javascript'>
$(function() {
try{
opera.setOverrideHistoryNavigationMode('compatible');
history.navigationMode = 'compatible';
}catch(e){}
function ReturnMessage()
{
return "wait";
}
function UnBindWindow()
{
$(window).unbind('beforeunload', ReturnMessage);
}
$(window).bind('beforeunload',ReturnMessage );
});
</script>