Unblock window.open pop-up? - javascript

Due to the limitations of a really clunky CMS, I am unable to use
target="_blank"
to open links in new windows. So I'm thinking that my only real solution is to point the link at an intermediary page that opens a new window and then redirects the current window back to the originating page... so something like this:
window.open ("http://www.NewPage.com/");
window.location = "http://www.OldPage.com/";
Of course, most browsers will block the window.open method... so what are my options? Surely there's some clever Javascript trickery to get around this.

No options. You can't do it, and for good reason.
Browsers will only allow window.open() to work when the code that calls it is handling an event like "click". In that circumstance, the browser assumes that the page provides a clickable element and that the user knows there'll be a popup. If a page just calls window.open() for a new window from some context like straight script code, or in a "ready" or "load" event handler, or an XMLHttpRequest callback, then the browser assumes the popup may be something obnoxious.
Some browsers allow the user to relax those rules, but your code can't force that.

You can probably just inject an iframe on the page and position it over everything, but I would really not recommend this.
The browser will be in control of whether the window.open is allowed or not at the end of the day so I wouldn't bother trying to find a solution.

Related

Why is window.open blocked while changing window.location.href is fine?

When the running javascript code is triggered by non-user events (timer, ajax ready, etc.), window.open is blocked (in chrome there will be a popup blocker in the url bar).
But changing window.location.href works fine.
I'm wondering why this decision is made. Are there any spec about this? (I only tested on chrome)
One is trying to open a popup, which people find distracting so browser developers block it.
The other is simply navigating the current page - which would make no sense to block as without that functionality standard links would not work.

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 .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..

Creating new tab / switching between Tabs in Firefox?

I am looking for a way to improve the workflow in a PHP based CMS. There is a lot of switching between the editor mode and the preview mode of the page. The editor mode is huge to load, and so I would like to open the preview mode in a different window.
I don't want to use new windows or an iframe within the current window to keep the workflow simple and to avoid confusion.
Is there a way to explicitly open a new tab (not window), and to jump to that tab from a document, in Firefox? The number of users is limited, so there is the possibility to set up the client with the necessary extensions / permissions.
I know Firefox can be forced to open all links in tabs, but I think that won't cut it, as I still can't address and focus the newly opened window.
Thanks for all the great answers everyone. I have now enough material to decide whether I'll take the greasemonkey approach, rely on the user to set up "open in tabs" and address the window by name, or use a "inline" HTML solution as so many of you suggested. I am accepting the answer that I feel went most effort into.
There is no way to force a window to open as a tab. It's all dependent on the user's preference settings.
I second the answers that say you should do this in HTML using Javascript. Then it can work in all browsers that support JS.
I would put two divs on the page and show/hide each div depending on which tab is selected. If you are clever about this you could trap the click on the tab and determine if the user left-clicked or middle-clicked. If they left click you load that tab on the page. If they middle-click you let the browser open a new tab/window (according to the user's prefs, don't try to force it), and leave the current window unchanged (that is, don't switch to the new tab). The action for clicking on the tab would be to use AJAX to load the contents of the remote document and put it into the tab. Use Javascript to modify the URL before submitting the AJAX request so that the server knows to send a web page fragment instead of the whole page.
The advantage of this dual-natured solution is that the tabbed approach will work the way you want it to work for the majority of cases, but for users with, say, two screens, or who prefer switching between browser tabs, they will still have the flexibility to work in multi-window mode. This can all be done without any browser extensions and it should work equally well in IE as well as Firefox, Opera, etc. Avoid locking yourself into one browser, even one as excellent as Firefox. One day a customer will need to use Opera or Safari and you'll be stuck.
You say you don't want to use an iframe to avoid confusion. Now I don't know about the layout of your website, but I've been using the approach that the editor opens in its own div right next to the content being edited and the content is being live updated as you edit. No need to change tabs.
(If the window is too narrow there are HTML tabs Edit and Preview)
It does not seem to add confusion to the user and for me this approach works really well. Maybe it's worth considering in your case.
What about using iframes and JavaScript?
I know you said you want to avoid 'confusion using iframes', but in my opinion if you really need to load different pages at the same time this is the best option.
In theory, you could create your own tab system using javascript or even better, using jQuery, because its UI module offers pretty cool tab control.
For every tab you could load separate "headerless-footerless" version of your specific admin page inside <iframe> element. If user wanted to modify something different, he will simply click on the tab and bring different iframe.
All this could also be done using AJAX, but iframe solution is quite easy as you just need to load ready page and all postbacks are already handled by original page and separated from master-admin-page.
You might also need to play a little bit to set correct height of your iframe to fit all the content without scrollbars, but this again, is just bit of javascript.
Nope, there's no way to force the opening of a new tab, simply because this would be unsupported by un-tabbed browsing
You can only set it to open a new window, not a new tab.
Greasemonkey springs to mind - a quick google gives open in tabs on left click. I think you could modify that so it only runs on one particular page, and you'd be up up and away.
This question made me wonder if HTML 5 allows that sort of specification, and it doesn't (nothing in one of the other hyperlink attributes, either). A new browsing context is a new browsing context, there's no way to express a preference for tab over window or foreground over background.
You can't force a tab, but if you use a target with a specific name, like target="my_cms_window", many browsers will open this as a new tab. Additionally, they will remember the name and if you use the target repeatedly, put the contents in the same tab. I have found that this works pretty well in the real world.

Ways to detect CTRL-N or when a user opens a new window

How can we detect when a user opens a new window. The user is already authenticated and we make heavy use of sessions.
We were trying to avoid Ctrl+N javascript hooks but maybe that is an option.
I am assuming the request is the exact same URL...with Ctrl+N?
We were trying to avoid ctrl-n javascript hooks
Forget it. Whilst you could in theory try to catch keypress events for ‘n’ with the Control key modifier, there are any number of other ways to open a new window or tab which may be more likely to be used, and you won't be able to catch. File->New Window/Tab, middle click or shift-click link, middle click back/forward buttons, right-click-open-in-new-window, open bookmark in new tab, double-click browser icon...
The user is already authenticated and we make heavy use of sessions.
That shouldn't be a problem in itself. I guess what you mean is that your application is dumping all sorts of page-specific data in the session that it shouldn't have, and now you find the application breaks when you have more than one window open on it? Well, commiserations and happy rewriting.
In the meantime about all you can do is tell the user “please don't try to open two browser windows on the same application”. There are potential ways you can make JavaScript on one page notice that JavaScript is running on another page in the same domain at the same time, generally involving using document.cookie as a inter-page communications conduit. But that's also a bit fragile.
If opening a new window causes a problem in your application, then you should fix the application code to handle it instead of trying to apply an inconsistent and unreliable client-side "bandage". That's my opinion.
Why?
And anyway you can't detect it. User can open new window not only with Ctrl+N but also with File->New Window.
You could possibly put a window count into the session and increment it on window.onload and decrement it on window.onunload.
Imagine me tutting, sucking air through my teeth and going "better you than me, guvna" if you use that, though.
What I have done to solve this issue is when the user authenticates set the window name on valid login.
<script>
window.name = 'oneWindow';
</script>
And then on the master page do a javascript check:
<script>
if (window.history.length == 0 || window.name != 'oneWindow')
//history length to see if it's a new tab or opened in a new window 0 for IE, 1 for FF
//window name to see if it's a CTRL + N new window
</script>
If the check is true then hide/remove the main content of the page and show a message stating they are doing something unsupported.
This works when your login page is not tied into the master page.
If you do not have a master page then I would suggest putting the check on all your pages.
Yes and no,
You'll always see it if a control has focus, else the event is sent directly to the browser and the code on the page never hear about it.
In my experience you can't hijack the browser's shortcut, your mileage may vary. You are likely to know it happened but the browser will do its thing (for obvious reason)
In most browsers, the effect of Ctrl-N is to open a new window at the same URL as the old one and associate it with the same sessionID.
Your best bet would be to modify the back end code if possible and allow for such things. Breaking the browser's feature is never a good thing.

Categories

Resources