I'm building a text editor in my website, the workflow is as follows.
In /list, the user picks an entry they want to edit from a list which takes them to /edit/[article_id].
The user does their work, and then clicks submit.
The server processes the thing, and redirects them back to /edit/[article_id] which by now reflects the edited work. The server also activates a flash message on the page to indicate the edit was successful.
By this point, the user probably wants to go back to /list and clicks the browser's Back button. This will take them back to the editor repeatedly depending on how many times they submitted.
I've tried putting a Back button somewhere on the page, but a good many users simply ignore it.
I'd rather not make the submission posted via AJAX, since that would also affect the flash message system.
What I like to do, is replace the last entry on the history list when the user submits, without changing its length. Is it possible?
Try this
window.location.replace(url);
after using replace() the current page will not be saved in session history, meaning the user won't be able to use the Back button to navigate to it.
Use window.close():
close();
Note: the current tab is implied. This is equivalent:
window.close();
or you can specify a different window.
So:
function close_window() {
if (confirm("Close Window?")) {
close();
}
}
with HTML:
close
or:
close
You return false here to prevent the default behavior for the event. Otherwise the browser will attempt to go to that URL (which it obviously isn't).
Related
Basically what i am trying to do was, whenever a user tries to close the current tab(when he was on my site), i want to display a pop up with three choices about why he was leaving and want to store that choice some where
So i have written the following in main.js which will be loaded through entire site pages
$(document).ready(function() {
// Before closing the current tab, ask user for a reason
$(window).on('beforeunload', function(event){
$('#load_choices_up').click();
event.stopPropagation();
event.preventDefault();
debugger;
});
});
So i have three issues with the above jquery code
*.This code was executing even when i click another link on the same page(I mean if i navigate to another page from current page), but i only want this code to run when the current tab/page was closed(about to close) completely, but not when navigating to another page on my site
*. After this line $('#load_choices_up').click() was executed, a choices pop up was opening as expected, but immediately the default processing of browser(that is closing functionality) was not being stopped with two lines event.stopPropagation(); and event.preventDefault();, i mean these two methods of stopping the behaviour is not working and the browser is closed, but i want to do some processing based on user choices input and then based on that i will close tab.
*. When i used return "Why do you want to leave the page", instead of choices pop up, the browser was displaying different message based on browser type like "You have unsaved changes" in chrome, and some different message in firefox, instead of displaying my custom message
So finally, why event.stopPropagation(); and event.preventDefault(); are not working ? and why i can't able to display my custom message ?
You can't prevent someone from closing the browser. This is for obvious security reasons. Imagine a spam-website preventing you from closing the website while pumping you full of god knows what.
You can at most pull one function like an alert() or a prompt. After a user closes them, the tab will close either way.
beforeUnload is also extremely short-timed. You won't be able to run massive scripts with it, as the user would probably close the tap before any script would run properly. (I tried it with an ajax call, didn't work)
So, even if you're able to get the options you want in there, the moment a user chooses one of the options, you're not going to be able to save it anywhere. Your script will never make it that far.
You can customize the "are you sure?" message like so:
$(document).ready(function() {
window.onbeforeunload = function(e) {
return 'Dialog text here.';
};
});
but again, you can only change the text. It's a browser's native functionality, and you cannot change it.
My goal here is to create a Javascript function in a one-page app that can tell me if the back-button would do anything.
I thought that window.history.length would help me: if the length is same as when the app started, you are at "the beginning" and the function should do nothing.
But no. Imagine that there is one internal link in the app, #a. When you start the app from a new tab, the browser is at #, the length is 1 and you know the back button will do nothing. If you click the #a, you go to #a, the length is 2, and you know the back button would work.
Then, sadly, if you do press the back button, you go back to #, but the length is still 2, because #a is in the "future history".
Help me out. How do I know whether the back button is currently "active"? This is killing me.
(The problem is a little complicated by the idea that there might be a URL from a completely different site in the history. For me, that should be treated as "inactive", even though the back-button would itself actually work.)
Assuming your users never modify the url manually, then the only ways they navigate are by either
Pressing a button/link in your app, or
Pressing the back button
Therefor, you can track this with your own history. Every time a button is clicked, store what page it was on and that a button was clicked (possibly in localstorage). Then, when it loads again you can simply test whether or not where the user is now was reached by hitting a button/link or hitting back. If it was by hitting back, decrement your history. If you have no recorded history, you know the back button either won't work or goes to a different site.
The solution is to store route changes within your app and keep your own state history. This is because of the following:
For security reasons the History object doesn't allow the
non-privileged code to access the URLs of other pages in the session
history, but it does allow it to navigate the session history.
To do this in angular you need to use the $locationChangeSuccess event. See: How to detect browser back button click event using angular? for detecting back button and if its not back button simply append to an array that you track.
i want to know is there any way we can know browser's events.. like : clicking on BACK button, FORWARD button, REFRESH button by javascript.
These specific browser events are not available as it would be vulnerable to severe privacy violations. Privacy is something browser vendors hold sacred and a key selling (proverbial) point. All browsers allow you to know is when a user enters or leaves your page for which Kamui pointed out the technical details.
Within the same site, it's possible to achieve some browser event tracking using cookies and javascript. For example track wether users click on a hyperlink and label it as a forward event and when a user leaves the page without clicking on a hyperlink it could be one of:
browser url input
back action
javascript location.href replace
The location.href replace can be tracked as well when you have full control over all javascript, just use a helper method with tracking code instead of directly chaning location.href.
That leaves browser url input and the back action. With cookies and request headers (getting the referrer) it is possible to get close to finding out the forward and back events, though not 100%, but pragmatically, 99% sure is good enough.
Figuring out the refresh event is easy with request headers (referrer), if the current url matches the referrrer, it's a refresh event.
Now I offer no code or definite solution, but I outlined what you could do to track back, forward and refresh events within a single domain context. It won't be a quick and easy way to implement it and as far as I know, there's no framework in existance that reliably tracks browser events or even comes close to what I described above.
A more common/lazy technique to achieve something similar is to create a single page app, for which there are many frameworks available. Just google single page app framework, but thats a pretty heavy solution with other implications that I won't go into now.
You can not capture (for example run some piece of code when user presses Back button) them, however, you can direct your pages in history by using:
history.go
history.back
history.forward
More about JS History object.
As #sarfraz says you cannot capture the back and forward button clicks but you could call
window.onbeforeunload = function(){alert("you just tried to leave the page");};
which should be triggered when either the back/forward/refresh buttons are clicked to perform an action, unfortunately you can't tell if they are going back or forward. Please note don't alert a message it's really annoying when trying to exit a page.
EDIT
you can also do this in jQuery if you have it
$(window).unload( function () { alert("Bye now!"); } );
I searched a lot to get rid of this problem on the internet but could not find a specific solution despite the problem being discussed in details previously.
The query is simple. My javascript dynamically adds an Iframe to the web page (which displays a feedback form). The problem is that, "after answering", now when the user clicks the back-button of the browser the iframe instead of the browser window is affected i.e. the questionnaire is displayed again. I want the browser back button to behave normally.
This behavior is really annoying and I am having real trouble fixing this.
I am using firefox.
Looking forward to the replies. Please inform me if I should give more details.
Thanks,
Your form has a submit button, which posts the page to the server. The back button will always send the user back to the form regardless of whether you use a iframe or not. The ideal way is to notify the user of a completed action, in this case thank the user for the feedback (using an alert box) and redirect the user to the home page or provide a button in the page saying "Back to Home".
Firefox and IE indeed act like you mentioned, but Chrome do not, and I'd guess other WebKit browsers would do the same.
In Chrome, clicking the Back button will land you where you want to go (the previous URL of the parent frame). i.e. Chrome to not add iframe URL changes in the back button history.
Sadly, I've found no way to force IE and FF to replicate this, so I used the AJAX post approach suggested above by Arun.
Here's my iframe source, which use jQuery to post the form, and replace the whole page with the result of that POST:
<form method="post" onsubmit="postForm(this);return false">
...
</form>
<script type="text/javascript">
function postForm(form) {
$.post(form.action, $(form).serialize(), postCompleted);
}
function postCompleted(data) {
$('html').html(data);
}
</script>
This works in all browsers; clicking the Back button will send you back to the previous URL a seen by the end user, instead of the initial form loaded dynamically in the iframe.
I encountered the same problem: I use a dynamically created iframe to show a "popup" on my page, whose SRC points to another page that has got a form and a submit button. After submitting that page, a JS callback is used to hide the iframe. As you explained, this causes a new entry to be added to the history (on IE at least).
But I found out that removing the iframe element from the DOM (instead of hiding it) results in the unwanted history entry being removed (tested on IE9)! Which is what the user would expect in that situation.
You can observe this yourself on IE9:
Open the back button menu (right-click the back button): you only have one entry for the current page
Press submit in the iframe => the back button menu shows one extra entry for the iframe
Remove the iframe from the DOM => the back button menu no longer shows that entry
Once the user is on my page, I do not want him to refresh the page.
Anytime, the user hits F5 or refresh button on top. He should get an alert saying
You cannot refresh the page.
Also if the user opens a new tab and tries to access the same url in prev tab he should get an alert
You cannot open same page in 2 tabs
Anyway I can do this using JavaScript or jQuery? Point one is really important.
#1 can be implemented via window.onbeforeunload.
For example:
<script type="text/javascript">
window.onbeforeunload = function() {
return "Dude, are you sure you want to leave? Think of the kittens!";
}
</script>
The user will be prompted with the message, and given an option to stay on the page or continue on their way. This is becoming more common. Stack Overflow does this if you try to navigate away from a page while you are typing a post. You can't completely stop the user from reloading, but you can make it sound real scary if they do.
#2 is more or less impossible. Even if you tracked sessions and user logins, you still wouldn't be able to guarantee that you were detecting a second tab correctly. For example, maybe I have one window open, then close it. Now I open a new window. You would likely detect that as a second tab, even though I already closed the first one. Now your user can't access the first window because they closed it, and they can't access the second window because you're denying them.
In fact, my bank's online system tries real hard to do #2, and the situation described above happens all the time. I usually have to wait until the server-side session expires before I can use the banking system again.
You can't prevent the user from refreshing, nor should you really be trying. You should go back to why you need this solution, what's the root problem here?. Start there and find a different way to go about solving the problem. Perhaps is you elaborated on why you think you need to do this it would help in finding such a solution.
Breaking fundamental browser features is never a good idea, over 99.999999999% of the internet works and refreshes with F5, this is an expectation of the user, one you shouldn't break.
Although its not a good idea to disable F5 key you can do it in JQuery as below.
<script type="text/javascript">
function disableF5(e) { if ((e.which || e.keyCode) == 116 || (e.which || e.keyCode) == 82) e.preventDefault(); };
$(document).ready(function(){
$(document).on("keydown", disableF5);
});
</script>
Hope this will help!
Back in the ole days of CGI we had many forms that would trigger various backend actions. Such as text notifications to groups, print jobs, farming of data, etc.
If the user was on a page that was saying "Please wait... Performing some HUGE job that could take some time.". They were more likely to hit REFRESH and this would be BAD!
WHY? Because it would trigger more slow jobs and eventually bog down the whole thing.
The solution?
Allow them to do their form.
When they submit their form... Start your job and then direct them to another page that tells them to wait.
Where the page in the middle actually held the form data that was needed to start the job.
The WAIT page however contains a javascript history destroy. So they can RELOAD that wait page all they want and it will never trigger the original job to start in the background as that WAIT page only contains the form data needed for the WAIT itself.
Hope that makes sense.
The history destroy function also prevented them from clicking BACK and then refreshing as well.
It was very seamless and worked great for MANY MANY years until the non-profit was wound down.
Example:
FORM ENTRY - Collect all their info and when submitted, this triggers your backend job.
RESPONSE from form entry - Returns HTML that performs a redirect to your static wait page and/or POST/GET to another form (the WAIT page).
WAIT PAGE - Only contains FORM data related to wait page as well as javascript to destroy the most recent history. Like (-1 OR -2) to only destroy the most recent pages, but still allows them to go back to their original FORM entry page.
Once they are at your WAIT page, they can click REFRESH as much as they want and it will never spawn the original FORM job on the backend. Instead, your WAIT page should embrace a META timed refresh itself so it can always check on the status of their job. When their job is completed, they are redirected away from the wait page to whereever you wish.
If they do manually REFRESH... They are simply adding one more check of their job status in there.
Hope that helps. Good luck.
No, there isn't.
I'm pretty sure there is no way to intercept a click on the refresh button from JS, and even if there was, JS can be turned off.
You should probably step back from your X (preventing refreshing) and find a different solution to Y (whatever that might be).
Issue #2 now can be solved using BroadcastAPI.
At the moment it's only available in Chrome, Firefox, and Opera.
var bc = new BroadcastChannel('test_channel');
bc.onmessage = function (ev) {
if(ev.data && ev.data.url===window.location.href){
alert('You cannot open the same page in 2 tabs');
}
}
bc.postMessage(window.location.href);
Number (2) is possible by using a socket implementation (like websocket, socket.io, etc.) with a custom heartbeat for each session the user is engaged in. If a user attempts to open another window, you have a javascript handler check with the server if it's ok, and then respond with an error messages.
However, a better solution is to synchronize the two sessions if possible like in google docs.