One time initialization for JavaScript variable - javascript

I am developing a JavaScript for a webpage. This script has to create a popup, when the user is idle for a certain time. When the popup shows up, the user can choose to either close the popup or to minimize it.
In case of closing the popup, further opened pages within the website shall not open the popup anymore. In case of minimizing, it should not do either. Nonetheless when the user has a certain idle time on any page the first time, it shall appear.
It works in so far, that the pop up is created and also the closing of the pop works (and that it does not open anymore). But it does not work a refresh of the page anymore. So the storing does not work. And I know it is, because of my variables and a refresh also restarts the script again, so the initialization of the variables does rewrite the session value.
So basically my question is: How do it do the 1st time initialization of the variables, which than are furtherly used after a refresh?
My code is the following:
var isClosed = new Boolean(false);
var isShrinked = new Boolean(false);
var test = "Tesst";
sessionStorage.setItem("session", isClosed=false);
function close_popup() {
$('#' + 'box').fadeOut('slow');
sessionStorage.setItem("session", isClosed=true);
}
(function idelor(){
document.onclick = document.onmousemove = document.onkeypress = function() {
idleCounter = 0;
};
window.setInterval(function() {
if (sessionStorage.getItem("session").toString() == "false") {
if (isShrinked == false) {
if (++idleCounter >= IDLE_TIMEOUT) {
var scriptCode = document.createElement('p');
scriptCode.id = 'Sentotal';
document.getElementsByTagName('body')[0]
.appendChild(scriptCode);
document.getElementById("Sentotal").innerHTML = boxTotal;
}
}
}
}, interval);}());

You can use cookie for this matter.
//A simple function to get the value stored in cookie;
var getCookie = name =>
document.cookie.split(';')
.map(token => token.trim('').split('='))
.reduce((prev, curr) =>
(prev[curr[0]] = curr[1]) && prev, {})[name],
myPopup = () => {
if (!getCookie('noPopUp')) {
console.log('your popup logic');
document.cookie = 'noPopUp=true'
}
},
reset = () => {
document.cookie = 'noPopUp=true; expires=' + new Date();
};
reset(); //Remove this and myPopUp will do nothing until you restart your browser.
myPopUp();
myPopUp();
Cookie resets (by default) when browser closes.

I used Hin Fan Chan's suggestion of using cookies, and have the following, stable working solution coded:
Just two variables now as constant names for the Cookies:
var CLOSE_CONSTANT = "CloseCookie";
var MINIMIZE_CONSTANT = "MinimizeCookie";
Simple functions for creating and getting the cookies. Note, that "error" in getCookie(...) is very important for the initialization of the script!:
function setCookie(name, state) {
var cname = name;
var value = state;
document.cookie = cname + "=" + value;
}
function getCookie(cname) {
var name = cname + "=";
var ca = document.cookie.split(';');
for (var i = 0; i < ca.length; i++) {
var c = ca[i];
while (c.charAt(0) == ' ') {
c = c.substring(1);
}
if (c.indexOf(name) == 0) {
return c.substring(name.length, c.length);
}
}
return "error";
}
I also build a cookieChecker(...) function, which automatically fills error-Cookies (those, who are not existing atmo) with "false":
function cookieChecker(name) {
switch (getCookie(name)) {
case "error":
setCookie(name, "false");
break;
default:
break;
}
}
Now the final function, which is the only function being opened by the HTML. cookieChecker(...) is used twice: For the minimization and the closing of the popup. These two functions simply set the state of a cookie to true (and fading the box out):
(function idelor() {
var minutes = false;
var interval = minutes ? 60000 : 1000;
var IDLE_TIMEOUT = 5;
var idleCounter = 0;
document.onclick = document.onmousemove = document.onkeypress = function() {
idleCounter = 0;
};
cookieChecker(MINIMIZE_CONSTANT);
cookieChecker(CLOSE_CONSTANT);
window
.setInterval(
function() {
switch (getCookie(CLOSE_CONSTANT) + " "
+ getCookie(MINIMIZE_CONSTANT)) {
case "false false":
if (++idleCounter >= IDLE_TIMEOUT) {
var scriptCode = document.createElement('p');
scriptCode.id = 'Sentotal';
document.getElementsByTagName('body')[0]
.appendChild(scriptCode);
document.getElementById("Sentotal").innerHTML = BOXTOTAL;
}
default: break;
}
}, interval);
}())

Related

Javascript and passing Cookies issue

I am working on a script which takes the vertical scroll posistioning of a div container and on document unload it stores the vertical posistion within a cookie and then loads it on load.
Originally I had the following:
$('#GridViewContainer').load('claims.php', function() {
$(this).scrollTop($(this).prop("scrollHeight") - $(this).height());
});
Which is ok if you are refreshing the page but if you are reloading the page with parameters it will lose it's position. Solution? Store it in a cookie...
However I am having issues with storing the value and loading it on load. I am using php to return all current Cookies and I can see I am setting the cookie "div_yCookie" but the content seems to be:
'div_yCookie' => string '[object Object]' (length=15)
(I am a complete Javascript and jQuery novice... No doubt it is something obvious but can someone help?
<script>
function createCookie(name,value,days) {
if (days) {
var date = new Date();
date.setTime(date.getTime()+(days*24*60*60*1000));
var expires = "; expires="+date.toGMTString();
}
else var expires = "";
document.cookie = name+"="+value+expires+"; path=/";
}
function readCookie(name) {
var nameEQ = name + "=";
var ca = document.cookie.split(';');
for(var i=0;i < ca.length;i++) {
var c = ca[i];
while (c.charAt(0)==' ') c = c.substring(1,c.length);
if (c.indexOf(nameEQ) == 0) return c.substring(nameEQ.length,c.length);
}
return null;
}
function eraseCookie(name) {
createCookie(name,"",-1);
}
$(document).ready(function () {
$('#GridViewContainer').load('claims.php', function() {
var x = readCookie('div_yCookie');
$(this).scrollTop($(this).prop("scrollHeight") - x);
//$(this).scrollTop($(this).prop("scrollHeight") - $(this).height());
});
});
window.onbeforeunload = function(){
var div_y = $('#GridViewContainer').scrollTop($('#GridViewContainer').prop("scrollHeight") - $('#GridViewContainer').height());
createCookie('div_yCookie',div_y,0.5);
};
</script>
UPDATE
It turns out it actually works when you refresh the page however it still doesn't work when you reload the page.

Cookies returning undefined

I'm building a small HTML game that uses cookies/localStorage to save and load users data. I have an object declared that holds all of the data which is then referenced by the save/load functions and by game calculations:
var iAttack, iDefence, iGold;
// nothing to do with Apple lol...
var data = {
pStats: {
attack: iAttack,
defence: iDefence
},
pInventory: {
gold: iGold
}
}
These will obviously return undefined, but this is before the cookie values are inserted.
So, heres a run-through of whats supposed to happen:
When the window loads, the if statements are gone through to check cookies/localStorage and if there is any previous storage data in the browser. These booleans get assigned to cookies, storageLocal and previousData. This is the code for it:
var previousData = false;
var cookies = false;
var storageLocal = false;
//activated on window.load
function loadData(){
//check for previous data
if (document.cookie != "") {
previousData = true;
console.log("Previous data? " + previousData)
} else if (localStorage.getItem("gold") !== null) {
previousData = true;
console.log("Previous data? " + previousData)
} else {
console.log("Previous data? " + previousData)
}
// check if cookies/localStorage
document.cookie = "foo=bar";
if(document.cookie){
cookies = true;
console.log("Cookies will be used")
} else if (typeof(localStorage) != undefined){
storageLocal = true;
console.log("localStorage will be used")
}
// loadData() continued...
If previousData = false then default values are assigned to the object variables, eg iDefence = 5 and this works fine.
Lets assume that previousData and cookies are true: the function then goes on to inserting the data from the cookies into the object variables like this:
if (previousData) {
if (cookies){
data.pStats.attack = parseInt( readCookie("attack") );
data.pStats.defence = parseInt( readCookie("defence") );
// note that i've used iAttack instead of data.pStats.attack but doesn't work
In the console, if i input iAttack or data.pStats.attack it returns undefined. This is the problem that been keeping me up all of last night trying to work around. Any help would be really appreciated.
This is the saveData function that is triggered by onclick. It inputs the object values into cookies:
function saveData(){
if(cookies){
createCookie("attack", iAttack, 7);
createCookie("defence", iDefence, 7);
//if its the first time saving then the default values of iAttack/def will be used
If you're curious about createCookie() and readCookie(), these are the functions:
function createCookie(name,value,days) {
if (days) {
var date = new Date();
date.setTime(date.getTime()+(days*24*60*60*1000));
var expires = "; expires="+date.toGMTString();
}
else var expires = "";
document.cookie = name+"="+value+expires+"; path=/";
}
function readCookie(name) {
var nameEQ = name + "=";
var ca = document.cookie.split(';');
for(var i=0;i < ca.length;i++) {
var c = ca[i];
while (c.charAt(0)==' ') c = c.substring(1,c.length);
if (c.indexOf(nameEQ) == 0) return c.substring(nameEQ.length,c.length);
}
return null;
}
function eraseCookie(name) {
createCookie(name,"",-1);
}

Keep dynamically loaded HTML elements in case the browser "Back" or "Forward" button is clicked

(I read a few threads on the subject but did not find a working solution.)
On my page, I have a "Load more" button that triggers an Ajax call to get new portion of items to display. I would like to preserve these dynamically appended elements when the user gets to different page and then hits "Back" or "Forward" button of the browser - however I cannot get it to work.
I tried setting cache: true for the jQuery $.ajax() request. I also played around with the "Expires" and "Cache-Control" headers on the request, but no success. I consider keeping the dynamic content in <input type="hidden"> and listening to onLoad event in my jQuery script.
Any advice on how I can keep/cache the appended elements every time they're dynamically loaded?
UPDATE:
What I need to "remember" is HTML structure, so possibly a lot of characters (imagine if the user hits "Load more" 10 times and then leaves the page). So the size of any storage needs to be considered.
Here is an example of what I commented above. I think, in your case, it is useful. If this way is unviable you should consider to use a server side workaround. Check jsFiddle.
$(function(){
var clicked_times = 0;
$('button').on('click', function(){
// ajax....
// ajax success:
clicked_times++;
$('<p>new content</p>').insertBefore($(this));
});
window.onbeforeunload = function(){
if( clicked_times > 0 ) Cookies.Set('reload_contents', clicked_times);
};
if( Cookies.Check('reload_contents') ){
var times = Cookies.Get('reload_contents');
for( var i = 0; i < times; i++){
$('button').trigger('click');
}
Cookies.Set('reload_contents', '', -1);
}
});
/** Cookie methods */
var Cookies = {
Check: function (name) {
return !!this.Get(name);
},
Get: function (name) {
var n, ca, c;
n = name + "=";
ca = document.cookie.split(';');
for (var i = 0; i < ca.length; i++) {
c = ca[i].trim();
if (c.indexOf(name) === 0) return c.substring(name.length + 1, c.length);
}
return false;
},
Set: function (name, value, expire, options) {
var d = new Date(), expires;
var defaults = { expire_in: 'days', path: '/' };
if (typeof options !== "undefined") $.extend(true, defaults, options);
if (expire !== undefined && expire !== null) {
if (defaults.expire_in == 'days') d.setDate(d.getDate() + expire);
else if (defaults.expire_in == 'minutes') d.setDate(d.getTime() + expire * 1000);
else {
return false;
}
expires = "expires=" + d.toGMTString();
}
else expires = expires = "";
document.cookie = name + "=" + value + "; " + expires + '; path=' + defaults.path;
return true;
}
};
Use the browsers history. Try that (don't know about its crossbrowser-ability):
var url = "http://newurl.com";// you could save only hashes too.
if (/*url &&*/ location.url != url && history.replaceState) {
history.replaceState(null, url, url);
}
Greetings. André

Force Meteor To Refresh / Re-render Templates?

*For reference I'm using iron router.
Instead of a sign in page I have this global sign in form embedded in an nav (aka on every page).
Right now I'm doing a really hacky refresh to reload the page once a user logs in.
I would like to just reload to the template aka not refresh the whole page.
Basically just want the templates rendered function to rerun on login.
Here's my current login code:
'submit #login': function(event, template){
event.preventDefault();
var handle = template.find('#usernameLogin').value;
var secretKey = template.find('#passwordLogin').value;
Meteor.loginWithPassword(handle, secretKey, function(err){
if (err) {
alert(err);
}else{
$('#close').click();
/* replace this with reactive ajax or whatever when you can! */
Meteor._reload.reload();
}
});
},
My render function which I think may be the real issue now:
Template.tournament.rendered = function () {
thisCampaign = this.data;
var self = this;
if (this.data.tournament.live) {
/* if theres a registered user */
if (Meteor.userId()) {
/* Select a winner box */
var participants = $('.participant-id');
var currentParticipant;
var nextRound;
var thisMatch;
var nextMatch;
var bracket;
participants.map(function(index, value){
if ($(value).text() === Meteor.userId()) {
if ($(value).parent().find('.participant-status').text() === 'undetermined') {
nextRound = $(value).parent().find('.participant-round').text();
thisMatch = $(value).parent().find('.participant-match').text();
bracket = $(value).parent().parent().parent().find('.participant');
};
};
});
nextRound = parseInt(nextRound) + 1;
nextMatch = Math.round(parseInt(thisMatch)/2) - 1;
if (parseInt(thisMatch) % 2 != 0) {
currentParticipant = 0;
}else{
currentParticipant = 1;
}
var winnerOptions = '';
var winnerBox = $('<div class="select-winner">');
if (bracket) {
bracket.map(function(index, value) {
winnerOptions += '<span class="winner-option"> '+$(value).find('.participant-title').text()+' <div class="winner-info"> '+$(value).find('a').html()+' </div> </span>'
});
winnerBox.append(winnerOptions);
$($($('.round'+nextRound).find('li')[nextMatch]).find('.participant')[currentParticipant]).removeClass('loser').addClass('undetermined');
$($($('.round'+nextRound).find('li')[nextMatch]).find('.participant')[currentParticipant]).find('a').addClass('tooltip').html(winnerBox);
};
}else{
}
}else{
/* Tournament Start Time */
var tournamentStartTime = function(){
var d = new Date();
var n = d.getTime();
var currentTime = TimeSync.serverTime(n);
var startTime = self.data.card.startTime;
var difference = startTime - currentTime;
var hoursDifference = Math.floor(difference/1000/60/60);
difference -= hoursDifference*1000*60*60
var minutesDifference = Math.floor(difference/1000/60);
difference -= minutesDifference*1000*60
var secondsDifference = Math.floor(difference/1000);
/* if ends (make tournament live server side?) */
if (hoursDifference < 0 || minutesDifference < 0 || secondsDifference < 0) {
Meteor.clearInterval(tStartTime);
Session.set("tournamentStartTime", false);
}else{
if (hoursDifference < 10) {hoursDifference = "0"+hoursDifference;}
if (minutesDifference < 10) {minutesDifference = "0"+minutesDifference;}
if (secondsDifference < 10) {secondsDifference = "0"+secondsDifference;}
var formattedTime = hoursDifference + ':' + minutesDifference + ':' + secondsDifference;
Session.set("tournamentStartTime", formattedTime);
}
};
Session.set("tournamentStartTime", '00:00:00');
tournamentStartTime();
var tStartTime = Meteor.setInterval(tournamentStartTime, 1000);
/* Allow new user sign up */
var alreadySignedUp = false;
var usersSignedUp = $('.participant-id')
usersSignedUp.map(function (index, user) {
if ($(user).text().trim() === Meteor.userId()) {
alreadySignedUp = true;
}
});
if (this.data.card.host != Meteor.user().username && !(alreadySignedUp)) {
var openSlots = [];
var allSlots = $('.participant');
allSlots.map(function (index, participant) {
if ($(participant).find('.participant-title').text().trim() === '' && !($(participant).hasClass('loser'))) {
openSlots.push(participant);
}
});
openSlots.map(function (openSlot, index) {
$(openSlot).removeClass('winner').addClass('undetermined');
});
}
/* if theres a registered user */
if (Meteor.userId()) {
}else{
}
}
};
From what i can see there, your rendered function would not work as you expect as the template may render while the loggingIn state is still occuring...
My suggestion would be to use something along the lines of {{#if currentUser}} page here{{/if}} and then put the code you are trying to run in the rendered in a helper inside that currentUser block that way it would only display and be called if there is a logged in user, otherwise it would not show up and you would not need to re-render the page to perform any of that.
Basically once the user has logged in, any helper (other than rendered) that has the Meteor.userId() or Meteor.user() functions being called would re-run automatically, otherwise you could perform login actions inside a Tracker.autorun function if they are global to your app per client.

How to find out user clicked 3 times through my website with Javascript

Is there any way in JavaScript how to find out user clicked through the same domain 2 or more times?
I need to popup a window after user clicked anywhere on the site for 3 times. I know how to do it after one click - with document.referrer or addEventListener, but then I'm lost.
I need something that will capture all click events (not only links) and count them.
Sure. You need to store a list of users' click events, either in a cookie, or in a server-side data store. On every recorded click, increment the count by one, and do your thing when the number hits 3.
Try using session cookies to store state between pages -- they're fast, pretty widely compatible, and will zero out when the browser shuts down, to keep from spamming your users' cookie jars.
I tried this and it worked fine:
window.onload = function() {
var clicked = readCookie('popunder');
if(clicked == null) {
clicked = 0;
}
var allLinks = document.getElementsByTagName("a");
for(i=0;i<=allLinks.length;i++) {
allLinks[i].addEventListener("click",countClicks,true);
}
function countClicks() {
if(clicked == 2) {
popunder(); //something to do
} else {
clicked++;
doCookie('popunder', clicked, 1);
alert(clicked);
}
}
function popunder() { alert('thats 3 clicks!'); }
function doCookie(name,value,days) {
if (days) {
var date = new Date();
date.setTime(date.getTime()+(days*24*60*60*1000));
var expires = "; expires="+date.toGMTString();
} else {
var expires = "";
}
document.cookie = name+"="+value+expires+"; path=/";
}
function readCookie(name) {
var readName = name + "=";
var cSplit = document.cookie.split(';');
for(var i=0;i < cSplit.length;i++) {
var sc = cSplit[i];
while (sc.charAt(0)==' ') sc = sc.substring(1,sc.length);
if (sc.indexOf(readName) == 0) return sc.substring(readName.length,sc.length);
}
return null;
}
}
Thanks for all your advice.
I tried this code. But after the refresh the clicked variable goes to 0 again.
I need to save every new value of clicked into cookie (or whatever else), so its number will rise with every click on link on page.
Is it possible to change value of the variable in cookie this way?
window.onload = function(){
var **allLinks** = document.getElementsByTagName("a");
var **clicked** = 0;
**doCookie**('popunder',clicked,1);
for(i=0;i<=allLinks.length;i++){
allLinks[i].addEventListener("click",countClicks,true);
}
function **countClicks**(){
if(clicked == 3){
popunder(); //something to do
}
else{
alert(readCookie('popunder'));
return clicked++;
}
}
function **doCookie**(name,value,days) {
if (days) {
var date = new Date();
date.setTime(date.getTime()+(days*24*60*60*1000));
var expires = "; expires="+date.toGMTString();
}
else var expires = "";
document.cookie = name+"="+value+expires+"; path=/";
}
function **readCookie**(name) {
var readName = name + "=";
var cSplit = document.cookie.split(';');
for(var i=0;i < cSplit.length;i++) {
var sc = cSplit[i];
while (sc.charAt(0)==' ') sc = sc.substring(1,sc.length);
if (sc.indexOf(readName) == 0) return sc.substring(readName.length,sc.length);
}
return null;
}

Categories