回答:
onbeforeunloadイベントを試してください:ページがアンロードされる直前に発生します。また、ユーザーが本当に離れたいかどうかを尋ねることもできます。デモを見るonbeforeunload Demo。
または、彼が去ったときにAjaxリクエストを送信することもできます。
Mozilla Developer Networkには、onbeforeunloadのわかりやすい説明と例があります。
ページが汚れている場合(つまり、ユーザーがデータを入力した場合)、ページを離れる前にユーザーに警告する場合:
window.addEventListener('beforeunload', function(e) {
var myPageIsDirty = ...; //you implement this logic...
if(myPageIsDirty) {
//following two lines will cause the browser to ask the user if they
//want to leave. The text of this dialog is controlled by the browser.
e.preventDefault(); //per the standard
e.returnValue = ''; //required for Chrome
}
//else: user is allowed to leave without a warning dialog
});
これが代替ソリューションです。ほとんどのブラウザでは、ナビゲーションコントロール(ナビゲーションバー、タブなど)がページコンテンツ領域の上にあるため、上部からページを離れるマウスポインタを検出し、「離れる前に」を表示できます。ダイアログ。それは完全に控えめだと、それはあなたがユーザーと対話することができます前に、彼らが実際に残すためのアクションを実行します。
$(document).bind("mouseleave", function(e) {
if (e.pageY - $(window).scrollTop() <= 1) {
$('#BeforeYouLeaveDiv').show();
}
});
欠点は、もちろん、ユーザーが実際に離れるつもりであると推測されることですが、ほとんどの場合それは正しいです。
このために私は使用しています:
window.onbeforeunload = function (e) {
}
ページがアンロードされる直前に発生します。
onbeforeunloadますか?
私はこの質問に回答したことを知っていますが、ページロードが発生したときだけでなく、実際のブラウザが閉じられたときに何かをトリガーしたい場合は、次のコードを使用できます。
window.onbeforeunload = function (e) {
if ((window.event.clientY < 0)) {
//window.localStorage.clear();
//alert("Y coords: " + window.event.clientY)
}
};
私の例では、ローカルストレージをクリアし、マウスとy座標でユーザーに警告しています。ブラウザーが閉じている場合のみ、プログラム内からのすべてのページの読み込みで無視されます。
eこの場合は変数)を使用する必要があります: stackoverflow.com/questions/9813445/ …
This feature is non-standard and is not on a standards track. Do not use it on production sites facing the Web: it will not work for every user. developer.mozilla.org/en-US/docs/Web/API/Window/event
これを行う(少しハッキーな)方法の1つは、サイトから離れるリンクをサーバー側へのAJAX呼び出しで置き換え、ユーザーが離れていることを示し、同じJavaScriptブロックを使用してユーザーを外部サイトに連れて行くことですリクエストしました。
もちろん、これは、ユーザーがブラウザウィンドウを閉じるか、新しいURLを入力するだけでは機能しません。
これを回避するには、ページでJavaScriptのsetTimeout()を使用し、数秒ごとにAJAX呼び出しを行う必要があります(ユーザーが離れたかどうかを知りたい速さによって異なります)。
Service Workersのおかげで、ブラウザーがサポートしていれば、クライアント側で純粋にAdamのようなソリューションを実装できます。ハートビート要求を回避するだけです。
// The delay should be longer than the heartbeat by a significant enough amount that there won't be false positives
const liveTimeoutDelay = 10000
let liveTimeout = null
global.self.addEventListener('fetch', event => {
clearTimeout(liveTimeout)
liveTimeout = setTimeout(() => {
console.log('User left page')
// handle page leave
}, liveTimeoutDelay)
// Forward any events except for hearbeat events
if (event.request.url.endsWith('/heartbeat')) {
event.respondWith(
new global.Response('Still here')
)
}
})
setInterval(() => fetch('/heartbeat'), 5000)?
非同期コードを実行する必要がある場合(ユーザーが現在ページにフォーカスしていないというメッセージをサーバーに送信するなど)、イベントbeforeunloadは非同期コードの実行に時間を与えません。非同期の場合、visibilitychangeおよびmouseleaveイベントが最良のオプションであることがわかりました。これらのイベントは、ユーザーがタブを変更したとき、ブラウザーを非表示にしたとき、またはコースターをウィンドウスコープから外したときに発生します。
document.addEventListener('mouseleave', e=>{
//do some async code
})
document.addEventListener('visibilitychange', e=>{
if (document.visibilityState === 'visible') {
//report that user is in focus
} else {
//report that user is out of focus
}
})
何のために、これは私がやったことであり、多分それは記事が古くても他人を助けることができます。
PHP:
session_start();
$_SESSION['ipaddress'] = $_SERVER['REMOTE_ADDR'];
if(isset($_SESSION['userID'])){
if(!strpos($_SESSION['activeID'], '-')){
$_SESSION['activeID'] = $_SESSION['userID'].'-'.$_SESSION['activeID'];
}
}elseif(!isset($_SESSION['activeID'])){
$_SESSION['activeID'] = time();
}
JS
window.setInterval(function(){
var userid = '<?php echo $_SESSION['activeID']; ?>';
var ipaddress = '<?php echo $_SESSION['ipaddress']; ?>';
var action = 'data';
$.ajax({
url:'activeUser.php',
method:'POST',
data:{action:action,userid:userid,ipaddress:ipaddress},
success:function(response){
//alert(response);
}
});
}, 5000);
activeUser.phpへのAjax呼び出し
if(isset($_POST['action'])){
if(isset($_POST['userid'])){
$stamp = time();
$activeid = $_POST['userid'];
$ip = $_POST['ipaddress'];
$query = "SELECT stamp FROM activeusers WHERE activeid = '".$activeid."' LIMIT 1";
$results = RUNSIMPLEDB($query);
if($results->num_rows > 0){
$query = "UPDATE activeusers SET stamp = '$stamp' WHERE activeid = '".$activeid."' AND ip = '$ip' LIMIT 1";
RUNSIMPLEDB($query);
}else{
$query = "INSERT INTO activeusers (activeid,stamp,ip)
VALUES ('".$activeid."','$stamp','$ip')";
RUNSIMPLEDB($query);
}
}
}
データベース:
CREATE TABLE `activeusers` (
`id` int(11) NOT NULL,
`activeid` varchar(20) NOT NULL,
`stamp` int(11) NOT NULL,
`ip` text
) ENGINE=MyISAM DEFAULT CHARSET=utf8;
基本的に5秒ごとにjsはユーザーとユーザーのIPアドレスを追跡するphpファイルに投稿します。アクティブユーザーは、5秒以内にデータベースのタイムスタンプが更新されるデータベースレコードです。古いユーザーはデータベースへの更新を停止します。IPアドレスは、ユーザーが一意であることを確認するために使用されるだけなので、サイト上の2人が同時に1人のユーザーとして登録することはありません。
おそらく最も効率的なソリューションではありませんが、それで十分です。