How to handle desktop notification in multiple tabs [duplicate] - javascript

This question already has answers here:
Closed 10 years ago.
Possible Duplicate:
Is there a way to detect if a browser window is not currently active?
I have a function that is called every second that I only want to run if the current page is in the foreground, i.e. the user hasn't minimized the browser or switched to another tab. It serves no purpose if the user isn't looking at it and is potentially CPU-intensive, so I don't want to just waste cycles in the background.
Does anyone know how to tell this in JavaScript?
Note: I use jQuery, so if your answer uses that, that's fine :).

In addition to Richard Simões answer you can also use the Page Visibility API.
if (!document.hidden) {
// do what you need
}
This specification defines a means for site developers to
programmatically determine the current visibility state of the page in
order to develop power and CPU efficient web applications.
Learn more (2019 update)
All modern browsers are supporting document.hidden
http://davidwalsh.name/page-visibility
https://developers.google.com/chrome/whitepapers/pagevisibility
Example pausing a video when window/tab is hidden https://web.archive.org/web/20170609212707/http://www.samdutton.com/pageVisibility/

You would use the focus and blur events of the window:
var interval_id;
$(window).focus(function() {
if (!interval_id)
interval_id = setInterval(hard_work, 1000);
});
$(window).blur(function() {
clearInterval(interval_id);
interval_id = 0;
});
To Answer the Commented Issue of "Double Fire" and stay within jQuery ease of use:
$(window).on("blur focus", function(e) {
var prevType = $(this).data("prevType");
if (prevType != e.type) { // reduce double fire issues
switch (e.type) {
case "blur":
// do work
break;
case "focus":
// do work
break;
}
}
$(this).data("prevType", e.type);
})
Click to view Example Code Showing it working (JSFiddle)

I would try to set a flag on the window.onfocus and window.onblur events.
The following snippet has been tested on Firefox, Safari and Chrome, open the console and move between tabs back and forth:
var isTabActive;
window.onfocus = function () {
isTabActive = true;
};
window.onblur = function () {
isTabActive = false;
};
// test
setInterval(function () {
console.log(window.isTabActive ? 'active' : 'inactive');
}, 1000);
Try it out here.

Using jQuery:
$(function() {
window.isActive = true;
$(window).focus(function() { this.isActive = true; });
$(window).blur(function() { this.isActive = false; });
showIsActive();
});
function showIsActive()
{
console.log(window.isActive)
window.setTimeout("showIsActive()", 2000);
}
function doWork()
{
if (window.isActive) { /* do CPU-intensive stuff */}
}

All of the examples here (with the exception of rockacola's) require that the user physically click on the window to define focus. This isn't ideal, so .hover() is the better choice:
$(window).hover(function(event) {
if (event.fromElement) {
console.log("inactive");
} else {
console.log("active");
}
});
This'll tell you when the user has their mouse on the screen, though it still won't tell you if it's in the foreground with the user's mouse elsewhere.

If you are trying to do something similar to the Google search page when open in Chrome, (where certain events are triggered when you 'focus' on the page), then the hover() event may help.
$(window).hover(function() {
// code here...
});

Related

Disable browser back action using jquery

I am developing an online testing app and it is required that during the test, users cannot be allowed to refresh page neither go back until the test is ended. I have successfully been able to disable refresh action in jquery through all means possible (to the best of my knowledge) using the following code:
$(window).bind({
beforeunload: function(ev) {
ev.preventDefault();
},
unload: function(ev) {
ev.preventDefault();
}
});
But I have been having troubles disabling the back action on all browsers, the best solution I got on SO conflicts with the code I have above, it is given below:
window.onload = function () {
if (typeof history.pushState === "function") {
history.pushState("jibberish", null, null);
//alert("Reloaded");
window.onpopstate = function () {
history.pushState('newjibberish', null, null);
// Handle the back (or forward) buttons here
// Will NOT handle refresh, use onbeforeunload forthis.
};
}
else {
var ignoreHashChange = true;
window.onhashchange = function () {
if (!ignoreHashChange) {
ignoreHashChange = true;
window.location.hash = Math.random();
// Detect and redirect change here
// Works in older FF and IE9
// * it does mess with your hash symbol (anchor?) pound sign
// delimiter on the end of the URL
}
else {
ignoreHashChange = false;
}
};
}
}
The solution above suits my purpose in disabling the back button but conflicts with the page refresh prevention handler above.
I am out of ideas on what to do and I have also searched a long time for a solution to this but found none yet. Any help would be greatly appreciated, even if it takes a totally different approach to solving the problem, I wouldn't mind at all.
Thanks everyone
UPDATE
I never realized that doing things this way breaks a lot of ethical rules, anyway, I've thought about it and figured out something else to do when if the page is refreshed or back button pressed (either using keyboard or the browser controls). I want to redirect to a url which will end the current exam session. I believe that's possible, hence I think the solution I seek is to get the best way to achieve this. Redirecting to another url if back button or refresh button is pressed (both using the browser controls and the keyboard).
I have tried many options but none worked except this-
//Diable Browser back in all Browsers
if (history.pushState != undefined) {
history.pushState(null, null, location.href);
}
history.back();
history.forward();
window.onpopstate = function () {
history.go(1);
};
With regards to the update I posted in my question, I have been able to solve my problem. Here's what I did (just modifying my existing code a little and removing the window.onload listener I had initially):
$(window).bind({
beforeunload: function(ev) {
window.location.replace("my_url_goes_in_here");
},
unload: function(ev) {
window.location.replace("my_url_goes_in_here");
}
});
This construct works for both page refresh and back actions done in anyway (either using keyboard or browser controls for the any of them).
However, I've not yet tested in any other browser other than firefox 47.0, but I'm glad it's working for now all the same.
Thanks for all your comments, they were extremely helpful
Using javascript if you have two pages page1 and page2 and (page1 redirect to page2) and you want to restrict the user from getting back to page1, just put this code at page1.
<script src="http://ajax.googleapis.com/ajax/libs/jqueryui/1.10.2/jquery-ui.min.js"></script>
<script src="http://ajax.googleapis.com/ajax/libs/jquery/1.9.1/jquery.min.js"></script>
<script>
$(document).ready(function () {
function disableBack() {
window.history.forward()
}
window.onload = disableBack();
window.onpageshow = function (evt) {
if (evt.persisted)
disableBack()
}
});
</script>

How to get javascript Timer to stop when not viewing tab/window

I am running a page with a timer that I'm using to run in a iframe of a page so that I know that someone was on there actually with window in focus paying attention to screen and if leave have the timer pause until back viewing the window or in focus.
I have 4 timer files: timer.css timer.js timer.php & timerb.js
I believe I would execute it in the following file and code, but that is where I am stuck as don't know what or where to add it for sure and no luck yet and why here asking so please take a look and let me know if you can help.
File: timer.js
function adTimer() {
timer++;
if(timer == fulltimer) {
var show="Click "+key;
$("#buttons").fadeIn();
$("#timer").html(show);
}
else {
setTimeout(adTimer, 1000);
}
$("#bar").width((timer/fulltimer)*200);
}
This could be enough for you:
$(window).blur(function(){
//your code for inactive
});
$(window).focus(function(){
//your code for active
});
or non jQuery solution (https://stackoverflow.com/a/1760283)
window.onblur = function () {
//your code for inactive
};
window.onfocus = function () {
//your code for active
};
if not try Page Visibility API (answer already here https://stackoverflow.com/a/1060034)
Just wondering why all that implementation if JQuery already provide a timeout. did you try to use set Timeout.
http://www.sitepoint.com/settimeout-example/

start animation when tab/page active

I have simple question about start animation of page when tab or page is active. I mean when user open the page but start browering another website until our website loads. then he click over our website tab and then animation loads. I've seen this on many websites but never know what's the trick to do this.
for the demo go to: http://swiftideas.net/
open website and go to another page, when website fully loaded, click on swiftideas website. You will see that a fade effect saying "HELLO. WE ARE SWIFT IDEAS" and Menu Also!
But it starts when you come over the page. pretty intelligent! Any clue how to achrive this?
I hope you people also like this!
From: How to tell if browser/tab is active
You would use the focus and blur events of the window:
var interval_id;
$(window).focus(function() {
if (!interval_id)
interval_id = setInterval(hard_work, 1000);
});
$(window).blur(function() {
clearInterval(interval_id);
interval_id = 0;
});
To Answer the Commented Issue of "Double Fire" and stay within jQuery ease of use:
$(window).on("blur focus", function(e) {
var prevType = $(this).data("prevType");
if (prevType != e.type) { // reduce double fire issues
switch (e.type) {
case "blur":
// do work
break;
case "focus":
// do work
break;
}
}
$(this).data("prevType", e.type);
})

Vertical scroll bug in Google Chrome

jsFiddle
Trying to vertically scroll the div child in Google Chrome, arrived at the end, if you try to continue the scroll is also scrolled the div parent, which does not happen with Mozilla. How to fix it?
With jquery you can disable the overflow when mouse is over the child div.
This way works on Firefox 24 for Mint, and Chromium 28...
http://jsfiddle.net/JcUxs/2/
$('.child').on('mouseover',function(){
$(this).parent().addClass('fixoverflow');
});
$('.child').on('mouseleave',function(){
$(this).parent().removeClass('fixoverflow');
});
css:
.fixoverflow{
overflow: hidden
}
I think that this is the best solution I can achieve (It took 1 hour to understand that the scroll event and the wheel is getting trigger both):
I used flag variable to keep the scroller position.
I used jquery and I noticed just now from the comments that you asked for pure javascript.
Anyway jquery bases on native javascript so I'll edit my answer later and translate it to pure code.
Just confirm that it's good enough for you and i'll translate it.
JavscriptCode:
var isCanceled = false;
var currentPos = $(".parent").scrollTop();
var stopWheelTimer = undefined;
$(".child").on('mousewheel', function (event) {
clearTimeout(stopWheelTimer);
event.stopPropagation();
isCanceled = true;
currentPos = $(".parent").scrollTop();
stopWheelTimer = setTimeout(function(){
isCanceled = false;
}, 250);
});
$(".parent").on('mousewheel', function (elem) {
if(isCanceled)
{
$(elem.target).scrollTop(currentPos);
}
});
$(".parent").on('scroll', function (elem) {
if(isCanceled)
{
$(elem.target).scrollTop(currentPos);
}
});
Working Example:
jsFiddle

How to detect when a tab is focused or not in Chrome with Javascript?

I need to know if the user is currently viewing a tab or not in Google Chrome. I tried to use the events blur and focus binded to the window, but only the blur seems to be working correctly.
window.addEventListener('focus', function() {
document.title = 'focused';
});
window.addEventListener('blur', function() {
document.title = 'not focused';
});
The focus event works weird, only sometimes. If I switch to another tab and back, focus event won't activate. But if I click on the address bar and then back on the page, it will. Or if I switch to another program and then back to Chrome it will activate if the tab is currently focused.
2015 update: The new HTML5 way with visibility API (taken from Blowsie's comment):
document.addEventListener('visibilitychange', function(){
document.title = document.hidden; // change tab text for demo
})
The code the original poster gives (in the question) now works, as of 2011:
window.addEventListener('focus', function() {
document.title = 'focused';
});
window.addEventListener('blur', function() {
document.title = 'not focused';
});
edit: As of a few months later in Chrome 14, this will still work, but the user must have interacted with the page by clicking anywhere in the window at least once. Merely scrolling and such is insufficient to make this work. Doing window.focus() does not make this work automatically either. If anyone knows of a workaround, please mention.
The selected answer for the question Is there a way to detect if a browser window is not currently active? should work. It utilizes the Page Visibility API drafted by the W3C on 2011-06-02.
It might work after all, i got curious and wrote this code:
...
setInterval ( updateSize, 500 );
function updateSize(){
if(window.outerHeight == window.innerHeight){
document.title = 'not focused';
} else {
document.title = 'focused';
}
document.getElementById("arthur").innerHTML = window.outerHeight + " - " + window.innerHeight;
}
...
<div id="arthur">
dent
</div>
This code does precisly what you want, but on an ugly way. The thing is, Chrome seems to ignore the title change from time to time (when switching to the tab and holding the mouse down for 1 sec seems to always create this effect).
You will get different values on your screen, yet your title won't change.
conclusion:
Whatever you are doing, don't trust the result when testing it!
For anyone who wants to swap page titles on blur and then go back to the original page title on focus:
// Swapping page titles on blur
var originalPageTitle = document.title;
window.addEventListener('blur', function(){
document.title = 'Don\'t forget to read this...';
});
window.addEventListener('focus', function(){
document.title = originalPageTitle;
});
I found that adding onblur= and onfocus= events to inline bypassed the issue:
This could work with JQuery
$(function() {
$(window).focus(function() {
console.log('Focus');
});
$(window).blur(function() {
console.log('Blur');
});
});
In chrome you can run a background script with a timeout of less than 1 second, and when the tab does not have focus chrome will only run it every second. Example;
This doesn't work in Firefox or Opera. Don't know about other browsers, but I doubt it works there too.
var currentDate = new Date();
var a = currentDate.getTime();
function test() {
var currentDate = new Date();
var b = currentDate.getTime();
var c = b - a;
if (c > 900) {
//Tab does not have focus.
} else {
//It does
}
a = b;
setTimeout("test()",800);
}
setTimeout("test()",1);

Categories