Detect if console/devtools is open in all browsers - javascript

I'm trying to create a script which will run when any browser console is opened or closed. Is there any way to detect if the browser console in all browsers (Firefox/IE/Chrome/Safari/Opera) is open or not via JavaScript, jQuery, or any other client-side script?

If you are willing to accept an interference for the user,
you could use the debugger statement, as it is available in all major browsers.
Side note: If the users of your app are interested in console usage, they're probably familiar with dev tools, and will not be surprised by it showing up.
In short, the statement is acting as a breakpoint, and will affect the UI only if the browser's development tools is on.
Here's an example test:
<body>
<p>Devtools is <span id='test'>off</span></p>
<script>
var minimalUserResponseInMiliseconds = 100;
var before = new Date().getTime();
debugger;
var after = new Date().getTime();
if (after - before > minimalUserResponseInMiliseconds) { // user had to resume the script manually via opened dev tools
document.getElementById('test').innerHTML = 'on';
}
</script>
</body>

devtools-detect should do the job. Try the simple demo page.
devtools-detect → detect whether DevTools is open, and its orientation.
Supported Browsers:
DevTools in Chrome, Safari, Firefox & Opera
Caveats:
Doesn't work if DevTools is undocked (separate window), and may show a false positive if you toggle any kind of sidebar.

I don't think it is directly possible in JS for security reasons.But in here
they are claiming that it is possible and is useful for when you want something special to happen when DevTools is open. Like pausing canvas, adding style debug info, etc.
But As #James Hill tell in this, I also thinks even if a browser chose to make this information accessible to the client, it would not be a standard implementation (supported across multiple browsers).
Also can also try this one also here.

It's not possible in any official cross browser way, but if the occasional false positive is acceptable, you can check for a window.onresize event. Users resizing their windows after loading a page is somewhat uncommon. It's even more effective if you expect users will be frequently opening the console, meaning less false positives as a percentage.
window.onresize = function(){
if ((window.outerHeight - window.innerHeight) > 100) {
// console was opened (or screen was resized)
}
}
Credit to https://stackoverflow.com/a/7809413/3774582. Although that question is chrome specific, the concept applies here.
To expand on this, if you need a very low tolerance on false positives, most window resizes will trigger this event dozens of times because it is usually done as a drag action, while opening the console will only trigger this once. If you can detect this, the approach will become even more accurate.
Note: This will fail to detect if the console is already open when the user visits the page, or if the user opens the console in a new window.

(function() {
'use strict';
const el = new Image();
let consoleIsOpen = false;
let consoleOpened = false;
Object.defineProperty(el, 'id', {
get: () => {
consoleIsOpen = true;
}
});
const verify = () => {
console.dir(el);
if (consoleIsOpen === false && consoleOpened === true) {
// console closed
window.dispatchEvent(new Event('devtools-opened'));
consoleOpened = false;
} else if (consoleIsOpen === true && consoleOpened === false) {
// console opened
window.dispatchEvent(new Event('devtools-closed'));
consoleOpened = true;
}
consoleIsOpen = false;
setTimeout(verify, 1000);
}
verify();
})();
window.addEventListener('devtools-opened', ()=>{console.log('opened')});
window.addEventListener('devtools-closed', ()=>{console.log('closed')});
Here is a code that worked for me.

This solution works like a charm
https://github.com/sindresorhus/devtools-detect
if you are not using modules - disable lines
// if (typeof module !== 'undefined' && module.exports) {
// module.exports = devtools;
// } else {
window.devtools = devtools;
// }
and result is then here
window.devtools.isOpen

I for my project use the blur event.
function yourFunction() {}
window.addEventListener('blur',(e)=>{e.preventDefault(); yourFunction()})
This will execute yourFunction when the window loses focus.
For instance when someone opens the DevTools.
Okay seems like it also fires when you try to access a different window... so maybe not the best solution.
Maybe pair it with looking at the width of the browser.
If it chainged you can be pretty sure about it I think

Related

Latest Desktop Firefox recognized as touch device?

has anyone noticed that on the last version of Desktop Firefox, it is recognized as a touch device?
I am using the script below:
function isTouch() {
try{ document.createEvent("TouchEvent"); return true; }
catch(e){ return false;
}
}
if (isTouch()) {
alert('I am touch device!')
}
The script has given me flawless results up until the latest version of Desktop Firefox. Is it a bug? Am I missing something?
Thanks everyone for your time!
edit: False alarm people. I have no idea what went wrong, I tried resetting preferences, disabled all extensions but had no luck.
I finally solved the issue by REFRESHING firefox (lost all my extensions though and had to reinstall).
Thanks for everybody's efforts and sorry for any inconvenience caused.
You are just checking if you can create a specific type of event, not really if you are currently on a touch device.
Here is a more complete isTouchDevice function, which I wrote some time ago based on the core of Modernizr.
/**
* Detect if the current device is a touch device.
* Inspired by Modernizr and hardcore streamlined.
*/
function isTouchDevice() {
var bool;
if( ('ontouchstart' in window) || window.DocumentTouch && document instanceof DocumentTouch ) {
bool = true;
}
else {
var fakeBody = document.createElement( 'fakebody' );
fakeBody.innerHTML += '<style>#media (touch-enabled),(-webkit-touch-enabled),(-moz-touch-enabled),(-o-touch-enabled){#touchtest{top:42px;position:absolute}}</style>';
document.documentElement.appendChild( fakeBody );
var touchTestNode = document.createElement( 'div' );
touchTestNode.id = 'touchtest';
fakeBody.appendChild( touchTestNode );
bool = touchTestNode.offsetTop === 42;
}
return bool;
}
I've had a similar problem, and maybe some people will benefit from the information.
In my case, the Touch events were always detected as positive by Modernizr in Firefox desktop, even if they weren't fired.
In the end, I realized that 'dom.w3c_touch_events.enabled' had a value of '1' even if I didn't set it myself.
It was actually switched on by the "Touch" button in Responsive Design View, but never switched back to '0' even after disabling the Touch events with the very same button.
So I've reported a bug to Mozilla : https://bugzilla.mozilla.org/show_bug.cgi?id=1188270
You will find a test case there.
Basically, the only solution I had to go back to normal is to change manually the value of 'dom.w3c_touch_events.enabled' to '0' in 'about:config'.
And I'm now aware that by enabling Touch events in the Responsive Design View, I will have to manually switch it back after.
Hope this can help some people !

In a Firefox restartless add-on, how do I run code when a new window opens (listen for window open)?

I am starting to build a restartless Firefox add-on and I am having trouble setting up the bootstrap.js. Everyone seems to agree that the core of a bootstrap.js is pretty much boilerplate code, along these lines:
const Cc = Components.classes;
const Ci = Components.interfaces;
function startup() {
let wm = Cc["#mozilla.org/appshell/window-mediator;1"].getService(Ci.nsIWindowMediator);
let windows = wm.getEnumerator("navigator:browser");
while (windows.hasMoreElements()) {
let domWindow = windows.getNext().QueryInterface(Ci.nsIDOMWindow);
// then can control what happens with domWindow.document
}
}
function shutdown() {}
function install() {}
function uninstall() {}
This code works and I can control things in the existing windows. For example, domWindow.alert("text") successfully creates a standard alert saying "text" on every window that is currently open.
However, I can't find any code that will allow me to do things in new windows; i.e. those created after the script runs. What is the correct way to handle the creation of new windows and gain control over them, to the point where I could get another "text" alert from one when it is created?
Edit: Using the nsWindowMediator class and the code sample from MDN, I now have this:
var windowListener = {
onOpenWindow: function (aWindow) {
try {
let domWindow = aWindow.QueryInterface(Ci.nsIInterfaceRequestor).getInterface(Ci.nsIDOMWindowInternal || Ci.nsIDOMWindow);
domWindow.addEventListener("load", function () {
domWindow.removeEventListener("load", arguments.callee, false);
//window has now loaded now do stuff to it
domWindow.alert("text");
}, false);
} catch (err) {
Services.prompt.alert(null, "Error", err);
}
},
onCloseWindow: function (aWindow) {},
onWindowTitleChange: function (aWindow, aTitle) {}
};
function startup(aData, aReason) {
// Load into any existing windows
try {
let wm = Cc["#mozilla.org/appshell/window-mediator;1"].getService(Ci.nsIWindowMediator);
let windows = wm.getEnumerator("navigator:browser");
while (windows.hasMoreElements()) {
let domWindow = windows.getNext().QueryInterface(Ci.nsIDOMWindow);
loadIntoWindow(domWindow);
}
} catch (err) {
Services.prompt.alert(null, "Error", err);
}
Services.wm.addListener(windowListener);
}
However, there is still no output from the onOpenWindow call - the "text" alert does not appear, nor does the error alert in the catch block. I can confirm that onOpenWindow is actually being entered; if I put a Services.prompt.alert() at the beginning of onOpenWindow, I get the alert when I create a new window. Unfortunately, I get an infinite loop of alerts and I have no idea why.
However, I can't find any code that will allow me to do things in new windows; i.e. those created after the script runs. What is the correct way to handle the creation of new windows and gain control over them, to the point where I could get another "text" alert from one when it is created?
The correct way to act on each window when it opens is to use addListener() from nsIWindowMediator. The example code below does this. The nsIWindowMediator is included in Services.jsm and is accessed through Services.wm.addListener(WindowListener). In order to use a window listener, you have to pass it an nsIWindowMediatorListener (ref2) object. An nsIWindowMediatorListener contains three keys: onOpenWindow, onCloseWindow, and onWindowTitleChange. Each should be defined as a function which will be called when the appropriate event occurs.
The MDN document How to convert an overlay extension to restartless in "Step 9: bootstrap.js" contains an example of a basic bootstrap.js which will run the code in the function loadIntoWindow(window) for each currently open browser window and any browser window which opens in the future. I have used code modified from this in a couple of different add-ons. The example is substantially similar to the code you are already using. The example is (slightly modified):
const Ci = Components.interfaces;
Components.utils.import("resource://gre/modules/Services.jsm");
function startup(data,reason) {
// Load this add-ons module(s):
Components.utils.import("chrome://myAddon/content/myModule.jsm");
// Do whatever initial startup stuff is needed for this add-on.
// Code is in module just loaded.
myModule.startup();
// Make changes to the Firefox UI to hook in this add-on
forEachOpenWindow(loadIntoWindow);
// Listen for any windows that open in the future
Services.wm.addListener(WindowListener);
}
function shutdown(data,reason) {
if (reason == APP_SHUTDOWN)
return;
// Unload the UI from each window
forEachOpenWindow(unloadFromWindow);
// Stop listening for new windows to open.
Services.wm.removeListener(WindowListener);
// Do whatever shutdown stuff you need to do on add-on disable
myModule.shutdown();
// Unload the module(s) loaded specific to this extension.
// Use the same URL for your module(s) as when loaded:
Components.utils.unload("chrome://myAddon/content/myModule.jsm");
// HACK WARNING: The Addon Manager does not properly clear all add-on related caches
// on update. In order to fully update images and locales, their
// caches need clearing here.
Services.obs.notifyObservers(null, "chrome-flush-caches", null);
}
function install(data,reason) { }
function uninstall(data,reason) { }
function loadIntoWindow(window) {
/* call/move your UI construction function here */
}
function unloadFromWindow(window) {
/* call/move your UI tear down function here */
}
function forEachOpenWindow(todo) {
// Apply a function to all open browser windows
var windows = Services.wm.getEnumerator("navigator:browser");
while (windows.hasMoreElements())
todo(windows.getNext().QueryInterface(Ci.nsIDOMWindow));
}
var WindowListener = {
onOpenWindow: function(xulWindow) {
var window = xulWindow.QueryInterface(Ci.nsIInterfaceRequestor)
.getInterface(Ci.nsIDOMWindow);
function onWindowLoad() {
window.removeEventListener("load",onWindowLoad);
// Only add UI changes if this is a browser window
if (window.document.documentElement.getAttribute("windowtype")
== "navigator:browser")
loadIntoWindow(window);
}
window.addEventListener("load",onWindowLoad);
},
onCloseWindow: function(xulWindow) { },
onWindowTitleChange: function(xulWindow, newTitle) { }
};
While there is quite a bit more that your might want to do in your bootstrap.js code, the above is organized reasonably well and keeps all of the code to load into the Firefox UI within loadIntoWindow(window) and unloading the UI within unloadFromWindow(window). However, it should be noted that some UI elements you should only be adding/removing once (e.g. australis widgets, like buttons) and other elements (e.g. direct changes to the Firefox DOM) have to be added once in each window.
Unfortunately, I get an infinite loop of alerts and I have no idea why.
One of the significant differences between this example and what you are currently using is the test for the type of window that has opened. This is done so that we are only acting on newly opened windows which are browser windows instead of all newly opened windows:
if (window.document.documentElement.getAttribute("windowtype") == "navigator:browser")
loadIntoWindow(window);
The problem you describe of getting an infinite loop of alert() popups is caused by not checking to make sure that you are only acting on browser windows. The alert() popup is a window. Thus, you are calling alert() for every alert() window you open which, of course, just opens another alert() window on which you call alert(). This is your infinite loop.
Additional references:
1. Working with windows in chrome code
However, I can't find any code that will allow me to do things in new windows
When working with XPCOM objects you generally want to study their interfaces, which are often found on MDN. In this case your starting point would be nsIWindowMediator, since that's the service you're using in line 5.
As you can see it has an addListener function, which takes a parameter implementing nsIWindowMediatorListener. There's a code-example right there on the page.
But let's assume for the moment there isn't a code example. You could search for the interface on MDN, but it isn't listed. The next step would be searching MXR for the .idl. idl = interface description language
Once you got the interface contract you can more or less just implement it in javascript, at least for listeners. Implementing your own xpcom services would be a little more complicated.
Searching the addon sdk can often provide some hints too. In this case they don't seem to be using .addListener, but the file hints at another interesting service, which in turn you can find on MDN: nsIWindowWatcher.
Basically, if you're writing restartless addons you're rummaging through the entrails of firefox and will have to do some detective work to find the exact components you need. If you want something more convenient I would recommend the addon sdk, which provides a more organized but also more restricted set of commonly used APIs

visibilitychange event is not triggered when switching program/window with ALT+TAB or clicking in taskbar

The problem is with the behaviour of the event "visibilitychange".
It's triggered:
- When I switch to a different tab inside the browser window.
When I click in minimize / restore buttons for the browser window.
(this is ok)
It's not triggered:
- When I switch to a different window/program using ALT+TAB.
When I switch to a different window/program clicking on taskbar.
(this SHOULD trigger, because, just like when minimizing, the window's visibility may change)
W3 Page Visibility API Documentation: http://www.w3.org/TR/page-visibility/
There is no definition of "page visibility" regarding ALT+TAB/program switching in the spec sheet. I'm guessing it has something to do in between the OS and the Browser.
TESTED IN
Browsers:
Chrome 40.0.2214.115 m / Firefox 36.0.1 / Internet Explorer 11.0.9600.17107
OS: Windows 8.1
Is there a workaround to fix this behaviour? The implementation is fairly simple, I listen to the "visibilitychange" event using jQuery, and then in its callback, I check for the value of "document.visibilityState", but the problem is that the event is not firing when expected.
$(document).on('visibilitychange', function() {
if(document.visibilityState == 'hidden') {
// page is hidden
} else {
// page is visible
}
});
This can be done without jQuery too, but the ALT+TAB and taskbar switch hide/show expected behaviour is still missing:
if(document.addEventListener){
document.addEventListener("visibilitychange", function() {
// check for page visibility
});
}
I've also tried the ifvisible.js module (https://github.com/serkanyersen/ifvisible.js) but the behaviour is the same.
ifvisible.on('blur', function() {
// page is hidden
});
ifvisible.on('focus', function() {
// page is visible
});
I haven't tested in other browsers because if I can't make it work in Chrome on Windows I really don't care about the other browsers yet.
Any help or suggestions?
UPDATE
I tried using different vendor prefixes for the event name (visibilitychange, webkitvisibilitychange, mozvisibilitychange, msvisibilitychange) but but still the event is not triggered when I switch to a different program in the taskbar or ALT+TAB, or even if I open the start menu thing in windows with the windows key, which covers the whole screen.
I can reproduce the exact same issue in Chrome, Firefox and Internet Explorer.
UPDATE #2
Here's a roundup post I wrote for this issue and a workaround in pure Javascript to solve the encountered problems.
UPDATE #3
Edited to include a copy of the sourced blog post. (see accepted answer)
Here's a roundup post I wrote for this issue and a workaround in pure JavaScript to solve the encountered problems.
Edited to include a copy of the sourced blog post:
In any kind of javascript application we develop there may be a
feature or any change in the application which reacts according to the
current user visibility state, this could be to pause a playing video
when the user ALT+TABs to a different window, tracking stats about how
the users interact with our application, how often does him switch to
a different tab, how long does it take him to return and a lot of
performance improvements that can benefit from this kind of API.
The Page Visibility API provides us with two top-level attributes:
document.hidden (boolean) and document.visibilityState (which could be
any of these strings: “hidden”, “visible”, “prerender”, “unloaded”).
This would not be not good enough without an event we could listen to
though, that’s why the API also provides the useful visibilitychange
event.
So, here’s a basic example on how we could take action on a visibility
change:
function handleVisibilityChange() {
if(document.hidden) {
// the page is hidden
} else {
// the page is visible
}
}
document.addEventListener("visibilitychange", handleVisibilityChange, false);
We could also check for document.visibilityState value.
Dealing with vendor issues George Berkeley by John Smibert
Some of the implementations on some browsers still need that the
attributes or even the event name is vendor-prefixed, this means we
may need to listen to the msvisibilitychange event or check for the
document.webkitHidden or the document.mozHidden attributes. In order
to do so, we should check if any vendor-prefixed attribute is set, and
once we know which one is the one used in the current browser (only if
there’s the need for a prefix), we can name the event and attributes
properly.
Here’s an example approach on how to handle these prefixes:
var browserPrefixes = ['moz', 'ms', 'o', 'webkit'];
// get the correct attribute name
function getHiddenPropertyName(prefix) {
return (prefix ? prefix + 'Hidden' : 'hidden');
}
// get the correct event name
function getVisibilityEvent(prefix) {
return (prefix ? prefix : '') + 'visibilitychange';
}
// get current browser vendor prefix
function getBrowserPrefix() {
for (var i = 0; i < browserPrefixes.length; i++) {
if(getHiddenPropertyName(browserPrefixes[i]) in document) {
// return vendor prefix
return browserPrefixes[i];
}
}
// no vendor prefix needed
return null;
}
// bind and handle events
var browserPrefix = getBrowserPrefix();
function handleVisibilityChange() {
if(document[getHiddenPropertyName(browserPrefix )]) {
// the page is hidden
console.log('hidden');
} else {
// the page is visible
console.log('visible');
}
}
document.addEventListener(getVisibilityEvent(browserPrefix), handleVisibilityChange, false);
Other issues There is a challenging issue around the “Page Visibility”
definition: how to determine if the application is visible or not if
the window focus is lost for another window, but not the actual
visibility on the screen? what about different kinds of visibility
lost, like ALT+TAB, WIN/MAC key (start menu / dash), taskbar/dock
actions, WIN+L (lock screen), window minimize, window close, tab
switching. What about the behaviour on mobile devices?
There’s lots of ways in which we may lose or gain visibility and a lot
of possible interactions between the browser and the OS, therefore I
don’t think there’s a proper and complete “visible page” definition in
the W3C spec. This is the definition we get for the document.hidden
attribute:
HIDDEN ATTRIBUTE On getting, the hidden attribute MUST return true if
the Document contained by the top level browsing context (root window
in the browser’s viewport) [HTML5] is not visible at all. The
attribute MUST return false if the Document contained by the top level
browsing context is at least partially visible on at least one screen.
If the defaultView of the Document is null, on getting, the hidden
attribute MUST return true.
To accommodate accessibility tools that are typically full screen but
still show a view of the page, when applicable, this attribute MAY
return false when the User Agent is not minimized but is fully
obscured by other applications.
I’ve found several inconsistencies on when the event is actually
fired, for example (Chrome 41.0.2272.101 m, on Windows 8.1) the event
is not fired when I ALT+TAB to a different window/program nor when I
ALT+TAB again to return, but it IS fired if I CTRL+TAB and then
CTRL+SHIFT+TAB to switch between browser tabs. It’s also fired when I
click on the minimize button, but it’s not fired if the window is not
maximized and I click my editor window which is behing the browser
window. So the behaviour of this API and it’s different
implementations are still obscure.
A workaround for this, is to compensate taking advantage of the better
implemented focus and blur events, and making a custom approach to the
whole “Page Visibility” issue using an internal flag to prevent
multiple executions, this is what I’ve come up with:
var browserPrefixes = ['moz', 'ms', 'o', 'webkit'],
isVisible = true; // internal flag, defaults to true
// get the correct attribute name
function getHiddenPropertyName(prefix) {
return (prefix ? prefix + 'Hidden' : 'hidden');
}
// get the correct event name
function getVisibilityEvent(prefix) {
return (prefix ? prefix : '') + 'visibilitychange';
}
// get current browser vendor prefix
function getBrowserPrefix() {
for (var i = 0; i < browserPrefixes.length; i++) {
if(getHiddenPropertyName(browserPrefixes[i]) in document) {
// return vendor prefix
return browserPrefixes[i];
}
}
// no vendor prefix needed
return null;
}
// bind and handle events
var browserPrefix = getBrowserPrefix(),
hiddenPropertyName = getHiddenPropertyName(browserPrefix),
visibilityEventName = getVisibilityEvent(browserPrefix);
function onVisible() {
// prevent double execution
if(isVisible) {
return;
}
// change flag value
isVisible = true;
console.log('visible}
function onHidden() {
// prevent double execution
if(!isVisible) {
return;
}
// change flag value
isVisible = false;
console.log('hidden}
function handleVisibilityChange(forcedFlag) {
// forcedFlag is a boolean when this event handler is triggered by a
// focus or blur eventotherwise it's an Event object
if(typeof forcedFlag === "boolean") {
if(forcedFlag) {
return onVisible();
}
return onHidden();
}
if(document[hiddenPropertyName]) {
return onHidden();
}
return onVisible();
}
document.addEventListener(visibilityEventName, handleVisibilityChange, false);
// extra event listeners for better behaviour
document.addEventListener('focus', function() {
handleVisibilityChange(true);
}, false);
document.addEventListener('blur', function() {
handleVisibilityChange(false);
}, false);
window.addEventListener('focus', function() {
handleVisibilityChange(true);
}, false);
window.addEventListener('blur', function() {
handleVisibilityChange(false);
}, false);
I welcome any feedback on this workaround. Some other great sources
for ideas on this subject:
Using the Page Visibility API Using PC Hardware more efficiently in
HTML5: New Web Performance APIs, Part 2 Introduction to the Page
Visibility API Conclusion The technologies of the web are continuously
evolving, we’re still recovering from a dark past where tables where
the markup king, where semantics didn’t mattered, and they weren’t any
standards around how a browser should render a page.
It’s important we push these new standards forward, but sometimes our
development requirements make us still need to adapt to these kind of
transitions, by handling vendor prefixes, testing in different
browsers and differents OSs or depend on third-party tools to properly
identify this differences.
We can only hope for a future where the W3C specifications are
strictly revised, strictly implemented by the browser developer teams,
and maybe one day we will have a common standard for all of us to work
with.
As for the Page Visibility API let’s just kinda cite George Berkeley
and say that:
“being visible” is being perceived.
A working solution is proposed described here: https://stackoverflow.com/a/9502074/698168. It uses a combination of the W3C Page Visibility API, blur/focus and mouse movements. Hidden HTML pages related to Alt+Tab are identified in a probabilistic way (i.e. you cannot determine if your page is hidden with 100% accuracy).
we can do like below when switching between tabs and switching between applications
var pageVisible = true;
function handleVisibilityChange() {
if (document.hidden) {
pageVisible = false;
} else {
pageVisible = true;
}
console.log("handleVisibilityChange")
console.log("pageVisible", pageVisible)
// some function call
}
document.addEventListener("visibilitychange", handleVisibilityChange, false);
window.addEventListener('focus', function() {
pageVisible = true;
// some function call
}, false);
window.addEventListener('blur', function() {
pageVisible = false;
// some function call
}, false);
There's a very simple solution to this I have come across.
You just need to pass false to the useCapture while attaching an event listener to the document. Works like a charm!
document.addEventListener('visibilitychange', function () {
// code goes here
}, false)

window.open() is not working in IE6 and IE7

I have a dotnet application in which I have to close the current window and then open the new window again in runtime. I have used Javascript for it. The code is as follows:
function OpenNewWindow() {
if (ConfirmStartTest()) {
closeWindow();
window.open("OnlineTestFrame.aspx", "_Parent", "model=yes,dailog=no,top=0,height=screen.height,width=screen.width,status=no,toolbar=no,menubar=no,location=no,zoominherit =0,resizable =no,scrollbars=yes,dependent=no,directories=no,taskbar=no,fullscreen=yes");
self.focus();
}
}
//taking the confirmation for starting test
function ConfirmStartTest() {
var result = confirm("Do you want to start the test now?");
return result;
}
//function to close the current window
function closeWindow() {
//var browserName = navigator.appName;
//var browserVer = parseInt(navigator.appVersion);
var ie7 = (document.all && !window.opera && window.XMLHttpRequest) ? true : false;
if (ie7)
{
//This method is required to close a window without any prompt for IE7
window.open('','_parent','');
window.close();
}
else
{
//This method is required to close a window without any prompt for IE6
this.focus();
self.opener = this;
self.close();
}
}
Now, when I am running this application in IE7 and IE6, it is not running. But, in IE8 it is running fine.
This code was working fine for all IE6 n IE7 previously. All of a sudden it is giving error.Its not able to open the new window and stopping abruptly in b/w.
If anyonw has any idea regarding this, please let me know.
This is due to the assignment of self.opener.
12/04 Microsoft started pushing out Security Bulletin MS11-018 via Windows Update which closed of several vulnerabilities related to memory - one of these affected the opener property which no longer can be assigned to.
Nothing like closing a window and expecting anything after it to want to run.
Flow of the code
Function called
Close Window
Open window <-- How can I run if parent is closed?
Focus window
[rant]
What you are trying to do here by forcing a user to use your own pop up window so it has no chrome is very bad user experience. You are deleting a users history. Leave my browser alone! There is a reason why you have to do hacky stuff to close a window, the browsers do not allow you to do it.
[/rant]

How can I detect if a browser is blocking a popup?

Occasionally, I've come across a webpage that tries to pop open a new window (for user input, or something important), but the popup blocker prevents this from happening.
What methods can the calling window use to make sure the new window launched properly?
If you use JavaScript to open the popup, you can use something like this:
var newWin = window.open(url);
if(!newWin || newWin.closed || typeof newWin.closed=='undefined')
{
//POPUP BLOCKED
}
I tried a number of the examples above, but I could not get them to work with Chrome. This simple approach seems to work with Chrome 39, Firefox 34, Safari 5.1.7, and IE 11. Here is the snippet of code from our JS library.
openPopUp: function(urlToOpen) {
var popup_window=window.open(urlToOpen,"myWindow","toolbar=no, location=no, directories=no, status=no, menubar=no, scrollbars=yes, resizable=yes, copyhistory=yes, width=400, height=400");
try {
popup_window.focus();
} catch (e) {
alert("Pop-up Blocker is enabled! Please add this site to your exception list.");
}
}
Update:
Popups exist from really ancient times. The initial idea was to show another content without closing the main window. As of now, there are other ways to do that: JavaScript is able to send requests for server, so popups are rarely used. But sometimes they are still handy.
In the past evil sites abused popups a lot. A bad page could open tons of popup windows with ads. So now most browsers try to block popups and protect the user.
Most browsers block popups if they are called outside of user-triggered event handlers like onclick.
If you think about it, that’s a bit tricky. If the code is directly in an onclick handler, then that’s easy. But what is the popup opens in setTimeout?
Try this code:
// open after 3 seconds
setTimeout(() => window.open('http://google.com'), 3000);
The popup opens in Chrome, but gets blocked in Firefox.
…And this works in Firefox too:
// open after 1 seconds
setTimeout(() => window.open('http://google.com'), 1000);
The difference is that Firefox treats a timeout of 2000ms or less are acceptable, but after it – removes the “trust”, assuming that now it’s “outside of the user action”. So the first one is blocked, and the second one is not.
Original answer which was current 2012:
This solution for popup blocker checking has been tested in FF (v11),
Safari (v6), Chrome (v23.0.127.95) & IE (v7 & v9). Update the
displayError function to handle the error message as you see fit.
var popupBlockerChecker = {
check: function(popup_window){
var scope = this;
if (popup_window) {
if(/chrome/.test(navigator.userAgent.toLowerCase())){
setTimeout(function () {
scope.is_popup_blocked(scope, popup_window);
},200);
}else{
popup_window.onload = function () {
scope.is_popup_blocked(scope, popup_window);
};
}
} else {
scope.displayError();
}
},
is_popup_blocked: function(scope, popup_window){
if ((popup_window.innerHeight > 0)==false){
scope.displayError();
}
},
displayError: function(){
alert("Popup Blocker is enabled! Please add this site to your exception list.");
}
};
Usage:
var popup = window.open("http://www.google.ca", '_blank');
popupBlockerChecker.check(popup);
Hope this helps! :)
One "solution" that will always work regardless of browser company or version is to simply put a warning message on the screen, somewhere close to the control that will create a pop-up, that politely warns the user that the action requires a pop-up and to please enable them for the site.
I know it's not fancy or anything, but it can't get any simpler and only requires about 5 minutes testing, then you can move on to other nightmares.
Once the user has allowed pop-ups for your site, it would also be considerate if you don't overdo the pop-ups. The last thing you want to do is annoy your visitors.
I've tried lots of solutions, but the only one I could come up with that also worked with uBlock Origin, was by utilising a timeout to check the closed status of the popup.
function popup (url, width, height) {
const left = (window.screen.width / 2) - (width / 2)
const top = (window.screen.height / 2) - (height / 2)
let opener = window.open(url, '', `menubar=no, toolbar=no, status=no, resizable=yes, scrollbars=yes, width=${width},height=${height},top=${top},left=${left}`)
window.setTimeout(() => {
if (!opener || opener.closed || typeof opener.closed === 'undefined') {
console.log('Not allowed...') // Do something here.
}
}, 1000)
}
Obviously this is a hack; like all solutions to this problem.
You need to provide enough time in your setTimeout to account for the initial opening and closing, so it's never going to be thoroughly accurate. It will be a position of trial and error.
Add this to your list of attempts.
I combined #Kevin B and #DanielB's solutions.
This is much simpler.
var isPopupBlockerActivated = function(popupWindow) {
if (popupWindow) {
if (/chrome/.test(navigator.userAgent.toLowerCase())) {
try {
popupWindow.focus();
} catch (e) {
return true;
}
} else {
popupWindow.onload = function() {
return (popupWindow.innerHeight > 0) === false;
};
}
} else {
return true;
}
return false;
};
Usage:
var popup = window.open('https://www.google.com', '_blank');
if (isPopupBlockerActivated(popup)) {
// Do what you want.
}
A simple approach if you own the child code as well, would be to create a simple variable in its html as below:
<script>
var magicNumber = 49;
</script>
And then check its existence from parent something similar to following:
// Create the window with login URL.
let openedWindow = window.open(URL_HERE);
// Check this magic number after some time, if it exists then your window exists
setTimeout(() => {
if (openedWindow["magicNumber"] !== 32) {
console.error("Window open was blocked");
}
}, 1500);
We wait for some time to make sure that webpage has been loaded, and check its existence.
Obviously, if the window did not load after 1500ms then the variable would still be undefined.
For some popup blockers this don't work but i use it as basic solution and add try {} catch
try {
const newWindow = window.open(url, '_blank');
if (!newWindow || newWindow.closed || typeof newWindow.closed == 'undefined') {
return null;
}
(newWindow as Window).window.focus();
newWindow.addEventListener('load', function () {
console.info('Please allow popups for this website')
})
return newWindow;
} catch (e) {
return null;
}
This will try to call addEventListaner function but if popup is not open then it will break and go to catch, then ask if its object or null and run rest of code.
By using onbeforeunload event we can check as follows
function popup()
{
var chk=false;
var win1=window.open();
win1.onbeforeunload=()=>{
var win2=window.open();
win2.onbeforeunload=()=>{
chk=true;
};
win2.close();
};
win1.close();
return chk;
}
it will open 2 black windows in background
the function returns boolean value.

Categories