This question already has an answer here:
How do I make my webtime tracking extension more efficient?
(1 answer)
Closed 10 months ago.
I am working on a chrome extension, and I need the time spent on each tab. I'm using chrome.tabs api.
You need a timer, storage and tabs permissions and background Script.
The bg script needs an event and then check if its the desired URL:
window.addEventListener('load', function () {
chrome.tabs.getSelected(null,function(tab){
myURL=tab.url;
});
If the desired URL is met, retrieve current timestamp and save it to a variable.
If the user closes the tab or chrome window catch it:
chrome.tabs.onRemoved.addListener(function(tabid, removed) {
alert("tab closed")
})
chrome.windows.onRemoved.addListener(function(windowid) {
alert("window closed")
})
Wihtin the catch you get the current timestamp again, calculate end - start and you could save it to e.g. sessionStorage.
Maybe like a "chronometer", init a new Date() when your user open a tab and subtract a new Date() with the init time when your user close a tab?
Related
I'm using this code published by Sasi Varunan here
<script type="text/javascript">
// Broad cast that your're opening a page.
localStorage.openpages = Date.now();
var onLocalStorageEvent = function(e){
if(e.key == "openpages"){
// Listen if anybody else opening the same page!
localStorage.page_available = Date.now();
}
if(e.key == "page_available"){
alert("One more page already open");
}
};
window.addEventListener('storage', onLocalStorageEvent, false);
</script>
Code is working like charm - doing exactly what I want - detect if an application it's already open in another tab browser or even in another browser window.
From my understanding:
The very first time when the application is started the followings thinks happen:
App set openpages key with Date.now() value.
Because of 1. storage event listener start onLocalStorageEvent event.
Because the openpages key exists, is setting page_available key with Date.now ()
When the followings apps are started they find page_available key in storage (the second if) the alert is triggered and I can redirect them to an error page.
QUESTION:
If I close all the browser windows and restart the app in a new winwdow everything still works fine.
This is what I don't understand because the page_available key is persistent is still there in the storage (no one deleted) the app should go on the second if and that the alert ... but this is not happening.
The very first time when the application is started the followings thinks happen:
App set openpages key with Date.now() value.
Because of 1. storage event listener start onLocalStorageEvent event.
Because the openpages key exists, is setting page_available key with Date.now ()
When the followings apps are started they find page_available key in storage (the second if) the alert is triggered and I can redirect them to an error page.
The entire idea here is to communicate between the tabs using the storage event that is being triggered every time you access localStorage.
So when the page loads it first access the openpages key to trigger the storage event with e.key == "openpages".
Only after that it registers the event listener. So 2 only happens when you load the page on a second tab. On the second tab the event is triggered and the event listener is registered. Because the storage event is triggered for all the tabs, the event listener of the first tab (which is already registered) is being executed.
Tab 1 is triggered by the storage event with e.key == "openpages" and gets into the first if. There it triggers the storage event by accessing page_available key.
At this point tab 2 event listener reacts to the storage event but this time with e.key == "page_available" and gets into the second if where it shows the alert.
Note that if you don't close the tabs and open more tabs, tab 3 will trigger the storage event for all other tabs and you will have multiple tabs with alerts.
Just for reference:
If you want to trigger the alert on the first tab and not the second one you can achieve it with this code:
// Broadcast that you're opening the page.
localStorage.openpage = Date.now();
var onLocalStorageEvent = function(e) {
if (e.key == "openpage") {
alert("One more page already open");
}
};
window.addEventListener('storage', onLocalStorageEvent);
Read more about localStorage here.
Read more about addEventListener here.
After a restart of the browser window everything still works fine, and
I don't understand why because the page_available key is still there
in the storage
This is because localStorage has no expiration date which is opposite of sessionStorage. sessionStorage gets cleared once the browser is closed, but localStorage still remains.
You can still clear the localStorage by clearing the browser cache & cookies
Also this snippet localStorage.openpages = Date.now(); seems to be incorrect.
If you want to set a value in localStorage, do like this
localStorage.setItem('openpages',Date.now());
I am working on a web based application, in which I have to open popup window. I am using window.open() method to open the popup, like this:
window.open(url, "popupWin");
where url contains the URL I would like my popup window to navigate to. Now, the problem is, if I execute window.open() from multiple tabs (with same or different URLs), at least on Chrome, it might / might not give you the same window which was opened earlier. This behaviour is inconsistent, I mean, either it should get me fresh window every time, or it should get me previously opened window every time.
I need to persist the same popup window for entire domain. How can I do that?
Well looks like there is a direction to go or at least to give it a try.
It fully remains on localStorage which gives you ability to share the knowledge across your tabs within a single domain.
The code I give below does not work yet (it is only a direction), so don't expect too much from running it as it is.
What it does: it saves the popups by the url in a localStorage and when you try to open a new one with the same url it won't do that. If you don't want to distinguish them by URL it is even simpler: store boolean in a localStorage instead of an object.
What it does not do but should:
it should listen to the popup onunload (close) event and reset the localStorage information accordingly. Best for you here is just to set your localStorage boolean value to false
it should listen to the current tab onunload (reload, close) event and also reset something according to Your logic. As I understand the best for you would be just check whether this tab is the last one from your domain (you can also do this using localStorage, e.g. on every new tab adding its identifier, e.g. creation timestamp and destroying it on tab close) and if it is set your localStorage boolean value to false.
This, I think, would be enough to solve the problem. And finally a small piece of code:
// get the localstorage url map
function getOpenPopups() {
var obj = localStorage.getItem('mypopups');
return obj ? JSON.parse(obj) : {};
}
// set the localstorage url map
function setOpenPopups(object) {
localStorage.setItem('mypopups', JSON.stringify(object))
}
// open the popup
function popup(url, title) {
var popups = getOpenPopups();
// check whether popup with this url is already open
// if not then set it and open the popup
if (!popups[url]) {
popups[url] = true;
setOpenPopups(popups);
return window.open('abc', 'cde');
}
else {
return false;
}
}
jsFiddle
From w3c documentation we can see that window.open() returns a reference to the newly created window, or null if the call failed. That means we can keep it in memory and check for closed flag of that window.
var newWindow = window.open('/some/path', 'TestWindow');
// ...
if (!newWindow.closed) {
}
Keep in mind that if window with following name exists, page will be loaded in the same window without opening new one.
Other variants of name parameter like _blank, _self, _top, _parent you can find in official docs too.
I have a web-application for iPhone, and I need to trigger a Javascript function when the web page is in focus, in other words, when Safari is open.
What I want to accomplish is to start a timer in some way when the user clicks on a tel-link and starts the call. When the call ends, Safari pops up again, and the timer ends.
Is there any way to do this?
Best Regards
Linus
try this:
if you trigger the link for the call set the actual time in a localStorage-item.
$("#yourButton").click(function() {
var actualTime = new Date().getTime();
window.localStorage.setItem('callStart', actualTime);
})
after that you need to read the Storage after user ends up the call.
You can set this in the document.ready on the opening page.
in $(document).ready(function() {})
// check for the localStorageItem
if (window.localStorage.getItem('callStart')) {
// get it
var timeStart = window.localStorage.getItem('callStart');
var now = new Date().getTime();
/*
Now calculate here the difference now - timeStart
and you will get seconds, minutes or whatever you want
*/
// !!! Dont forget to clear the localStorageItem
window.localStorage.removeItem('callStart');
}
This is what I would try. The Usage of the HTML5-localStorage gives you the possibility to store key/values and data isnt lost if user stops the app or device is automatically locked.
Hope this helps a bit.
ADDED: You even can store JSON as the value in the localStorageItem. So you can set an callID and implement a calling-history for your users.
This question already has answers here:
Closed 11 years ago.
Possible Duplicate:
Can you detect/redirect a back button press through javascript?
I am developing a small web application. In my application I must know when the user clicks the "back" button, so I can run some javascript code. Is there any such way to detect it?
thank you
Ok, so I discovered that the JS API cannot access the history object's next property without elevated permissions, which got me thinking in another direction.
Form fields are automatically fetched from the browser's cache, thus holding historic data. while this is true, javascript code is run independently each time.
So I created a small hidden field to hold a timestamp and compare it against the javascript's generated datatime.
Here is the code, I am sure it can be much better implemented, though time is short:
$(document).ready(function () {
var date = new Date();
var clientMiliseconds = date.getTime();
clientMiliseconds = roundTime(clientMiliseconds);
var serverTimeStamp = $('#' + '<%= hfTimeStamp.ClientID %>').val();
serverTimeStamp = roundTime(serverTimeStamp);
alert(serverTimeStamp == clientMiliseconds);
});
function roundTime(time) {
time = Math.floor(time);
//since the server renders the time components a few seconds before the page is downloaded
//which also depends on where you assign the date on the serverside
//we've got a small inaccuracy of few seconds. we neglect these seconds, assuming that it would take the user
//a few seconds to click the back button
time = time / 10000;
time = Math.floor(time);
return time;
}
You can't do that. you can bind an event so that something happens when your user navigates away from the page (use onbeforeunload or unload() to do that) but there is no way to know where he has gone
I'm creating a Chrome extension that has a background.html file which requests information from an API once every minute. Once it receives the information, it messages popup.html with the JSON information with which popup uses to append new HTML elements onto the popup's body.
The problem is background is constantly running (as it should), but it will ping popup even when popup is closed. This causes popup to open itself every minute which is very annoying.
I want to know, is there a way to see if popup is closed and not do anything if that's the case? Or is there another way to prevent popup opening on its own?
Here's the Github repository, but the important parts are highlighted below.
Here's how I'm pinging popup:
// background.js
function sendQuestions()
{
var questions = JSON.parse(db.getItem(storage));
chrome.extension.sendRequest(appid, { 'questions': questions }, function() {});
}
setInterval(sendQuestions, 60e3);
Here's how popup handles it:
// popup.js
chrome.extension.onRequest.addListener(function(request) {
if (request.questions) {
displayQuestions(request.questions);
}
});
function displayQuestions(questions)
{
for (i = 0; i < questions.length; i++) {
var question = questions[i];
var htmlBlock = // ... generate a block of html ...
$('#container').prepend(htmlBlock);
}
}
Open a long lived connection from the popup to the background_page anytime it opens. In the background_page you can check to see if the connection is currently active. If it is pass the necessary messages otherwise wait until the connection is active.