javascript window.location issue with IE and Firefox - javascript

I have some strange behavior on my window.location redirects in IE and Firefox as part of my angular application. When calling window.location = xyz the first time it works fine in IE/FF/Chrome. On the second call which is supposed to go to google.com, Chrome does what it's supposed to, but IE and FF don't do anything. In the IE web console I can see that the navigation was triggered but the page and URL hasn't changed in my window. Now if I press F5 on this page it goes to the page it's supposed to even though the URL at the top is not pointing there (both in IE and FF).
Has anyone ever encountered this problem and knows how to solve it? I've tried all versions of redirecting (window.location, window.location.href, windows.location.assign(), window.location.replace() and also the angular service $window) with no luck.
First call triggered from a button press (working fine in all browsers):
$scope.pressButton = function() {
var url = 'xyz/index.html';
$window.location = url;
};
Second call triggered by a keypress (only works in Chrome):
function exitModule() {
$window.location = 'http://www.google.com';
console.log('window.location'); // still pointing to the old page
}
Update with code calling the exitModule() function:
Note: The application is built with angularjs.
The exitModule() function gets called in all browsers, it's just the redirect which doesn't happen in IE/FF.
HTML:
<body ng-app="myModule" ng-controller="MainCtrl" ng-keydown="keyPress($event);">
JS:
// Handle global key press
$scope.keyPress = function(event){
if(event.which === 27) { // EscapeKey
exitModule();
} else {
$scope.$broadcast('keyPress', event);
}
};

Alright I found the issue and I'm aware that it was almost impossible to figure this out without having the full code available. The above code was a bit simplified therefore it was missing the problem. The function exitModule gets called as soon as a promise is resolved. The call looks like this:
Correct
dataService.saveModule().then(exitModule);
My code was as shown below with the brackets after exitModule which is wrong. I don't quite understand the behavior of FF/IE compared to Chrome though ...but that's for another day.
Wrong
dataService.saveModule().then(exitModule());

Related

How to detect debug extension tab?

While building my Chrome extension, it's often very useful to open a new browser tab and paste this into it:
chrome-extension://xyzfegpcoexyzlibqrpmoeoodfiocgcn/popup.html
When I do that I'm able to work on my popup UI without it ever closing, and without having to click the extension icon at the top right and have the popup sometimes close on me.
Here's the problem: I need my js (referenced by popup.html) to know whether i'm in this debug tab, or whether it's running in "regular mode" (clicking the extension icon and running it normally). I first tried this:
var isDebugExtensionTab = (location.href.indexOf("chrome-extension:") == 0);
That doesn't work because it always evaluates to true -- that is the location.href in all cases, debug tab or regular mode.
How can I detect the difference?
Use chrome.tabs.getCurrent:
Gets the tab that this script call is being made from. May be undefined if called from a non-tab context (for example: a background page or popup view).
var isDebugExtensionTab = false;
chrome.tabs.getCurrent(function(tab) { isDebugExtensionTab = !!tab; });
It's asynchronous as all chrome.* API methods that may accept a callback so the result won't be available until the current context exits. If you need to use the value immediately, do it in the callback:
var isDebugExtensionTab = false;
chrome.tabs.getCurrent(function(tab) {
isDebugExtensionTab = !!tab;
runSomeDebugFunction();
});

Why does setting window.location.href not stop script execution

The following code changes the location to www.bing.com regardless of wether redirect is 1 or any other number. If redirect is 1, it logs "is redirecting" and then redirects to www.bing.com. My best guess is that when href is set a change-event is triggered, but it takes some ticks before it executes. Meanwhilethe first line of code after is still executed. Or? do anyone what happens?
if (redirect == 1) {
console.log("is redirecting");
window.location.href = "http://www.google.com";
}
window.location.href = "http://www.bing.com";
You are setting a property, not calling a method, the difference is important:
window.location.href = "something";
Javascript works asyncronous and event based,
that means the browser doesn't check for the window location changing right when you set the property, but some unpredictable time later.
Sometimes you want exit-events to be triggered or fired when the location changes.
When you compare this to the HTTP location header, the behaviour is the same.
Sometimes you want for example PHP scripts to continue even you send the location change header.
I would say the behaviour is undefined.
When you set the expected url to window.location.href, the current page will actually be in the dying state. And the result of the code written after that is simply unpredictable.
That's because everything after the if is executed as well, but it looks like there's a difference between Chrome and FF (haven't tested in IE).
Example code:
var redirect = 1;
if (redirect == 1) {
console.log("is redirecting");
document.location.assign('https://developer.mozilla.org/');
}
alert('go');
document.location.assign('https://www.bing.com/');
In Chrome 'go' is alerted, and you're redirected to bing.com.
In Firefox, 'go' is alerted, but you're redirected to MDN.
I think, the best thing to do is to wrap the other stuff in an else.

Trying to build safari extension. Not working -.-

So I'm making a Safari extension for my own personal use, and it's not working at all.
I'm trying to skip adf.ly and go directly to the website. But it's not doing anything at all.
I've tried alerting the current URL and the supposed new URL, and they aren't even displaying either.
Global.html
<!DOCTYPE html>
<script type='application/javascript'>
// Skip Adf.ly
// Made by Austen Patterson
// For Safari
//(C) Copyright 2013 Austen Patterson.
safari.application.addEventListener("start", performCommand, true);
safari.application.addEventListener("validate", validateCommand, true);
// Function to perform when event is received
function performCommand(event) {
// Make sure event comes from the button
if (event.command == "skip") {
var url = this.activeBrowserWindow.activeTab.url;
var newurl = url.replace(/http:\/\/adf\.ly\/(\d+)\//, '');
location.href(newurl);
window.open(newurl,"_self");
return;
}
}
</script>
and here is my extension builder settings.
You can't use alert from the global page. You can use console.debug, though, so that should help.
The bigger issue though is that you're treating the global page as though it has access to the page you're trying to modify via the window object. It doesn't work that way. location.href doesn't point to anything and window.open will probably not work from the global scope. (These are both leaky globals, which is something you want to avoid.) I haven't tested it, but something like this should work:
safari.application.addEventListener("beforeNavigate", function adflyChecker(event) {
var url = event.url.replace(/http:\/\/adf\.ly\/(\d+)\//, '');
safari.application.activeBrowserWindow.activeTab.url = url;
}, true);
This has the advantage of working on navigate and not requiring you to manually click the button. If you configure your extension to only apply to adf.ly URLs, then you can be sure that your code only fires when it's appropriate.
More information about the architecture of Safari extensions is available in the docs.

window.onbeforeunload in Chrome: what is the most recent fix?

Obviously, window.onbeforeunload has encountered its fair share of problems with Chrome as I've seen from all the problems I've encountered. What's the most recent work around?
The only thing I've got even close to working is this:
window.onbeforeunload = function () { return "alert" };
However, if I substitute return "alert" with something like alert("blah"), I get nothing from Chrome.
I saw in this question that Google purposefully blocks this. Good for them... but what if I want to make an AJAX call when someone closes the window? In my case, I want to know when someone has left the chatroom on my website, signalled by the window closing.
I want to know if there's a way to either
(a): fix the window.onbeforeunload call so that I can put AJAX in there
or
(b): get some other way of determining that a window has closed in Chrome
Answer:
$(window).on('beforeunload', function() {
var x =logout();
return x;
});
function logout(){
jQuery.ajax({
});
return 1+3;
}
A little mix and match, but it worked for me. The 1+3 makes sure that the logout function is being called (you'll see 4 if it's successful on the popup when you try to leave).
As of Chrome 98.0.4758.109 and Edge 100.0.1185.29, Chromium has not met the standard. There is a bug report filed, but the review is abandoned.
Test with StackBlitz!
Chrome requires returnValue to be a non-null value whether set as the return value from the handler or by reference on the event object.
The standard states that prompting can be controlled by canceling the event or setting the return value to a non-null value.
The standard states that authors should use Event.preventDefault() instead of returnValue.
The standard states that the message shown to the user is not customizable.
window.addEventListener('beforeunload', function (e) {
// Cancel the event as stated by the standard.
e.preventDefault();
// Chrome requires returnValue to be set.
e.returnValue = '';
});
window.location = 'about:blank';
Here's a more straightforward approach.
$(window).on('beforeunload', function() {
return "You should keep this page open.";
});
The returned message can be anything you want, including the empty string if you have nothing to add to the message that Chrome already shows. The result looks like this:
According to MDN,
The function should assign a string value to the returnValue property
of the Event object and return the same string.
This is the following
window.addEventListener( 'beforeunload', function(ev) {
return ev.returnValue = 'My reason';
})
This solved my problem why it wasn't working in my app:
Note that the user must interact with the page somehow (clicking somewhere) before closing its window, otherwise beforeunload is ignored in order not prevent abuse.

iPhone/iTouch not firing (new Image) request onunload

Hey guys, hope someone can help me out.
I'm making a small application to record clicks, which is going great, until I hit the iPhone/iTouch. I'd like to point out, that I've been testing with an iTouch, and I am just presuming the same thing will happen on a iPhone.
What I have at the moment is something similar to this,
<script>
function save(){
// Capture link, with var mycoords containing string
var a = 'http://mydomain.com/capture.php?co='+mycoords;
var img = new Image(1,1);
// Loads link with params, PHP uses $_GET
img.src = a;
alert('f'); // For testing
}
// alerts 'f', does not send data on device
window.onunload = save;
// alerts 'f', does not send data on device
window.onunload = (function(){
save();
});
// Alerts 'f', does not send data on device
window.addEventListener("unload",save,false);
</script>
This code works on all my desktop browsers, including Safari, but on the iTouch/iPhone, no. If I execute the save() function outside any onunload practice, the data sends just fine. I know the onunload works, due to the alerts. But I am absolutely baffled by image object not working in this instance, yet working everywhere else. I have had a good look about on the net, and have found no solution.
Perhaps someone here can maybe give me a solution or an explanation to why this is happening? I would be very grateful. Thank you for your time.
Basically there is no way to detect onunload reliably, as is answered here: javascript unload event in safari mobile?
If you're trying to track clicks, I would suggest adding a click event handler to the link which would first call your save() function and then it could return true or update the document.location.href to take the user to the final link.

Categories

Resources