I am wondering if it is possible to create a pop up window with javascript, and then close that window when it loses focus.
Here is my code:
var theWindow;
function launchWindow() {
theWindow=window.open('www.domain.com');
theWindow.onblur = function() {
this.close();
};
}
But that doesn't work at all. Any suggestions?
EDIT: I have discovered a solution that works for me, hopefully it will work for someone else:
var theWindow;
var windows = [];
function launchWindow() {
theWindow=window.open('www.domain.com');
windows.push(theWindow);
window.onfocus = function() {
for (x in windows) {
windows[x].close();
}
};
}
It's not an exact solution to my original problem (It doesn't close the window when it loses focus, but rather it closes it when the main window regains focus) but it works for me.
Is the URL of the popup window from the same domain as the parent? If not, you will likely not be able to attach an event to the new window's onblur event.
Run this from your browser console while viewing StackOverflow to see that it does in fact work when the popup is on the same domain as the originating window:
var theWindow = window.open ("http://www.stackoverflow.com","theWindow");
theWindow.onblur = function() { this.close(); };
window does not have the onblur event
Try to call it's closing by focusing on the <body> of the main window
The problem you may be having is that you are binding the onblur handler before the window has begun loading the page. Once the page is loaded, your onblur handler is gone. You'll need to defer binding long enough to give the page a chance to start loading before binding your event handler:
function launchWindow() {
var theWindow = window.open('www.domain.com');
setTimeout(function() {
theWindow.onblur = function() {
this.close();
};
}, 2000);
}
If you are loading a page in a different domain, you won't be able to bind the onblur handler at all. You'll need to stick to your solution using onfocus.
Related
I've created a fiddle to reproduce the problem.
https://jsfiddle.net/rvwp47Lz/23/
callback: function (key, option) {
console.log("You clicked the test button", this);
// Need the iframe contents to regain focus so the mouse events get caught
setTimeout(function () {
$iframe[0].contentWindow.focus();
}, 100);
}
Basically, what I want to happen is the mouse move events to be caught after closing the context menu.
I can call focus on the iFrame's body or document but it doesn't seem to have any effect.
After you right click one of the items within the iframe and select an item, the mousemove event on the iframes body is no longer called (you can also notice that the hover CSS effect on the items are no longer working).
Ideas?
After some debugging and playing around with jQuery.contextMenu's code it seems the issue actually comes from the itemClick function. I added comments to the code and will add an issue to their github for a possible fix (unless there's some reason they're disabling default here)
// contextMenu item click
itemClick: function (e) {
var $this = $(this),
data = $this.data(),
opt = data.contextMenu,
root = data.contextMenuRoot,
key = data.contextMenuKey,
callback;
// abort if the key is unknown or disabled or is a menu
if (!opt.items[key] || $this.is('.' + root.classNames.disabled + ', .context-menu-submenu, .context-menu-separator, .' + root.classNames.notSelectable)) {
return;
}
// This line is causing the issue since it's preventing the default actions which puts
// mouse events back into place. Chrome must disable mouse move events when the contextmenu event
// gets triggered to improve performance.
//e.preventDefault();
e.stopImmediatePropagation();
I'm trying to implement a popup (bootstrap modal style) that would be triggered as web visitor leaves my site.
I tried different alternatives of:
$(window).bind('beforeunload', function(){
$("#sModal").modal('show');
return 'Take our survey before you leave.';
});
However, it didn't work in FF while worked fine in IE. I had another problem also, that the "Do you want to leave or stay" alert was being displayed on any link click on my website itself, across all browser types, as the whole page was being loaded.
I got around this by looping through all my anchor tags and adding a click listener to remove the beforeunload listener using:
window.onload = function () {
var allLinks = document.getElementsByTagName('a');
for (var i = 0; i < allLinks.length; i++) {
allLinks[i].addEventListener("click", removeBeforeUnload, false);
}
};
The removeBeforeUnload function just used the
$(window).unbind('beforeunload');
Getting back to actually make the popoup/modal appear on all browsers, i used the code from this stackoverflow answer after my document completes loading:
window.onbeforeunload and window.onunload is not working in Firefox , Safari , Opera?
This solution works great across all browsers, however now I cannot unbind this event on any of my local clicked links! I tried everything
window.removeEventlistener('beforeunload',null,false);
window.removeEventlistener('onbeforeunload',null,false);
window.removeBeforeUnload();
window.onbeforeunload = null;
I hope you can point me in the right direction and explain why I cannot unbind this event, that I used from stackoverflow answer.Thanks!
One thought is use a global variable flag and don't do anything in the unload event handler when flag isn't truthy. Set this flag to null or false in link click handlers
Then you don't really need to remove the listener
var doUnload = true;
$('a').click(function(){
doUnload = false;
});
function unloadhandler(){
if(doUnload){
// show modal , return message etc
}else{
// do nothing , don't return anything
}
}
Probably jQuery is adding a 2nd beforeunload event listener, which you can't remove via the DOM API the same way as the one added to the Window by default.
What should work for you is:
var allLinks = $('a');
for (var i = 0; i < allLinks.length; i++) {
$(allLinks[i]).on('click', () => {
$(window).off('beforeunload');
// now add any custom code you want for handling this event
$("#sModal").modal('show');
)};
}
I'm trying to reliably identify when a browser window/tab is activated and deactivated. Normally, window's focus and blur events would do, but the document contains several iframes.
When an iframe is focused, the main window gets unfocused and vice versa, so we have the following possibilities of focus events [(none) means the window/tab is deactivated]:
current focus new focus events
----------------------------------------------------------------------
window (none) window:blur
window iframe window:blur + iframe:focus
iframe (none) iframe:blur
iframe window iframe:blur + window:focus
iframe another iframe iframe:blur + iframe:focus
(none) window window:focus
(none) iframe iframe:focus
It is no problem to register all of these events, as shown by this fiddle. But whenever we switch from the main window to an iframe or vice versa, or between two iframes, the respective blur and focus events both fire; and they fire with a small delay at that.
I am worried about the concurrency here, since the blur handler could go and start doing stuff, but it should have never started because the user actually just switched focus somewhere in between the frames.
Example: A page should do some AJAX requests periodically whenever it is currently not active. That is, it should start requesting whenever the user deactivates the tab and stop requesting as soon as it's activated again. So we bind a function to the blur event that initiates the requests. If the user just clicks on another iframe, blur, and shortly after that, focus is triggered. But the blur handler already fires away, making at least one request before it can be stopped again.
And that's my problem: How can I reliably detect when a user actually (de-)activates a browser window containing iframes, without risking to get a false alarm caused by two immediate blur and focus events?
I wrote a half-baked solution that uses a timeout after a blur event in order to determine if there was an immediate focus event after it (fiddle):
var active = false,
timeout = 50, // ms
lastBlur = 0,
lastFocus = 0;
function handleBlur() {
if (lastBlur - lastFocus > timeout) {
active = false;
}
}
function handleFocus() {
if (lastFocus - lastBlur > timeout) {
active = true;
}
}
$(window).on('focus', function () {
lastFocus = Date.now();
handleFocus();
}).on('blur', function () {
lastBlur = Date.now();
window.setTimeout(handleBlur, timeout);
});
$('iframe').each(function () {
$(this.contentWindow).on('focus', function () {
lastFocus = Date.now();
handleFocus();
}).on('blur', function () {
lastBlur = Date.now();
window.setTimeout(handleBlur, timeout);
});
});
But I believe this could be very problematic, especially on slower machines. Increasing the timeout is also not acceptable to me, 50 ms is really my pain threshold.
Is there a way that doesn't depend on the client to be fast enough?
you could poll for the document.hasFocus() value, which should be true if either an iframe or the main window are focused
setInterval(function checkFocus(){
if( checkFocus.prev == document.hasFocus() ) return;
if(document.hasFocus()) onFocus();
else onBlur();
checkFocus.prev = document.hasFocus();
},100);
function onFocus(){ console.log('browser window activated') }
function onBlur(){ console.log('browser window deactivated') }
I was trying to do it without polling, but the iframe doesn't fire an onblur event (if the browser window is deactivated when the iframe was on focus, I get no events fired), so I ended up needing polling for half of it anyway, but maybe someone can figure something out with this code
function onFocus(){ console.log('browser window activated'); }
function onBlur(){ console.log('browser window deactivated'); }
var inter;
var iframeFocused;
window.focus(); // I needed this for events to fire afterwards initially
addEventListener('focus', function(e){
console.log('global window focused');
if(iframeFocused){
console.log('iframe lost focus');
iframeFocused = false;
clearInterval(inter);
}
else onFocus();
});
addEventListener('blur', function(e){
console.log('global window lost focus');
if(document.hasFocus()){
console.log('iframe focused');
iframeFocused = true;
inter = setInterval(()=>{
if(!document.hasFocus()){
console.log('iframe lost focus');
iframeFocused = false;
onBlur();
clearInterval(inter);
}
},100);
}
else onBlur();
});
I try to fetch all events when the state of a window changes. So far, I use a content script that adds a "resize" listener to the window: window.onresize = function() {...}. This allows me to fetch when a window's state changes to "normal", "maximized" and "fullscreen".
However, I have no idea what to do to also get "minimized". Minimizing a window does not fire "resize" events. I tried to use the onFocusChanged API to add an listener, i.e., chrome.windows.onFocusChanged.addListener(function(windowId) {...}));, but it has its issues. Firstly, if the window I minimize has the focus, windowId = -1 (chrome.windows.WINDOW_ID_NONE), so I cannot fetch the window to readout its state. And secondly, if the window doesn't have the focus, the onFocusChanged event is not fired.
In short, how can I detect when a Chrome window has been minimized?
I think this might help:
chrome.windows.onFocusChanged.addListener(function() {
console.log("Focus changed.");
chrome.windows.getCurrent(function(window){
console.log(window.state);
if(window.state == "normal") {
console.log("It's normal.Stop the watch.");
} else if(window.state == "maximized"){
console.log("It's maximized.Start the watch.");
} else if(window.state == "minimized"){
console.log("It's minimized.Start the watch.");
}
});
});
I want to prevent the page loading when "Editing" on m page occures.
so i got this code
window.onbeforeunload = function() {
return "Are you sure you want to navigate away?";
}
Now i need to unbind this from the page.
is there any methods available ?
Thank you.
You set the handler to null:
window.onbeforeunload = null;
To unbind the event, set it to null:
window.onbeforeunload = null;
It may however be better for program flow to put a condition inside your onbeforeunload handler, so that you have a single function running on page unload:
window.onbeforeunload = function() {
if (myVar == "Editing")
return "Are you sure you want to navigate away?";
}
You should use some flag to check if page is editing values or just navigating to other page
you can follow this thread too
Javascript, controlling an onbeforeunload tag