I'm sure this question has been answered, before, but my searches are coming up empty.
I have a simple jQuery function (that slides in a box after the page has been scrolled down). It works fine.
However, how do I set cookies, or other method, to make it execute on the first page load and, then, on every 3rd page load of the session, after that?
A little snippet like this should work for you.
(function () {
// Get the countdown from localStorage
var countdown = Number(window.localStorage.getItem('countdown'));
// If countdown isn’t set it or if it has
// run a couple times it’ll be `0`
// Either way—we reset countdown and run the function
if (!countdown) {
countdown = 3;
// Run the function
}
// Update the countdown
window.localStorage.setItem('countdown', countdown - 1);
})();
These are both very instructive answers (my javascript skill is at the piece-it-together level). If it's helpful to someone, even though the question was for a javascript solution, I realized there might be a PHP solution, as well.
This worked, too:
<?php //Slide-in ad will show every x pages
$slide_ad_frequency=3;
session_start();
//increase the already-set counter by 1 or initiate the counter with a value of 1
if( isset( $_SESSION['counter'] ) )
{
$_SESSION['counter'] += 1;
}
else
{
$_SESSION['counter'] = 1;
}
//If counter equals the ad frequency setting
if($_SESSION['counter'] % $slide_ad_frequency == 0) : ?>
... Code to execute ...
<?php endif ?>
You can store the count of window loads on the sessionStorage so that data won't be lost on every reload. The data will be cleared when the tab is closed. If you want your data to not expire when the session ends, you should instead use localStorage; both have the same implementation.
window.onload = doSomething;
function doSomething() {
let count = sessionStorage.getItem('noOfPageLoads');
if( count ) { //if count is not null, increment it
count++;
sessionStorage.setItem('noOfPageLoads', count); //update the local storage
}
else { //if count is null, it's the first load, so put it in the local storage
count = 0;
sessionStorage.setItem('noOfPageLoads', count);
}
console.log('noOfPageLoads = '+ count)
if( count===0 || count===3 ) {
console.log('do something now');
//do what you want here
}
}
Related
I will like to achieve something in a quiz system.
Right about now I have a quiz system that works perfectly well. It closes the quiz after 10:00 min is elapsed.
But what I want now is, for each of the question there should be a timer.
So Question 1 would have 10 secs, Question 2 would also have 10 secs down to Question 20.
So when you fail to answer any question within ten seconds, it automatically takes you to the next question.
Right about now, what happens is that you must click on the next question button before it takes you to the next question, which is what I want to change.
Below is the code that does the timer and submit after 10 min
<script>
//function that keeps the counter going
function timer(secs){
var ele = document.getElementById("countdown");
ele.innerHTML = "Your Time Starts Now";
var mins_rem = parseInt(secs/60);
var secs_rem = secs%60;
if(mins_rem<10 && secs_rem>=10)
ele.innerHTML = " "+"0"+mins_rem+":"+secs_rem;
else if(secs_rem<10 && mins_rem>=10)
ele.innerHTML = " "+mins_rem+":0"+secs_rem;
else if(secs_rem<10 && mins_rem<10)
ele.innerHTML = " "+"0"+mins_rem+":0"+secs_rem;
else
ele.innerHTML = " "+mins_rem+":"+secs_rem;
if(mins_rem=="00" && secs_rem < 1){
quiz_submit();
}
secs--;
//to animate the timer otherwise it'd just stay at the number entered
//calling timer() again after 1 sec
var time_again = setTimeout('timer('+secs+')',1000);
}
</script>
<script>
setTimeout(function() {
$("form").submit();
}, 600000);
</script>
Here is the code that does the onclick to next question
<script type="text/javascript">
$('.cont').addClass('hide');
count=$('.questions').length;
$('#question'+1).removeClass('hide');
$(document).on('click','.next',function(){
last= parseInt($(this).attr('id'));
nex = last+1;
$('#question'+last).addClass('hide');
$('#question'+nex).removeClass('hide');
});
$(document).on('click','.previous',function(){
last = parseInt($(this).attr('id'));
pre = last-1;
$('#question'+last).addClass('hide');
$('#question'+pre).removeClass('hide');
});
setTimeout(function() {
$("form").submit();
}, 120000);
</script>
Please note that I fetch my questions with Php Mysqli
Initialize a timeout into a variable at start. The callback should simulate a click on the next button. Use .click() to simulate. It will execute all click event listeners associated to the button.
You also have to reset the timer when button is clicked (manually or not).
EDIT: After discussing by comments, I guess that you have <button.next> tags for each question in your HTML, with a numeric ID. So I propose you to stock in a variable your current progression.
// Initializes
let currentQuestion = 1;
let question_timer = setTimeout(question_timeout_callback, 10000);
// Function which simulates the click.
function question_timeout_callback() {
// Simulates
$(document).find(`#${currentQuestion}`).click();
}
// your code...
// And in your click event listener:
$(document).on('click','.next', function () {
// Resets timer
clearTimeout(question_timer);
question_timer = setTimeout(question_timeout_callback, 10000);
// Update question tracking
currentQuestion++;
// your code...
});
// Do NOT forget to update .previous buttons with "currentQuestion--"
Now, do not forget to ask yourself how you will handle the possibility to come back to the previous question.
i would suggest different approach.
first, take the time-counting to the backend of your application (so user can't tamper with it).
when user begins quiz, save start time and user identifier into db.
implement timeout (2s interval?) to ask backend, how much time is left.
create simple script which loads remaining time from db (calculates how much time remains for current question) and returns it to the frontend.
php:
<?php
$user = (int) $_GET['user'];
$questionNumber = (int) $_GET['question'];
//connect to the db
//select eg. with PDO
$st = $db->prepare('SELECT start_time FROM quiz_completion WHERE user_id = :user');
$st->bindParam(':user', $user, PDO::PARAM_INT);
$startTimeRow = $sth->execute();
//calculate remaining time
$elapsed = time() - $startTimeRow['start_time'];
$borderTime = 10 * $questionNumber;
echo $borderTime - $elapsed;
exit(0);
with mocked GET & db: https://3v4l.org/MId0K
then in js just call this script with user identifier and question number. when less than zero is returned, move user to the next question.
js:
$.ajax('http://localhost/your_php_script.php?user='+user+'&question='+questionNumber).done(
function(response){
if (response < 0) {
//move to the next q.
} else {
//show remaining time?
}
});
with asking backend to get time, there is risk of waiting too long for an answer from php (when many users are completing the poll)
I am trying to get a current score to add up every time an answer is correct, what is happening is that I have the questions in a pagination set up and when this answer is correct it give me the score but then when it goes to the next page it refresh the score and if I got that one right it just give me the score for that one again but it doesn't add up.
JS code:
$(function() {
$('#author').on('change', function(event) {
var opt = this.options[ this.selectedIndex ];
var correct = $(opt).text().match (arr2);
var score = 0;
if (correct){
alert('Good job ' + arr2,);
score += 2;
alert (score);
currentScore = score++;
alert(currentScore);
display(currentScore);
}
else {
alert ('nice try ' + arr2);
}
});
});
Here is another option - local storage.
Here is a reference W3School Web storage
It's not the most ideal solution, but it can meet your criteria.
let score = localStorage.getItem('score')
score++;
localStorage.setItem('score', score);
Your pages will be able to access the localStorage so you can get the value of score and re-set it.
Hopefully the reference can answer further questions, else leave a comment!
Con: It may not be supported by all browsers.
EDIT:
Here is an example with your code.
$(function() {
let currentScore = localStorage.getItem('score'); // get score
if (currentScore === null){ // if score doesnt exist yet
localStorage.setItem('score', 0); // set score
currentScore = 0; // make currentScore 0
}
$('#author').on('change', function(event) {
var opt = this.options[ this.selectedIndex ];
var correct = $(opt).text().match (arr2);
if (correct){
alert('Good job ' + arr2);
currentScore += 2; //increment current score by 2
alert (currentScore);
localStorage.setItem('score', currentScore); // set the item again with new value
alert(currentScore);
display(currentScore);
}
else {
alert ('nice try ' + arr2);
}
});
});
Edit 2:
let currentScore = localStorage.getItem('score'); // get score
currentScore = parseInt(currentScore);
it give me the score but then when it goes to the next page it refresh the score and if I got that one right it just give me the score for that one again but it doesn't add up.
I think your problem is there.
If I understand correctly, when the answer is good, the page refresh and passes to the next question. Your problem is that the score doesn't add up to the previous one.
The score variable is only stored in the current page, like a temporary one. Without saving the score on the server, via ajax or another method, and getting it on the next page, it will not add up. Indeed, score will have a value of 0 due to the refresh.
A simple schema :
score = 0 -> correct answer -> +50 point -> score = 50 -> next page -> score = 0
As you can see, because the javascript you wrote is not assuring the persistance of your information, the previously stored score is lost.
You need to send the score on the server and then get it back when the new page is loaded or to avoid changing page and make your quizz on one and only page, without refreshing.
Keep in mind that everytime you are refresing a page, the javascript is starting again and therefore everything done before is lost.
I hope this was helpful.
Ps: You should place your code in the $( document ).ready(); block just like this :
$( document ).ready(function() {
console.log( "ready!" );
});
It will make your code start when the html DOM (the structure of the html file) is loaded and ready to be manipulated. It can avoid a lot of errors.
Edit2 : What it will look like in your code :
$( document ).ready(function() {
$('#author').on('change', function(event) {
var opt = this.options[ this.selectedIndex ];
var correct = $(opt).text().match (arr2);
var score = 0;
if (correct){
alert('Good job ' + arr2,);
score += 2;
alert (score);
currentScore = score++;
alert(currentScore);
display(currentScore);
}
else {
alert ('nice try ' + arr2);
}
});
});
Or, to make this more readable and to avoird having a lot of things in the document.ready block (when you will have a lot of lines/functions) :
$( document ).ready( myNiceFunction() );
var myNiceFunction = function(){
$('#author').on('change', function(event) {
var opt = this.options[ this.selectedIndex ];
var correct = $(opt).text().match (arr2);
var score = 0;
if (correct){
alert('Good job ' + arr2,);
score += 2;
alert (score);
currentScore = score++;
alert(currentScore);
display(currentScore);
}
else {
alert ('nice try ' + arr2);
}
}
Ps2 : I know this is not the best website to explain it but I think it is simple enough to make you understand the principle of ajax without losing you into a bunch of technical stuff : here and here
Edit : Grammar and second post-scriptum.
Not sure how you're doing pagination but it should be ajaxed, instead of a full postback, so you don't lose the values on your page.
Please, I am trying to link all my pages with progressive 30 seconds count timer using JavaScript and html without being recount on page navigation. Thanks!
With more information in mind from comments, here's your code:
Somewhere in index.html
<div id="counter"></div>
YourScript.js
// Simplifies getting the value of a cookie
function getCookie(name)
{
var re = new RegExp(name + "=([^;]+)");
var value = re.exec(document.cookie);
return (value != null) ? unescape(value[1]) : null;
}
// Max time for cookie
var count = 30;
if(document.cookie && document.cookie.match('counter')) {
// Set value of counter to match the cookie
count = getCookie('counter');
}
// Runs once per second
setInterval(function() {
// Decrease the value of count by 1 every second
count--;
// if count is less or equal to 0 we move to menu.html
if(count <= 0) {
window.location.href="menu.html"
}
// Set the text inside the <div id="counter"></div> to the value of counter
document.getElementById('counter').innerHTML = count;
// Set the value of the cookie to match the value of our counter variable
document.cookie = 'counter=' + count;
}, 1000);
I created a jsfiddle for this but for some reason jsfiddle doesn't want to create a unique URL for me right now... Go to jsfiddle.net and copy paste this into the script field, and the div into the html area, then press Run several times and you'll see that the counter keeps counting down, persisting between page refreshes.
I wrote this program in js that goes through a list of URLs, where it stays on each page for a few seconds, closes the current window, and open the next in line. Everything works perfect, now I need it to stop/pause every 5 links. The second part of this project would be to create my own browser that open up like a program and there would be three buttons (start, continue, stop, maybe pause as well). I'd like start button to obviously start the function which goes through the pages, continue would be when it pauses on the fifth link I'd like a pop up message to say "wake up" and have the option to click "ok" only. Then you would have to click on continue in order for the function to continue. Stop would stop the function no matter where it has reached in the list. I'd like the links to show up in my browser not in Google Chrome or any other. What program should I use to design the browser? Here is the code of the current program:
var urlList = ['www.youtube.com',
'www.google.com',
'www.bing.com',
'www.yahoo.com',
'www.facebook,com',
'www.windows.com',
'www.opera.com',];
var wnd;
var curIndex = 0; // a var to hold the current index of the current url
function openWindow(){
wnd = window.open(urlList[curIndex], '', '');
if (curIndex % 5 == 0) {
}
setTimeout(function () {
wnd.close(); //close current window
curIndex++; //increment the index
if(curIndex < urlList.length) openWindow(); //open the next window if the array isn't at the end
}, 4000);
}
openWindow();
Help me finish the if statement...
Add a variable for your timeout period, instead of using the value 4000. Note that it must have global scope. I've added a variable calleddelay here:
var wnd;
var curIndex = 0; // a var to hold the current index of the current url
var delay;
Then, use the new variable in your openWindow() function, setting its value to a longer period in your if statement when you want the pauses to happen.
I've used a ternary operator here for instead of an if statement, but you could use an if statement just as well:
function openWindow(){
wnd = window.open('http://' + urlList[curIndex], '', '');
// pause for 30 seconds instead of 4 if the condition is met
delay = (curIndex > 0 && curIndex % 3 == 0 ? 30000 : 4000)
setTimeout(function () {
wnd.close(); //close current window
curIndex++; //increment the index
if(curIndex < urlList.length) openWindow(); //open the next window if the array isn't at the end
}, delay);
}
I have my code of timer that only alert when minutes and seconds are 0:
status = false;
hour_to_start = some_value; // THIS VALUE IS PUT FOR OTHER PERSON
min = 15; //THIS VALUE IS PUT FOR ANOTHER PERSON
seg = 60;
function timecamisa(){
if (seg > 0){
seg--;
}else{
if(seg==0){
min--;
seg=60;
}
}
if(min == 0 && seg==0){
// END - STOP ALL
min= 0;
seg = 0;
status = true;
}
var timer = min + ' minutos ' + seg + ' segundos';
document.getElementById("times-get").innerHTML = timer;
if(status != true){
setTimeout("timecamisa()",1000)//This reload this function (timecamisa())
}else{
alert("END!");
}
In my HTML i have a <span id="times-get"> where print the timer.
BUT, when i press F5 my timer return to the beginning and does not continue where you left off... So, How to do this? Anyone have a example?
My target is that my timer work with my variable 'hour_to_start' and 'min' where.. This timer displays the countdown from my variable 'hour_to_start' in 'x' 'min' (my other variable). And when the variable MIN is 0(ie, complete the mins).. Alert anything.
UPDATE!
OK, i do it with Jquery Plugin countdown Timer.. Is very useful for more than 1 timers.
Now, mi problem is.. when i change the time of my computer, this timer change too.
How to avoid changing my timer when you change the time, date and / or time of my machine?
You will need to get the time from either your server or from some remote server (e.g. via a javascript from someone else's server). If you get the time using javascript it will always depend on the clock of the user's machine.