React | How to detect Page Refresh (F5) - javascript

I'm using React js. I need to detect page refresh. When user hits refresh icon or press F5, I need to find out the event.
I tried with stackoverflow post by using javascript functions
I used javascript function beforeunload still no luck.
onUnload(event) {
alert('page Refreshed')
}
componentDidMount() {
window.addEventListener("beforeunload", this.onUnload)
}
componentWillUnmount() {
window.removeEventListener("beforeunload", this.onUnload)
}
here I have full code on stackblitz

If you're using React Hook, UseEffect you can put the below changes in your component. It worked for me
useEffect(() => {
window.addEventListener("beforeunload", alertUser);
return () => {
window.removeEventListener("beforeunload", alertUser);
};
}, []);
const alertUser = (e) => {
e.preventDefault();
e.returnValue = "";
};

Place this in the constructor:
if (window.performance) {
if (performance.navigation.type == 1) {
alert( "This page is reloaded" );
} else {
alert( "This page is not reloaded");
}
}
It will work, please see this example on stackblitz.

It is actually quite straightforward, this will add the default alert whenever you reload your page.
In this answer you will find:
Default usage
Alert with validation
1. Default Usage
Functional Component
useEffect(() => {
window.onbeforeunload = function() {
return true;
};
return () => {
window.onbeforeunload = null;
};
}, []);
Class Component
componentDidMount(){
window.onbeforeunload = function() {
return true;
};
}
componentDidUnmount(){
window.onbeforeunload = null;
}
2. Alert with validation
You can put validation to only add alert whenever the condition is true.
Functional Component
useEffect(() => {
if (condition) {
window.onbeforeunload = function() {
return true;
};
}
return () => {
window.onbeforeunload = null;
};
}, [condition]);
Class Component
componentDidMount(){
if (condition) {
window.onbeforeunload = function() {
return true;
};
}
}
componentDidUnmount(){
window.onbeforeunload = null;
}

Your code seems to be working just fine, your alert won't work because you aren't stopping the refresh. If you console.log('hello') the output is shown.
UPDATE ---
This should stop the user refreshing but it depends on what you want to happen.
componentDidMount() {
window.onbeforeunload = function() {
this.onUnload();
return "";
}.bind(this);
}

Unfortunately currently accepted answer cannot be more considered as acceptable since performance.navigation.type is deprecated
The newest API for that is experimental ATM.
As a workaround I can only suggest to save some value in redux (or whatever you use) store to indicate state after reload and on first route change update it to indicate that route was changed not because of refresh.

If you are using either REDUX or CONTEXT API then its quite easy. You can check the REDUX or CONTEXT state variables. When the user refreshes the page it reset the CONTEXT or REDUX state and you have to set them manually again. So if they are not set or equal to the initial value which you have given then you can assume that the page is refreshed.

Related

Enable and disable scroll based on boolean in SvelteKit?

The problem
In SvelteKit, I am trying to disable and enable scroll when my side menu is opened. To do that, I am trying to utilize the {open} variable that is bound to my menu icon with bind:open={open}.
I want to trigger the function enableScroll() when open is true, and trigger the function disableScroll() when open is false.
Both functions work fine. The {open} variable is true when I expect it to, and false when I expect it to when I use console.log().
The problem is that my if-block doesn't respond to {open} changing.
What I've tried
I have tried wrapping my if-block in another function and calling the function changeScroll() on:click.
I have tried
adapting the conditionals: if === true, true, open || null; similarly for the negation.
I have tried using a ternary operator inside of the binding like so: on:click={open ? disableScroll() : enableScroll() }
Currently, my code looks like this:
$: if (open === true) {
onMount(() => {
disableScroll()
})
} else if (open === false) {
onMount(() => {
enableScroll()
})
}
Perhaps I'm using onMount() wrongly? Or somehow I need to change my if statement to make it properly reactive / fix it some other way? I would gladly appreciate some help! Thank you.
onMount only queues a function to run once, when the component is mounted. So running onMount(() => { disableScroll() }) will not run disableScroll if the component has already been rendered -- any subsequent changes to open will not have any affect. This is why your code doesn't work.
However, you do need to do something to prevent your scroll code from running on the server, since window isn't available there. In SvelteKit, you can determine whether you're in the browser by using the browser import from $app/env. This will tell you if it's safe to access browser-only APIs on the document or window. So, you could do something like the following:
<script>
import { onMount } from 'svelte';
import { browser } from '$app/env';
let open;
let scrollTop = null;
let scrollLeft = null;
function disableScroll() {
if (browser) {
scrollTop =
window.pageYOffset || window.document.documentElement.scrollTop;
scrollLeft =
window.pageXOffset || window.document.documentElement.scrollLeft,
window.onscroll = function() {
window.scrollTo(scrollLeft, scrollTop);
}};
}
function enableScroll() {
if (browser) {
window.onscroll = function() {};
}
};
$: if (open) {
disableScroll();
} else {
enableScroll();
}
</script>

How can i handle page refresh event in React.js

I want to make a confirmation before user leaving the page. If he says ok then it would redirect to new page or cancel to leave.
but issue is that when user refresh page using browser refresh btn in google chrome that time below error occur
I tired this code but doesn't work in react.js please help
window.hideWarning = false;
window.addEventListener('beforeunload', (event) => {
if (!window.hideWarning) {
event.preventDefault();
event.returnValue = '';
}
});
Also try this code
window.onbeforeunload = function () { return ''; }.bind(this);
Try this code it's work for me
window.onbeforeunload = function () {
if ("Some condition") {
return '';
}
}.bind(this);
you can also use that
winodow.location.reload(true)
winodow.location.reload(false)
Please use this:
console.log(window.performance.navigation)

How do I make a tab highlight with React

I want to know how to make a Tab highlight everytime an event happens, in this case, it would be a call. So, if the user isn't in my website in the moment, he will know that a event happenned. My useEffect looks like the following:
useEffect(() => {
if (newCall < calls.length){
setHighlight(true)
setNewCall(calls.length)
}
}, [calls.length])
useEffect(() => {
if (newCall < calls.length){
setHighlight(!'your state name')
setInterval(()=>setHighlight(!'your state name'),2000)
setNewCall(calls.length)
}
}, [calls.length])
The above fragment of code sets highlight and so does the user knows that an event has happened and after 2 seconds the highlight will be returned to the initial state.
It seems as though the solution is a combination of:
Browser tab change notification like when you get a new gmail e-mail or a new tweet in Twitter
and
Detect If Browser Tab Has Focus
useEffect(() => {
window.onfocus = function(){
document.title = "Original Title"
}
return () => {
window.onfocus = null;
}
}, []);
useEffect(() => {
if (newCall < calls.length){
document.title = `Original Title (${calls.length} calls)`
}
}, [calls.length])

React - how to open modal when user tries to reload or close window/tab?

I am trying to trigger a modal when user tries to reload the page, visit new URL or close the browser window/tab.
At the moment, the code is successfully triggering the modal, but a default alert window also pops up which I want to get rid of:
Modal appears below the default alert window (using FireFox)
Code:
componentDidMount() {
window.addEventListener('beforeunload', this.onUnload)
}
componentWillUnmount() {
window.removeEventListener('beforeunload', this.onUnload)
}
onUnload(event) {
event.preventDefault();
this.setState({ modalIsOpen: true })
}
There might be a more recommended way to accomplish this, but overriding the alert function should work:
onUnload(event) {
event.preventDefault();
const nativeAlert = window.alert
window.alert = console.log // Temporarily override the alert function
this.setState({ modalIsOpen: true })
window.alert = nativeAlert // Restore it to default
}

javascript html5 history, variable initialization and popState

main question
Is there a javascript way to identify if we are accessing a page for the first time or it is a cause of a back?
My problem
I'm implementing html5 navigation in my ajax driven webpage.
On the main script, I initialize a variable with some values.
<script>
var awnsers=[];
process(awnsers);
<script>
Process(awnsers) will update the view according to the given awnsers, using ajax.
In the funciton that calls ajax, and replaces the view, I store the history
history.pushState(state, "", "");
I defined the popstate also, where I restore the view according to the back. Moreover, I modify the global variable awnsers for the old value.
function popState(event) {
if (event.state) {
state = event.state;
awnsers=state.awnsers;
updateView(state.view);
}
}
Navigation (back and forth) goes corectly except when I go to an external page, and press back (arrving to my page again).
As we are accessing the page, first, the main script is called,the valiable awnsers is updated, and the ajax starts. Meanwile, the pop state event is called, and updates the view. After that the main ajax ends, and updates the view according to empty values.
So I need the code:
<script>
var awnsers=[];
process(awnsers);
<script>
only be called when the user enters the page but NOT when it is a back. Any way to do this?
THanks!
Possible solution
After the first awnser I have thought of a possible solution. Tested and works, whoever, I don't know if there is any cleaner solution. I add the changes that I've done.
First I add:
$(function() {
justLoaded=true;
});
then I modify the popState function, so that is in charge to initialize the variables
function popState(event) {
if (event.state) {
state = event.state;
awnsers=state.awnsers;
updateView(state.view);
} else if(justLoaded){
awnsers=[];
process(awnsers);
}
justLoaded=false;
}
Thats all.
what about using a global variable?
var hasLoaded = false;
// this function can be called by dom ready or window load
function onPageLoad() {
hasLoaded = true;
}
// this function is called when you user presses browser back button and they are still on your page
function onBack() {
if (hasLoaded) {
// came by back button and page was loaded
}
else {
// page wasn't loaded. this is first visit of the page
}
}
Use cookie to store the current state.
yeah! This is what I have:
var popped = (($.browser.msie && parseInt($.browser.version, 10) < 9) ? 'state' in window.history : window.history.hasOwnProperty('state')), initialURL = location.href;
$(window).on('popstate', function (event) {
var initialPop = !popped && location.href === initialURL, state;
popped = true;
if (initialPop) { return; }
state = event.originalEvent.state;
if (state && state.reset) {
if (history.state === state) {
$.ajax({url: state.loc,
success: function (response) {
$(".fragment").fadeOut(100, function () {
$(".fragment").html($(".fragment", response).html()).fadeIn(100);
);
document.title = response.match(/<title>(.*)<\/title>/)[1];
}
});
} else { history.go(0); }
else {window.location = window.location.href; }
});
And:
$.ajax({url:link,
success: function (response) {
var replace = args.replace.split(",");
$.each(replace, function (i) {
replace[i] += ($(replace[i]).find("#video-content").length > 0) ? " #video-content" : "";
var selector = ".fragment "+replace[i];
$(selector).fadeOut(100, function () {
$(selector).html($(selector,response).html()).fadeIn(100, function () {
if (base.children("span[data-video]")[0]) {
if ($.browser.msie && parseInt($.browser.version, 10) === 7) {
$("#theVideo").html("");
_.videoPlayer();
} else {
_.player.cueVideoById(base.children("span[data-video]").attr("data-video"));
}
}
});
});
});
document.title = response.match(/<title>(.*)<\/title>/)[1];
window.history.ready = true;
if (history && history.pushState) { history.pushState({reset:true, loc:link}, null, link); }
}
});

Categories

Resources