Reputation: 10964
Is there a way to detect tab close event to clear the localStorage
. I need localStorage
to share data across tabs. window.onbeforeunload
event works fine but it has 2 issues for me:
Like when window is closed the sessionStorage
is cleared. At same time I can clear localStorage
but don't know what event to bind to. I checked a few questions already available but none seems to address this issue there are workarounds by using flags for click on links and form submits but not a clean way to do it. Kindly suggest any solution for this.
Upvotes: 20
Views: 82240
Reputation: 21
PS: Indonesian is my mother language, so I'm sorry if I'm bad at explaining in English.
If you want to keep your last action on tab refresh, but want to clear your last action on tab close, then I really recommend you to use sessionStorage instead of localStorage. Because as I know, if you use localStorage, then your last action will be cleared automatically when you clear your browser history, so that means if you want to clear your last action manually (e.g. you want it to be cleared on tab close), then you have to use localStorage.removeItem(''). BUT... if you use sessionStorage, then your last action will be cleared automatically when you close the tab (even though you never close your browser). And that means your last action will be kept continuously as long as you don't close the tab that loads the url/the page. So if you close that tab (but you don't close your browser) & just load the url/the page again in new tab, then sessionStorage will be in its initial value/state, because your last action that was in sessionStorage was removed automatically when you close the tab.
And if you want an example, here is my full code that I achieve from googling for almost a week. Btw I checked the result using the RUN CODE SNIPPET here, so even though it seems like there's something wrong, just try to save my html file here & open it in your browser. Because I use Visual Studio Code to edit & run the html file, and even if I open that file in Chrome, it works fine. And btw, you can change alert('') to console.log('') if you want your page to be more convenient for user.
function changeVisibility() {
document.getElementById("imgbox2").style.visibility="visible";
images = document.getElementById("imgbox2").style.visibility;
sessionStorage.setItem('imagesVis', images);
alert("Pt.1 CLICKED; images BECOME VISIBLE");
}
// When the user clicks on the button, toggle between hiding and showing the dropdown content
function myFunction() {
document.getElementById("myDropdown").classList.toggle("show");
}
// Close the dropdown menu if the user clicks outside of it
window.onclick = function(event) {
if (!event.target.matches('.dropbtn')) {
var dropdowns = document.getElementsByClassName("dropdown-content");
var i;
for (i = 0; i < dropdowns.length; i++) {
var openDropdown = dropdowns[i];
if (openDropdown.classList.contains('show')) {
openDropdown.classList.remove('show');
}
}
}
}
window.onload = function() {
if(sessionStorage.getItem('imagesVis')) {
document.getElementById("imgbox2").style.visibility="visible";
alert("Pt.1 HAS BEEN CLICKED before; images STAY VISIBLE");
}
else {
document.getElementById("imgbox2").style.visibility="hidden";
alert("Pt.1 NEVER CLICKED before; images STAY HIDDEN");
}
}
.imgbox {
text-align: center;
width: 100%;
margin: auto;
visibility: hidden;
}
button {
width: 100%;
font-size: 16px;
padding: 0;
border: 0;
background-color: grey;
font-family: 'Trebuchet MS', 'Lucida Sans Unicode', 'Lucida Grande', 'Lucida Sans', Arial, sans-serif;
}
/* Dropdown Button */
.dropbtn {
background-color: grey;
border: 4px outset darkgrey;
color: white;
padding: 8px;
font-size: 16px;
cursor: pointer;
font-family: 'Trebuchet MS', 'Lucida Sans Unicode', 'Lucida Grande', 'Lucida Sans', Arial, sans-serif;
font-weight: bold;
}
/* Dropdown button on hover & focus */
.dropbtn:hover, .dropbtn:focus {
background-color: darkgrey;
color: black;
border-style: groove;
}
/* The container <div> - needed to position the dropdown content */
.dropdown {
position: relative;
display: inline-block;
margin: 2em; /* set the position of the dropdown button and its contents */
}
/* Dropdown Content (Hidden by Default) */
.dropdown-content {
display: none;
position: absolute;
background-color: grey;
width: 100%;
box-shadow: 0px 8px 16px 0px rgba(0,0,0,0.2);
z-index: 1;
height: 9.5em;
overflow-y: auto;
overflow-x: hidden;
}
/* Links inside the dropdown */
.dropdown-content a {
color: white;
padding: 5px 10px;
text-decoration: none;
text-align: center;
display: block;
font-family: 'Trebuchet MS', 'Lucida Sans Unicode', 'Lucida Grande', 'Lucida Sans', Arial, sans-serif;
}
/* Change color of dropdown links on hover */
.dropdown-content a:hover {
background-color: darkgrey;
color: black; font-weight: bold;
}
/* Show the dropdown menu (use JS to add this class to the .dropdown-content container when the user clicks on the dropdown button) */
.show {display:block;}
<div class="dropdown">
<button onclick="myFunction()" class="dropbtn">Select Part</button>
<div id="myDropdown" class="dropdown-content">
<button onclick="changeVisibility()"><a href="#">Pt.1</a></button>
<a href="#">Pt.2</a>
<a href="#">Pt.3</a>
<a href="#">Pt.4</a>
<a href="#">Pt.5</a>
<a href="#">Pt.10</a>
<a href="#">Pt.50</a>
<a href="#">Pt.100</a>
</div>
</div>
<div class="imgbox" id="imgbox2">
<div style="background-color: #484444; max-height: 15em; overflow: auto; width: max-content; margin: auto;">
<a style="display: flex; padding: 0; text-align: center;"><img border="0" data-original-height="5469" data-original-width="575" src="https://static.wikia.nocookie.net/naturerules1/images/7/7b/White-persian-cats-picture-id637190306.jpg/revision/latest?cb=20210426035333"></a>
<a style="display: flex; padding: 0; text-align: center;"><img border="0" data-original-height="5458" data-original-width="576" src="https://cdn.pixabay.com/photo/2022/03/16/07/45/turkish-angora-7071832_1280.jpg"></a>
<a style="display: flex; padding: 0; text-align: center;"><img border="0" data-original-height="5466" data-original-width="575" src="https://images.unsplash.com/photo-1612356700139-ba3b20f5f468?ixlib=rb-1.2.1&ixid=MnwxMjA3fDB8MHxzZWFyY2h8Mnx8bHlueHxlbnwwfHwwfHw%3D&w=1000&q=80"></a>
</div>
</div>
Upvotes: 2
Reputation: 1781
I know that that is an old question, but I was just looking for a solution for this, but I couldn't find anything that works properly. Then I came up with a solution which is working fine for me.
What I did was to change the perspective, instead of clearing the local storage when the browser is closed I decided to clear it when it is opened. Users won't see the difference.
I just set a function that check the sessionStorage when the page is loaded, if it is empty the function gets the localStorage cleared; After that it sets a register
to sessionStorage to ensure that the localStorage won't be emptied again just for having the page reloaded.
function clearStorage() {
let session = sessionStorage.getItem('register');
if (session == null) {
localStorage.removeItem('remove');
}
sessionStorage.setItem('register', 1);
}
window.addEventListener('load', clearStorage);
Upvotes: 19
Reputation: 1
I know the question is quite old, but maybe someone still needs it.
This solution is not pretty, but it works quite well:
@HostListener('window:beforeunload')
setToSession(): void {
const token = this.authenticationService.currentTokenValue;
sessionStorage.setItem('tempToken', JSON.stringify(token));
}
@HostListener('window:load')
clearLocalStorage(): void {
const session = sessionStorage.getItem('tempToken');
const user = this.authenticationService.currentTokenValue.user;
const loginMode = user.loginMode;
console.log(loginMode);
if (!loginMode && session == null) {
console.log('TOKEN REMOVED');
localStorage.removeItem('token');
window.location.reload();
}
}
A temporary token is stored in the sessionStorage when closing/reloading, which is queried when reloading. Only if the token is there and the loginMode is false, the storage is deleted.
Upvotes: 0
Reputation: 739
Use cookie to solve the issue, cookie value will automatically remove on browser close, In my case I am using API with token, that stored in localStorage, so when browser close or shutdown it not logout the user, so what I done is
after login just set cookie with key 'loginstatus' and value 'loggedin'
document.cookie = "loginstatus=loggedin";
localStorage.setItem("token", token);
In the method checking user islogged by using localStorage value
isUserLoggedIn(){
let session = localStorage.getItem('token');
if (session == null) {
return false;
}else{
return session
}
}
Modified by removing localStorage token if cookie value doesn't exists
isUserLoggedIn(){
// remove token if cookie not set
if(this.getCookie("loginstatus") != 'loggedin'){
localStorage.removeItem("token");
}
let session = localStorage.getItem('token');
if (session == null) {
return false;
}else{
return session
}
}
and it worked !!!
Upvotes: 3
Reputation: 349
Check if time between window.onbeforeunload event and window.onload event if it is less than 3 seconds keep the session live else remove the token.
window.onbeforeunload = function (e) {
window.localStorage.unloadTime = JSON.stringify(new Date());
};
window.onload = function () {
let loadTime = new Date();
let unloadTime = new Date(JSON.parse(window.localStorage.unloadTime));
let refreshTime = loadTime.getTime() - unloadTime.getTime();
if(refreshTime>3000)//3000 milliseconds
{
window.localStorage.removeItem("token");
}
};
Upvotes: 3
Reputation: 149
Use SessionStorage
instead. It gets cleared off whenever the tab is closed.
Upvotes: 0
Reputation: 10964
I was able to find solution to this and thought of sharing. Since the window.onbeforeunload event fires on browser/tab close but on refresh as well(which i did not want) the thing was my localstorage was being processed at time of rfresh as well. Which I did not want. In order to overcome this I implemented 1 more event handler window.onload that fires only on refresh and not on tab/browser close where I would reset the localStorage as if nothing had happened. The code is:
window.onbeforeunload = function (e) {
window.onunload = function () {
window.localStorage.isMySessionActive = "false";
}
return undefined;
};
window.onload = function () {
window.localStorage.isMySessionActive = "true";
};
I returned undefined in window.onbeforeunload as i did not want a confirm popup to appear on tab/browser close and refresh.
Upvotes: 4