let isLeavingPage = false;
let notificationTimeout;
// Request notification permission
function requestPermission() {
if (!('Notification' in window)) {
alert('This browser does not support desktop notifications');
return;
}
Notification.requestPermission().then(permission => {
if (permission === 'granted') {
document.getElementById('status').textContent = 'Notifications enabled!';
setupTabCloseDetection();
}
});
}
// Method 1: Using visibilitychange event
document.addEventListener('visibilitychange', function() {
if (document.visibilityState === 'hidden' && !isLeavingPage) {
tryToSendNotification('Tab Hidden', 'Come back soon!');
}
});
// Method 2: Using beforeunload event
window.addEventListener('beforeunload', function(e) {
isLeavingPage = true;
// Try to send notification before page unloads
tryToSendNotification('Thanks for visiting!', 'We hope to see you again soon!');
// Some browsers require returnValue to be set
e.preventDefault();
e.returnValue = '';
// Set a flag in localStorage that we can check on next visit
localStorage.setItem('lastVisitEndTime', Date.now());
});
// Method 3: Using page show event to detect return after close
window.addEventListener('pageshow', function() {
const lastVisitEndTime = localStorage.getItem('lastVisitEndTime');
if (lastVisitEndTime) {
const timeSinceLastVisit = Date.now() - parseInt(lastVisitEndTime);
// If it's been more than 1 second since last visit, assume it was a genuine close
if (timeSinceLastVisit > 1000) {
tryToSendNotification('Welcome Back!',
'It\'s been ' + Math.round(timeSinceLastVisit/1000) + ' seconds since your last visit');
}
localStorage.removeItem('lastVisitEndTime');
}
});
// Method 4: Using blur event
window.addEventListener('blur', function() {
if (!isLeavingPage) {
// Wait a bit to see if it's a genuine tab close
notificationTimeout = setTimeout(() => {
tryToSendNotification('Missing You!', 'Don\'t forget to come back and finish what you started!');
}, 1000);
}
});
// Method 5: Using focus event to clear timeout
window.addEventListener('focus', function() {
clearTimeout(notificationTimeout);
});
// Helper function to send notifications
function tryToSendNotification(title, body) {
if (Notification.permission === 'granted') {
// Store the notification in a variable to prevent garbage collection
const notification = new Notification(title, {
body: body,
icon: 'https://via.placeholder.com/64',
requireInteraction: true,
tag: 'tab-close' // This ensures only one notification is shown
});
// Handle notification click
notification.onclick = function() {
window.focus();
notification.close();
};
// Store notification reference in localStorage
const notificationData = {
title: title,
body: body,
timestamp: Date.now()
};
localStorage.setItem('lastNotification', JSON.stringify(notificationData));
}
}
// Setup tab close detection systems
function setupTabCloseDetection() {
// Check if there was a previous notification
const lastNotification = localStorage.getItem('lastNotification');
if (lastNotification) {
const data = JSON.parse(lastNotification);
const timeSince = Date.now() - data.timestamp;
// If it's been less than 5 seconds, show a welcome back notification
if (timeSince < 5000) {
tryToSendNotification('Welcome Back!',
'Looks like you were just here ' + Math.round(timeSince/1000) + ' seconds ago');
}
localStorage.removeItem('lastNotification');
}
}
// Initialize on load
if (Notification.permission === 'granted') {
setupTabCloseDetection();
}