I'm using id in every page to scroll the page to some fixed rate whenever the user is redirecting to another page in my website.
My problem is, user needs to double click the browser's back button to redirect the page to previous page, Thus I need to set double click the back button of a browser whenever the user made a single click the browser back button ..
Thank you
Short answer:
document.onmouseover = function() {
//User's mouse is inside the page.
window.innerDocClick = true;
}
document.onmouseleave = function() {
//User's mouse has left the page.
window.innerDocClick = false;
}
window.onhashchange = function() {
if (!window.innerDocClick) {
//Browser back button was clicked
window.history.go(-2);
}
}
Explanation:
The window.history object contains the URLs that the user has visited in the browser. The window.history.go(x) function is used to make the browser go to the relative page in history (so in this case -2 to go back 2 pages).
For detecting when the back button in the browser was pressed, I did a quick search and found the solution to this question here about "How to Detect Browser Back Button event - Cross Browser". The accepted answer has a very full and detailed approach to this which I used to get the above snippet, which you should definitely read.
A quick overview of what the above snippet does, is that it uses 2 events to detect whether the user's mouse is within the page document or not. If it is not in the page document, then this means that the user is not going to be clicking on any in-page elements such as hyperlinks etc. which could also be changing the URL. The 'onhashchange' event detects when the location hash changes, and then checks if the user's mouse is within the document, and if not then executes the double back button.
Please note: this method does not cover if the user presses the backspace key (or any other hotkey). The accepted answer does cover a method of doing this using jQuery, which looks as if it could be modified to work in vanilla JavaScript if jQuery is not wanted.
This method also probably does not cover devices such as iPads or other tablets and mobile devices as they do not have mouse events. Furthermore, swipe events on a mac's trackpad will most likely not be covered. Not having these devices, it is impossible for me to test them.
Related
Hi I'm trying to implement a "Are you sure you want to leave this page?" popup when navigating away from a page with a modified form that hasn't been submitted. The website is a single page app built using a custom framework.
Since all anchor links are handled by the framework it can tell that clicking a side nav link will cause a page change and show a Bootstrap confirm dialog. If the user clicks "Ok" the click goes through and an AJAX call is made to pull the new page content. If they click "Cancel" the modal is dismissed and they stay on the current page.
The part I haven't been able to solve is when a user clicks the "Back" button in their web browser. This triggers the "popstate" event. All navigation/history is managed using the history API since it's a single page app.
The issue is that when someone clicks "Back", the URL changes since "popstate" occurred, then I show my "Are you sure you want to leave?" modal. When the event occurs the URL in your address bar now shows the page you would go to from your history, not the page you're currently viewing. If you click "Cancel" in the Bootstrap confirm you are now left with the wrong URL displayed in your address bar.
event.preventDefault, event.stopPropagation, or return false inside popstate don't stop the URL from changing. AFAIK you can't intercept the "Back" button before "popstate". Trying to window.history.replaceState inside "popstate" doesn't seem to work either.
Does anyone have a solution on how to make this work?
Can you stop the URL from changing in the "popstate" event?
Can you rewrite the history somehow in "popstate" to change the URL back to what it was on the current page and retain the previous entry if you do decide you want it to go through after a modal has been accepted?
Some other solution I haven't thought of?
My original thought was to block the URL change in "popstate" then let the framework trigger the link click to load the new content and change the URL if they click "Yes" but I haven't found a way to do that.
Thanks!
I solved this by doing the following;
Each time a history state is created I generate a timestamp as a guid
The current timestamp is stored in a variable on the top level module
When popstate occurs the incoming history state's guid is compared against the top level modules guid
If the new guid is greater we're going forward, if it's less we're going backward
When the user clicks the back/forward button the hash does change to the incomming URL. If the user clicks cancel it runs history.go( direction ) where direction is 1 or -1 depending on the timestamps. This sets the URL back to what it should be and doesn't do anything weird to the history stack. The top level history variable has a flag to know that we're faking a page change so the link load logic in popstate is not executed.
The only quirk is if the user does click yes to navigate away when that request is sent and returned and a history object is created you do not update the top level module's guid. If you do the guid comparison will always think you're going backward because the new event you just added will always be the highest number. This may not be an issue if you don't make new requests for history URL's but our framework does so it doesn't display stale data like the browser typically does.
It's not ideal since you do see the URL change (no content changes) but so far it seems to work well enough. Another solution I found was to store your own site's history in local/session storage and compare URLs instead of using guid timestamps to find the popstate direction. This won't work in Safari's private browsing mode since both storage layers are disabled so I opted for guid's.
So to start out, this problem happens on some computers but not others, all using the latest version of Chrome.
So I have a table that has URL's embedded in the tr elements in data-url attributes. For some reason, a few PC's don't trigger this click event. Instead of it counting as a click, an scrolling icon shows up, allowing them to scroll the page by moving their cursor around. One thing to note is that this icon indicates you can scroll horizontally, when that isn't the case. A shitty phone picture of the icon, since I couldn't screencap it.
Here's a link to how I detect which mouse button is being used.
$("tr.row-link").on("click", function(e) {
var url = $(this).data("link");
if (url) {
console.log(e.which);
if (e.which === 2) {
window.open($(this).data("link"));
} else {
document.location.href = $(this).data("link");
}
}
});
To be honest, it almost seems like there's a utility installed on these computers that interfere with normal mouse operations in the browser, but I can't seem to find anything installed that would do that.
How can I debug this issue? Honestly this may be a SuperUser question, but I wasn't sure due to the fact it's a discrepancy with click event handling.
As you can see in the image below, I'm not interested in just disabling the click on the back button of the browser. Instead, I want to disable right click on it too. This is one point.
The other part of the question is: How do Gmail handles the same feature. For example, if you login and perform certain actions on some of your mails, in browser's history log, it still maintans every single page which you have used and then you logout of it. Now, if you move on to the browser's history as I did in the image, it shows which all pages you visited but if you click on any one of it, it redirects to the login page. Now, my questions is, "How to handle the clicks on the same (when we get that history)?"
I have read about window.history(), history.pushState(). But they all helped me till handling the back button but not its right click.
I am developing a web application. And I wrote some JS script to be executed on document ready. But in chrome when we click on back button and go back to previous page it is executing all the js script again. But when I use same on firefox it do not execute the JS.
I have an accordion on a page and when user open any accordion and go on one of the link under the accordion and after that if again clicks the back button on the accordion page chrome is closing all the accordions as I have written the script to close all these on document ready. But firefox do not close.
Is there any way to fix this with javascript? So that I can put any condition like if(history.forward.length < 1){ do this....}
You can use the pageshow event to guarantee you always detect navigation to a particular page, regardless of whether the user presses the back/forward button or selects a link, and regardless of which browser is being used.
Then you can perform checks regarding the state of UI and perform logic as required (i.e. modify UI, prevent execution of additional JS).
window.addEventListener('pageshow', function(event) {
// check state of UI, etc.
});
The solution that came to my mind is using sessionStorage to know if it is a first time loading or not. Or even better, you can keep state of your accordions in session storage so it always be the way the user want.
In my case, the iframe was a hidden iframe (width and height zero).
This iframe is just an workaround from legacy system, developed 12 years ago. But still using nowadays on current application.
To solve it, i just redirected the page loaded into iframe to the blank page.
Example:
page_loaded_into_iframe.php
<?php
//do the php stuffs
?>
<script>
alert("hello world");
location.href = "about:blank"; // here, where the the magic happens!
</script>
Once pressed the "back button", the browser will reload a blank page.
Be aware that this might be not applicable if your case is not similar to mine.
In the Chrome Extension you can use the function:
chrome.webNavigation.onCommitted.addListener(function callback)
and in the callback function you may take a look to the arguments:
transitionType + transitionQualifiers
to look for:
"forward_back" The user used the Forward or Back button to initiate the navigation.
For deatils see chrome.webNavigation
Of course, this event can be communicated to the content script with the usual message model (refer to: Message Passing
Suppose I have a link, which would fade out the entire page when link is clicked. The reason I fade out the page is because a next page is about to load, but it is not loaded yet. I can use pointer-events: none which will disable any mouse events until the next page is loaded.
Suppose it was done with the keyboard, I could use the following to prevent double-enter, or to cleanly disable all elements within, for example tab-enter would be disabled this way as well.
parent.onkeydown = fals
parent.onkeyup = fals
parent.onkeypress = fals
function fals() {return false}
This works well for short loads, but if it takes a long time to load, the user may notice the following difficulties.
Cannot tab away from the a tag.
Cannot use several of the keyboard shortcuts which would control the browser.
Able to tab into the disabled area from the address bar.
Is there a modern and slick way to prevent these 3 problems, other than setting an onfocus=blur for all of the child elements? I do not care about IE today.
I think the commonly accepted way of dealing with things like what you're talking about is to use Modal's, which is to say when they click that link, you pop up a box that says 'Processing' or something like that, and you create a fullscreen div with a z-index above everything else so the user can't click / interact with anything else on the screen until you're done doing whatever it is you are doing.
See http://twitter.github.com/bootstrap/javascript.html#modals for an example of what i'm talking about.