Why does browser block popup windows in callback but not otherwise - javascript

Strange behavior - Im trying to open a new window in a callback - using Angular but probably a general JS issue.
If I do this:
$window.open('http://google.com', '_blank');
It works fine. However this doesn't as it gets blocked by my browser - I am using Safari 7 and have "block popup windows" checked:
Items.list(function(items) {
$window.open('http://google.com', '_blank')
});
Why does the browser block that and not the other and how can I circumvent this? I played with setTimeout as well as some SO post suggestion to assign $window.open to a variable before calling async but did not work here.

Popup blocker logic often blocks popup windows when the popup window is not opened as a direct consequence of a user action (like a click).
A callback that happens asynchronously is NOT a direct consequence of a user action - it's sometime later and is not directly connected to that action (as the browser sees it), thus the browser may not allow it.
The usual work-around is to open the popup window immediately (as a direct consequence of the user action) and then populate its content later after the asynchronous callback occurs and the content is available.

Does angular 6 support popup window like javascript? I am not looking for a modal window solution. I want to be able move the window to another screen like you can do with JavaScript popup windows. Is there any documentation on that? How can you go about doing it on Angular 5/6 ie to open a pop up window

Related

AngularJS: How to open a file in a new tab?

LIVE DEMO
Given a URI of a file, I'd like to open it in a new tab (not a new window).
It looks like it is not possible to use $window.open(uri, '_blank').
So, I tried the following trick:
var link = angular.element('');
angular.element(document.body).append(link);
link[0].click();
link.remove();
and it works.
But, if I put exactly the same code in a promise callback, it doesn't work anymore (it opens the file in a new window instead).
Any idea what's going on here?
PLAYGROUND HERE
From your code/content, you can't force the browser to open a new tab (rather than a new window, or vice-versa). It's up to the browser settings to force it one way or another.
Anything else would be a security risk.
Let us understand fundamental how pop up blocker work.
If user trigger the function to open a new url, then pop up blocker will allow it(it should applied to any modern browser - at least firefox, chrome)
If not from user (like javascript function in background, promise or any other function trigger not from user), browser will block unless user whitelist the site manually.
This is not working.
function openInNewTab() {
window.open('http://stackoverflow.com','_blank');
}
openInNewTab();//fail
This is working
<h1><button onclick="openInNewTab()">Open In New Tab - working</button></h1>
I created simple plunkr version - http://plnkr.co/edit/QqsEzMtG5oawZsQq0XBV?p=preview
So, to answer your question. It is impossible unless user authorize it (user trigger it or white listed the site).
Quote from firefox -
Pop-up windows, or pop-ups, are windows that appear automatically
without your permission.
https://support.mozilla.org/en-US/kb/pop-blocker-settings-exceptions-troubleshooting
*Open in new tab / new windows not make any difference. Pop up blocker will still always block. It doesn't means that browser will allow if open in new tab. It is just coincidentally for certain browser default the settings in that manner.
Workaround
You can ask user explicitly to trigger the function to open in new tab after the background execution.
You can display message in UI to ask user to open the url.
Example - http://plnkr.co/edit/iyNzpg64DtsrijAGbHlT?p=preview
You can only open new windows inside click event handlers fired by the user.
The reason for this is usability.
I'm not sure if all browsers have this behavior but some browsers do not allow scripts to open windows without the user being noticed. Imagine when you visit a web page and suddenly, the web page opens several windows => it's annoying.
See this DEMO (tested with my Chrome and Firefox), even we trigger click event by script, the browser still blocks the popup.
$("#test").click(function(){
openInNewTab();
});
$("#test").click();
You cannot open a new window inside your ajax success callback because your ajax success is run in another cycle after the click event handler has finished its execution.
See this link for a workaround
if I put exactly the same code in a promise callback, it doesn't work
anymore (it opens the file in a new window instead).
I'm surprised that you're still able to open a new window. But this problem really has a lot of things to do with click events fired by the user.
Your problem is two-fold, and both folds tread on uncertain territory.
In the old days of browsers, window.open did exactly that – open a new window. That's because the concept of tabs hadn't been invented yet. When tabs were introduced, they were treated exactly like windows to improve compatibility, and that tradition continues to this day. That, and the fact that window.open was only standardized very recently, means that JavaScript cannot distinguish between windows and tabs.
There is no "normal" way to specify whether a link should open in a new tab or not. You can use the following hack, though: specify a custom window size to the open call (via the third argument), like so:
window.open('http://example.com', '', 'width=' + screen.width);
This will cause almost all browsers to open a separate window because tabs cannot have custom sizes.
In JavaScript, there are trusted events and untrusted events. Trusted events are, for example, legitimate clicks on a link by the user, whereas an untrusted event would be a manual click() call on a link.
Only trusted event handlers may open new windows/tabs. This is to prevent client-side attacks that crash the browser or confuse a user by rapidly opening a hundred tabs on mouseover or something similar.
Your second example doesn't work because the popup blocker blocks the untrusted event that you triggered via the click(). Although it was caused by a real click, the asynchronous call in-between severs the link to trustedness.
working version
$http.get('https://api.github.com/users/angular').then(openInNewTab());
EDIT----------------
Do not know why but a click() method called from a callback function acts differently than calling it straight.
You can see it here with a set interval example.
That is why I had call the function directly rather than going through a callback.
see it with timer callback
or you can use $window service please see here : http://plnkr.co/edit/8egebfFj4T3LwM0Kd64s?p=preview
angular.module("Demo", []).controller("DemoCtrl", function($scope, $http, $window) {
$scope.uri = 'http://martinfowler.com/ieeeSoftware/whenType.pdf';
function openInNewTab() {
var link = angular.element('');
angular.element(document.body).append(link);
link[0].click();
link.remove();
}
$scope.works = openInNewTab;
$scope.doesntWork = function() {
$http.get('https://api.github.com/users/angular').then($window.open($scope.uri));
};
});
For us the following worked well: http://blog-it.hypoport.de/2014/08/19/how-to-open-async-calls-in-a-new-tab-instead-of-new-window-within-an-angularjs-app/
In short: We remember the reference to the new window and changing the location afterwards.

Window focus for a faster loading pop-up

I am very new to JavaScript. Kindly note that I am trying below issue in a shell which overrides many JavaScript functions.
I have an issue with focusing a window: on a single "click" action, I navigate to a new page which has two JavaScript methods which launch two external URLs which I don't own. For example I launch Yahoo.com and Google.com. My JS launches Yahoo.com in current window (as a page navigate) and Google.com as a pop-up. I WANT Google.com WINDOW TO BE FOCUSED irrespective of loading time of either URLs. The major issue is I cannot use the setTimeout JS function as this function's behavior is altered within the shell and is not usable.
Note: I am using a custom reusable JS function to launch external URLs and I just pass values to that method. So I don't even have access to window object. If I can somehow achieve a time delay without using setTimeout, it will be ideal case. If not, I will have to override that custom JS function, get access to the window object. Even if I have control over those window objects for external URLs, since loading times are different, setting focus to the Google window object is not always giving me the focus on Google window.
(IE6 & 7)
You cannot guarantee the behavior you want, in general; browsers will not let you.
Safari generally ignores requests to focus windows. Firefox and I think Chrome can be configured by their users (not by your code) to allow focus requests, but by default they won't.

window.open and .Net WebServices

I don't know exactly the cause of this symptom but here goes. In our web app, we call window.open to open a new window/tab (internally everyone's is set to open in a new tab). After opening this new tab, IE8 immediately switches the focus to it.
We then integrated a web service, so we call this web service which in turn invokes a callback javascript function when it returns. We are now calling window.open from inside the callback function. When we do this, IE8 opens the new tab but does not switch the focus. Calls to window.focus on the parent page and the child page do nothing.
Now, I know javascript is not threaded, but is this something to do with asynchronicity? Is there a way to get the browser to behave as expected?
I believe that by default, IE will only switch focus to the new tab if it was opened as a result of a user-initiated action such as a click. If the window.open call is not in response to a UI action then IE is probably opening the tab in the background as if it were some kind of popup, though obviously it's not being blocked by the popup blocker.
If you are in an intranet environment and can specify settings, have you tried setting the "Always switch to new tabs when they are created" check box on the tabbed browsing settings dialog?

window .open is not opening on page load in ie8

Hi unable to open window.open on page load in ie8 If I use window.location its not opening in new page please help me out of this.
This is because you're running into the popup blocker. This is a Good Thing(tm) :-) You can only open popups in response to the user taking an explicit action, like clicking something (and then typically only from within the event handler itself), not on things like page load where the unwitting user could be (and historically has been) inundated with dozens of windows opening all over the place. (And even doing it in response to an explicit user action may not be allowed by some blockers.)
Are no-one seeing a big problem with running window.open(window.location.href,'_blank') in the onload handler?
This is systematically a recursive function which would continue until the user manages to close the new window prior to the onload handler running.
I'm not saying that this has anything to do with the problem it might just be that IE8 is clever enough to see this..

How can I trap the unknown cause of a Javascript popup?

I am debugging someone else's web page. There is a link on it which tries to open itself in a popup window, the reason for this is unclear -- there is nothing obvious in the HTML (onclick=foo) to cause this.
Disabling JavaScript means the link opens normally. I have Firefox/Firebug/Dom Inspector and would like to trap whatever JavaScript event is leading to the popup. Since I can't find the code, I'm stuck.
Can Firebug create a sort of global breakpoint to trap all code? Is there some other way to hook into this behaviour and inspect it?
The page in question is http://hijinxmusic.co.uk/ and the problem link is "Green Policy" near the bottom.
Thanks for your time.
The green policy document opens a popup with itself on load:
<body onload="MM_openBrWindow('green%20policy.htm','green','width=900,height=600')">
This is inside green policy.htm
Just to add to David's answer, the function that gets executed on body load in the page at http://hijinxmusic.co.uk/green%20policy.htm essentially calls window.open()
function MM_openBrWindow(theURL,winName,features) { //v2.0
window.open(theURL,winName,features);
}
The bigger problem is that the page that you are trying to open in a new window is the same window that the user is already looking at, which doesn't make any sense. What's more is that if the popup blocker wasn't blocking window creation, you would have an infinite loop of popups (load green policy.html, open a new green policy.html, load green policy.html, etc). Where did you want the popup to happen?
Also, to add to Russ Cam's answer, you can detect when the popup fails to open by checking the return value of window.open. I have used this successfully in Firefox, IE, Opera and Safari (haven't needed to test in Chrome). Using the provided function, this is how I handle blocked popups:
function MM_openBrWindow(theURL,winName,features) { //v2.0
if ( !window.open(theURL, winName, features) ) {
// Window failed to open:
// show a HTML dialog/popover that prompts the user to allow
// popups from this site, along with a `cancel` and `try again`
// button. The `try again` button will attempt to open the
// window again with the provided parameters
dialog.popupBlockedNotice.open(arguments);
}
// Window opened successfully.
}

Categories

Resources