Only run a function once in JavaScript? [duplicate] - javascript

I'm using a page loader on the front page of my website, I'd like it to run only the first time someone visits my website, so later on since the page will be cached it'll execture faster and thus I won't need the loader the next times he visits.
I thought using storing a signal to caches/cookies to do so, but I have no idea how ?
here is the loader javascript :
function myFunction() {
var myVar = setTimeout(showPage, 1000);
}
function showPage() {
$("#loader_sec").css("display","none");
$("#bodyloader").css("display","block");
}
myFunction();
<div id="loader_sec">
...
</div>
How should I configure caches/cookies to launch this code only the first time someone visits ? If there are better ways to do so please suggest.

Try this:
function myFunction() {
var myVar = setTimeout(showPage, 1000);
}
function showPage() {
$("#loader_sec").css("display","none");
$("#bodyloader").css("display","block");
}
if(!localStorage.getItem("visited")){
myFunction();
localStorage.setItem("visited",true);
}
<div id="loader_sec">
...
</div>

Try with Session/local storage. Like this -
$(window).load(function () {
$(function () {
if (!sessionStorage.getItem("runOnce")) {
// Your code goes here....
sessionStorage.setItem("runOnce", true);
}
});
});

You'll need to persist some data on the user's device in order to know that they have visited your site before. You would do this via local storage or cookies.
Here is a simple library you can use to read/write cookies: https://developer.mozilla.org/en-US/docs/Web/API/Document/cookie/Simple_document.cookie_framework
You could write a value to a cookie when the user has been shown the page loader. A check for this value when the page loads will let you know if the loader has been displayed previously or not and inform your decision about whether it should be displayed this time.

I would do the logic in a caching/data access layer. You can use https://github.com/kriskowal/q for executing functions as a callback when another function completes.
Then you can do
getData(key)
.then(function () {
hideLoader(); // Function for your show/hide logic
});
or something of the sort.
getData would look something like:
var getData = function (key) {
var deferred = Q.defer();
if (cache[key]) {
deferred.resolve(cache[key]);
} else {
//Data request logic that returns 'data'
deferred.resolve(data);
}
return deferred.promise;
};
This way you're not guessing how long your requests are going to take and you're not forcing a second long load time on your user because the page will load as soon as your data has been retrieved.
By the way, the cache here is just a key/value store. Aka var cache = {};

Related

Puppeteer, awaiting a selector, and returning data from within

I am loading a page, intercepting its requests, and when a certain element shows up I stop loading and extract the data I need...
Here is the problem that I am faced with.
When simplified the code looks actually something like this:
async function loadPage()
{
var contentLoaded = false;
var content;
//now i say when element shows up, do something
// it is page.waitForSelector but for simplicity, i use a timeout
// because the problem is the same
//i set it to "show up" in 10 seconds here.
//when it shows up, it sets the content to 100 (extracts the content i want)
//and stores it..
setTimeout(()=>{
content = 100;
contentLoaded = true;
},10000)
//Here i have a function that loads the page
//Intercepts request and handles them
//Until content is loaded
page.on('request', req =>{
if(!contentLoaded)
{
// keep loading page
}
})
// this is the piece of code i would like to not run,
// UNTIL i either get the data, or a timeout error
// from page.waitForSelector...
//but javascript will run it if it's not busy with the
//loading function above...
// In 10 seconds the content shows
// and it's stored in DATA, but this piece of code has
// already finished by the time that is done...
// and it returns false...
if(contentLoaded)
{return content}
else
{return false}
}
var x = loadPage();
x.then(console.log); //should log the data or false if error occured
Thank you all for taking the time to read this and help out, I'm a novice so any feedback or even reading material is welcome if you think there is something I'm not fully understanding
Solved
Simple explanation:
Here is what I was trying to accomplish:
Intercept page requests so that I can decide what not to load, and speedup loading
Once an element shows up on the page, i want to extract some data and return it.
I was trying to return it like this: (note, all the browser and error handling will be left out in these since it would just clutter the explanation)
var data = loadPage(url);
async function loadPage(URL)
{
var data;
page.waitForSelector(
var x = //page.evaluate returns data to x...
data = x;
)
return data;
}
Which doesn't work since return runs immediately but waitForSelector runs later, so we always return undefined...
The correct way of doing it, or rather the way it works for me is to return the whole promise, and then extract the data...
var data = loadPage(url);
data.then(//do what needs to be done with the data);
async function loadPage(URL)
{
var data = page.waitForSelector(
var x = //page.evaluate returns data to x...
data = x;
)
return data; // we return data as a promise
}
I hope it's a solid enough explanation, if someone needs to see the whole deal, I could edit the question and place the whole code there...

Using Localstorage to store and retrieve javascript variables from one html page to another (DOM)

I have one html page 1.html and i want to get some text content and store it to a js.js file using jquery to get the text by id.
This code only works in 1.html page, where the text I want to copy from is but not in 2.html file.
Here is my code. Note that it works if I store text inside localstorage setter second parameter.
$( document ).ready(function() {
var c1Title= $('#r1c1Title').text();
//changing c1Title to any String content like "test" will work
localStorage.setItem("t1",c1Title);
var result = localStorage.getItem("t1");
$("#title1").html(result);
alert(result);
});
Here is the complete demo I am working on Github:
You need to use either localStorage or cookies.
With localStorage
On the first page, use the following code:
localStorage.setItem("variableName", "variableContent")
That sets a localStorage variable of variableName for the domain, with the content variableContent. You can change these names and values to whatever you want, they are just used as an example
On the second page, get the value using the following code:
localStorage.getItem("variableName")
That will return the value stored in variableName, which is variableContent.
Notes
There is a 5MB limit on the amount of data you can store in localStorage.
You can remove items using localStorage.removeItem("variableName").
Depending on where you are, you may need to take a look at the cookie policy (this effects all forms of websites storing data on a computer, not just cookies). This is important, as otherwise using any of these solutions may be illegal.
If you only want to store data until the user closes their browser, you can use sessionStorage instead (just change localStorage to sessionStorage in all instances of your code)
If you want to be able to use the variable value on the server as well, use cookies instead - check out cookies on MDN
For more information on localStorage, check out this article on MDN, or this one on W3Schools
Please try to use this code. It's better to use local storage.
Here you need to make sure that you are setting this local storage
value in parent html page or parent js file.
create local storage
localStorage.setItem("{itemlable}", {itemvalue});
localStorage.setItem("variable1", $('#r1c1Title').text());
localStorage.setItem("variable2", $('#r1c2Title').text());
Get local storage value
localStorage.getItem("{itemlable}")
alert(localStorage.getItem("variable1") + ' Second variable ::: '+ localStorage.getItem("variable2"));
For more information follow this link https://www.w3schools.com/html/html5_webstorage.asp
If you wanted to store in div then follow this code.
Html Code
<div class="div_data"></div>
Js code:
$(document).ready(function () {
localStorage.setItem("variable1", "Value 1");
localStorage.setItem("variable2", "Value 2");
$(".div_data").html(' First variable ::: '+localStorage.getItem("variable1") + ' Second variable ::: '+ localStorage.getItem("variable2"));
});
Hope this helps.
You can use local storage as mentioned in above comments. Please find below how to write in javascript.
Local Storage Pros and Cons
Pros:
Web storage can be viewed simplistically as an improvement on cookies, providing much greater storage capacity.
5120KB (5MB which equals 2.5 Million chars on Chrome) is the default storage size for an entire domain.
This gives you considerably more space to work with than a typical 4KB cookie.
The data is not sent back to the server for every HTTP request (HTML, images, JavaScript, CSS, etc) - reducing the amount of traffic between client and server.
The data stored in localStorage persists until explicitly deleted. Changes made are saved and available for all current and future visits to the site.
Cons:
It works on same-origin policy. So, data stored will only be available on the same origin.
// Store value in local storage
localStorage.setItem("c1Title", $('#r1c1Title').text());
// Retrieve value in local storage
localStorage.getItem("c1Title");
Your html div
<div id="output"></div>
Add Javascript Code
$('#output').html(localStorage.getItem("c1Title"));
Let me know if it not works
Create a common.js file and modified this and save.
Session = (function () {
var instance;
function init() {
var sessionIdKey = "UserLoggedIn";
return {
// Public methods and variables.
set: function (sessionData) {
window.localStorage.setItem(sessionIdKey, JSON.stringify(sessionData));
return true;
},
get: function () {
var result = null;
try {
result = JSON.parse(window.localStorage.getItem(sessionIdKey));
} catch (e) { }
return result;
}
};
};
return {
getInstance: function () {
if (!instance) {
instance = init();
}
return instance;
}
};
}());
function isSessionActive() {
var session = Session.getInstance().get();
if (session != null) {
return true;
}
else {
return false;
}
}
function clearSession() {
window.localStorage.clear();
window.localStorage.removeItem("CampolUserLoggedIn");
window.location.assign("/Account/Login.aspx");
}
Insert like this.
$(function () {
if (!isSessionActive()) {
var obj = {};
obj.ID = 1;
obj.Name = "Neeraj Pathak";
obj.OrganizationID = 1;
obj.Email = "npathak56#gmail.com";
Session.getInstance().set(obj);
}
///clearSession();
});
get like this way
LoggedinUserDetails = Session.getInstance().get();

Continual counter regardless of page refresh

I have this piece of jQuery that currently increments a number by one every 5 seconds. The problem I have is that its client side, therefore it resets every time you refresh the page.
Instead I'd like the counter to continue even if you are away from the site and regardless of how many times you refresh the page, which is why I thought a server side script such as PHP would be better suited to my use case. If not please suggest otherwise.
I've setup a working fiddle of what I currently have with jQuery: http://jsfiddle.net/f354bzy5/
What would be the PHP to recreate this affect that include my requirements above?
Here's the Jquery I'm using:
//Counter
var counter = 22000000000;
$(".count").html(counter);
setInterval(function () {
$(".count").html(counter);
++counter;
}, 5000);
Check this DEMO
//Counter
var counter=22000000000;
if(typeof(localStorage.getItem('counts'))!='object')
{
counter=parseInt(localStorage.getItem('counts'));
}
setInterval(function () {
$(".count").html(counter);
++counter;
localStorage.setItem('counts',counter);
}, 1000);
Highlight on localStorage
localStorage is an implementation of the Storage Interface. It stores
data with no expiration date, and gets cleared only through
JavaScript, or clearing the Browser Cache / Locally Stored Data -
unlike cookie expiry.
Can you store counter in cookie.
document.cookie = counter.
so you can get last value from cookie, if user refresh the page.
It comes down to two simple choices for you. Just choose the right one which better fits your requirement:
Choose Cookie : If you want the server side to access the counter. Remember cookies are sent along with the requests by default.
Choose Local Storage : If you don't want to send the counter along with requests every time, you are supposed to go for local storage.
You could do it with localStorage. Here's how I am doing it. You can tweak it as you need.
//detecting support for localStorage.
if (window.localStorage) {
//counterValue already exists in localStorage? Let's use that or set to zero.
var counterValue = localStorage.counterValue || 0;
setInterval(function() {
//increment the counter and store updated vale in localStorage as well.
localStorage.counterValue = ++counterValue;
//put it in your HTML if you might
$(".count").html(counterValue);
}, 5000);
}
How about using localStorage with some utility functions? Bear in mind that this is a client side solution and the item would be wiped off when the user deletes the browser cache/local data etc.
function isLocalStorage() {
try {
return 'localStorage' in window && window['localStorage'] !== null;
} catch(e) {
return false;
}
}
function setCounter(key, val) {
localStorage.setItem(key, val);
}
function getCounter(key) {
return parseInt(localStorage.getItem(key), 10);
}
(function() {
var key = "myCounter";
var counter = isLocalStorage() && getCounter(key) || 1;
var $placeholder = $(".count");
$placeholder.html(counter);
setInterval(function () {
counter++;
$placeholder.html(counter);
isLocalStorage() && setCounter(key, counter);
}, 2000);
}());
-- Demo --

How to load page only once

Below is my code but page load continuously,i want to load only once
window.onload = function () {
window.location.reload();
}
There are a few ways you could solve this, all of which require saving state across page loads. You could use cookies, localStorage, the location object itself, etc.
Here's a way that checks to see if there is a hash string 'reloaded' and, if not, adds it and reloads the page. Then, when it tries to execute again, the hash will be there and it will not reload:
if (location.hash.indexOf('reloaded') === -1) {
location.hash += 'reloaded';
location.reload();
}
$(document).ready(function(){
if(document.URL.indexOf("#")==-1){ //Check if the current URL contains '#'
url = document.URL+"#"; // use "#". Add hash to URL
location = "#";
location.reload(true); //Reload the page
}
});
Due to the if condition page will reload only once.
The other way to achieve this is :
(function()
{
if( window.localStorage )
{
if( !localStorage.getItem('firstLoad') )
{
localStorage['firstLoad'] = true;
window.location.reload();
}
else
localStorage.removeItem('firstLoad');
}
})();
window.onload = function ()
{
// for getting params value
function parse(val)
{
var result = "not found";
tmp = [];
location.search
.substr(1)
.split("&")
.forEach(function (item) {
tmp = item.split("=");
if (tmp[0] === val) result = decodeURIComponent(tmp[1]);
});
return result;
}
if(parse("load")!="once")
{
//sending parameter so next time it won't reload..
window.location.href += "?load=once";
window.location.reload();
}
}
By nature of visiting a page, It will only load once. You could change your code to prove this fact:
window.onload = function () {
alert("Loaded");
}
But, I would suggest the vapor.js route to detecting page load, that is, omit this onload call, because the lines of code in the onload function run after the page is loaded. I think you either don't know what your goal is or you have an entirely different problem you are trying to solve in a way that does not make sense
You built a loop,
site is loading
window.onload is triggered
reload is initiaded
site is (re-)loading
window.onload is triggered
reload is initiaded
.......
.......
Important fact for you to learn is that browsers run through your code from top to bottom and when you reload your page, the whole prozess repeats.
So every Time you reload, the window.onload event-listener is registered and calls the function attached to it, as soon as the window object is fully loaded.
There is no mechanism that tells the browser to stop.
if you would like run your Javascript code once the DOM is loaded, and you are looking for an browser independent solution i would recommend jQuery and its $( document ).ready() function.
with jQuery included to your Page:
$( document ).ready(function(){
//Code inside this function runs after your document is loaded
})

Reset jQuery AJAX timeout externally

I was wondering if there is any possibility through which one can reset the timeout of an AJAX request through an 'external' control. For example, let's say I have the following:
jQuery.fn.worker = function worker() {
$.get('/home/GetData', function (data) {
// Manipulate retrieved data
});
setTimeout(worker, 30000);
};
Would it be possible to have, let's say, a button through which I could reset the worker's timeout?
Thank you in advance!
Assuming you make the timer available globally, you can use clearTimeout(timer).
var timer = setTimeout(worker, 30000); // create
clearTimeout(timer); // clear

Categories

Resources