Related
I've been having a problem that when my auto clicker in my clicker game goes fast enough to get to 200 thousand, it starts to lag, and then it doesn't function properly, or as fast.
Is there a way to make 100 thousand turn into 100K, and 101 thousand turn into 101K without being repetitive?
I tried this with my original code, and realized putting up to 1000 suffixes into each function would be a little too hard:
if (number >= 100000) {
document.getElementById(ID).innerHTML = "100K"
}
if (number >= 101000) {
document.getElementById(ID).innerHTML = "101K"
}
and on and on.
I don't want multiple if statements!
This would work, but it would take up way too much space, and I know there is an easier way to it, but I just couldn't find it. Can anyone provide a way to do this?
Try separating the job of formatting your number into a different function.
SUFFIXES = 'KMBTqQsSOND' // or whatever you'd like them to be
function getSuffixedNumber(num) {
var power = Math.floor(Math.log10(num));
var index = Math.floor(power / 3);
num = Math.round(num / Math.pow(10, (index * 3))); // first 3 digits of the number
return num + (SUFFIXES[index - 1] || ''); // default to no suffix if we get an out of bounds index
}
You can call the function like this: var x = getSuffixedNumber(101000), the value of x will be "101K".
I have a js which is integrated into other websites. When the user enters the site, a function is called from the script and an element pops up.
Is it possible for me, in the js function that pops-up the element, to make it open only for a certain percentage (let's say 60%) of the users?
I thought about using the Math.random() function, but i'm not sure how to make it.
EDIT:
After thinking about it, it might be that this is not achievable by javascript alone and it will require the use of some kind of tracking of users (via database or such). If someone knows of a different way, I'll be happy to hear it.
It is easily achievable by Javascript, and it's very simple!
var pctg = 60; // Set percentage here
var rndm = Math.ceil(Math.Random() * 100);
if (rndm <= pctg) {
// Execute popup statement(s)
}
On a first glance, this code snippet gives a 60% chance that the popup will occur: that is, one page view is completely independent from another page view. It can easily happen that 20 or more subsequent visitors get the popup, but the opposite is also possible. But the more visitors, the closer the 60% will be approached.
If you want to be mercillesly accurate, you can say 'set the percentage that a given visitor will receive the popup'.
This method will not attempt any kind of balance, it relies purely on sheer number of page views. Also, do not forget, that this is per page view.
If you want to remember whether or not a certain user should receive popups between visits, you can use cookies:
document.cookie="bShowPopup=0"; or document.cookie="bShowPopup=1";
This also opens up the possibility to create a more powerful code, one that creates a given chance of displaying the popup per page view, up until the point that the popup has already been displayed once:
First a function to read and write the specified cookie string:
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) != -1) return c.substring(name.length,c.length);
}
return "";
}
function setCookie(cname, cvalue, exdays) {
var d = new Date();
d.setTime(d.getTime() + (exdays*24*60*60*1000));
var expires = "expires="+d.toUTCString();
document.cookie = cname + "=" + cvalue + "; " + expires;
}
Please check out http://www.w3schools.com/js/js_cookies.asp for more information regarding the use of cookies.
Next we could do this:
// See if the user already received the popup
// The if statement will only evaluate to true if the popup is *not* explicitly disabled (that is, it is set to 1, or not set)
if (getCookie('bShowPopup') !== '0')
{
var pctg = 60; // Set percentage here
var rndm = Math.ceil(Math.Random() * 100);
if (rndm <= pctg) {
// Execute popup statement(s)
//stmt123....
// Set cookie bShowPopup to 0 (so the user won't receive popups ever again)
// NOTE: The cookie will expire after 30 days.
setCookie('bShowPopup', '0', 30);
}
}
Another approach, that will create the closest result without any server-side programming or user-tracking is to check whether a certain user should be shown popups only once, and then store the decision result in a cookie. The only thing to modify in the previous code is to set the bShowPopup cookie to 0 even if the popup wasn't shown.
if (getCookie('bShowPopup') !== '0')
{
var pctg = 60; // Set percentage here
var rndm = Math.ceil(Math.Random() * 100);
if (rndm <= pctg) {
// Execute popup statement(s)
//stmt123....
}
setCookie('bShowPopup', '0', 30);
}
Please, also refer to http://www.w3schools.com/jsref/jsref_random.asp regarding the use and return valies of Math.random().
Using Math.Random() is a good choice for this. Math.Random() generates a number between 0 and 1, so if you want a random number between 0 and 10, multiply the result by 10, then take the ceiling of that number to remove the decimal places and convert it to a round number. For 0 to 100, multiply it by 100. At the beginning of your pop-up function, add the following:
var rand = Math.Random() * 100;
next wrap the code that displays the popup in an if statement that checks to see if the random number you generated is less than or equal to 60:
if(Math.ceil(rand) <= 60) {
...
}
Heres an example of what I did when I needed this functionality
The following code would be a bit easier to maintain if you change the number of options or the chance percentage.
var contentId, random = Math.random();
if (random < 0.5) {
// option 1: chance 0.0–0.499...
contentId = 0;
} else (random < 0.75) {
// option 2: chance 0.50—0.7499...
contentId = 1;
} else {
// option 3: chance 0.75–0.99...
contentId = 2;
}
loadContent(contentId);
EDIT Based on comment feedback.
Glad to help. If this is a php page then you don't need ajax. Simply update/return the count at the top of the page via php/sql and then echo that figure into your JS function. You only need to check whether the figure is divisible by 3. If it is then run your popup function. This way you can also report on the amount of times the popup would have been activated.
I'm attempting to build an app that calculates sales metrics. I have run into an unusual problem in my build.
Part of the app allows users to increase/decrease a variable by 5% and then see how that will effect an overall metric. It also allows the user to see the percentage increase/decrease.
I have the functionality working roughly as intended, however if I enter a number lower than 20 into the input and then try in increase it with my incrementing function it only increments once and then stops.
If the number I enter into the input is 20 or greater it increments in the intended way.
Below is my angular code:
function controller ($scope) {
$scope.firstNumber = 0;
$scope.firstPercent = 0;
$scope.increase = function(id) {
var A = parseInt(id);
var B = A * 5/100;
var C = 0;
var C = A + B;
if (id === $scope.firstNumber) {
$scope.firstNumber = C;
$scope.firstPercent = $scope.firstPercent + 5;
}
};
$scope.decrease = function(id) {
var A = parseInt(id);
var B = A * 5/100;
var C = 0;
var C = A - B;
if (id === $scope.firstNumber) {
$scope.firstNumber = C;
$scope.firstPercent = $scope.firstPercent - 5;
}
};
I can't see anything wrong with my maths, my thinking is that perhaps I'm approaching angular in the wrong way. However I'm not sure.
I have put together a fiddle that shows the full code.
jsFiddle
I have updated the fiddle to use parseFloat. Seems like the numbers are incrementing now.
var A = parseFloat(id);
http://jsfiddle.net/kjDx7/1/
The reason why it was working with values above 20 was that it was just reading the part before decimals each time it tried to increase. So 20 became 21 and 22.05 and so on. As long the the value before decimal kept changing, it showed different (but incorrect) answers.
On the other hand, 10 became 10.5 which when parsed yielded 10. As you can see, this cycle continued endlessly.
The reason why you face the issue is because 5% of anything less than or equal to 20 is less than or equal to 1.
When you parseInt() the value, you always end up with the same number again.
Take 15 for example.
5% of 15 = 15.75
After parseInt(), you get the value 15 again.
You use the same value to increment / decrement each time.
Hence for values below 20, you don't get any changes.
As #Akash suggests, use parseFloat() instead - or why even do that when the value that you get is float anyway
I made a fork of your fiddle. I'm not completely sure what you want to achive.
Take a look at this fiddle.
$scope.increase = function() {
$scope.firstPercent = $scope.firstPercent + 5;
var A = $scope.firstNumber;
var B = (A / 100) * $scope.firstPercent;
var C = A + B;
$scope.firstNumberWithPercent = C;
};
update
After posting, i see that question is already answered. But is this what you really want? When you hit increase, it takes 5 % off of the number in the input field. That is ok, but when you hit decrease after that, it takes 5 % off the number in the same field. So your starting point is different.
100 + 5/100 = 105
105 - 5/105 = 99,75
I am currently developing a site that will make use of HTML5's localStorage. I've read all about the size limitations for different browsers. However, I haven't seen anything on how to find out the current size of a localStorage instance. This question seems to indicate that JavaScript doesn't have a built in way of showing the size for a given variable. Does localStorage have a memory size property that I haven't seen? Is there an easy way to do this that I'm missing?
My site is meant to allow users to enter information in an 'offline' mode, so being able to give them a warning when the storage is almost full is very important.
Execute this snippet in JavaScript console (one line version):
var _lsTotal=0,_xLen,_x;for(_x in localStorage){ if(!localStorage.hasOwnProperty(_x)){continue;} _xLen= ((localStorage[_x].length + _x.length)* 2);_lsTotal+=_xLen; console.log(_x.substr(0,50)+" = "+ (_xLen/1024).toFixed(2)+" KB")};console.log("Total = " + (_lsTotal / 1024).toFixed(2) + " KB");
The same code in multiple lines for reading sake
var _lsTotal = 0,
_xLen, _x;
for (_x in localStorage) {
if (!localStorage.hasOwnProperty(_x)) {
continue;
}
_xLen = ((localStorage[_x].length + _x.length) * 2);
_lsTotal += _xLen;
console.log(_x.substr(0, 50) + " = " + (_xLen / 1024).toFixed(2) + " KB")
};
console.log("Total = " + (_lsTotal / 1024).toFixed(2) + " KB");
or add this text in the field 'location' of a bookmark for convenient usage
javascript: var x, xLen, log=[],total=0;for (x in localStorage){if(!localStorage.hasOwnProperty(x)){continue;} xLen = ((localStorage[x].length * 2 + x.length * 2)/1024); log.push(x.substr(0,30) + " = " + xLen.toFixed(2) + " KB"); total+= xLen}; if (total > 1024){log.unshift("Total = " + (total/1024).toFixed(2)+ " MB");}else{log.unshift("Total = " + total.toFixed(2)+ " KB");}; alert(log.join("\n"));
P.S. Snippets are updated according to request in the comment. Now the calculation includes the length of the key itself.
Each length is multiplied by 2 because the char in javascript stores as UTF-16 (occupies 2 bytes)
P.P.S. Should work both in Chrome and Firefox.
Going off of what #Shourav said above, I wrote a small function that should accurately grab all your the localStorage keys (for the current domain) and calculate the combined size so that you know exactly how much memory is taken up by your localStorage object:
var localStorageSpace = function(){
var allStrings = '';
for(var key in window.localStorage){
if(window.localStorage.hasOwnProperty(key)){
allStrings += window.localStorage[key];
}
}
return allStrings ? 3 + ((allStrings.length*16)/(8*1024)) + ' KB' : 'Empty (0 KB)';
};
Mine returned: "30.896484375 KB"
You can get the current size of the local storage data using the Blob function. This may not work in old browsers, check the support for new Blob and Object.values() at caniuse.
Example:
return new Blob(Object.values(localStorage)).size;
Object.values() turns the localStorage object to an array. Blob turns the array into raw data.
IE has a remainingSpace property of the Storage object. The other browsers have no equivalent at this time.
I believe that the default amount of space is 5MB, although I have not tested it personally.
Here is a simple example of how to do this and should work with every browser
alert(1024 * 1024 * 5 - unescape(encodeURIComponent(JSON.stringify(localStorage))).length);
Hope this help someone.
Because Jas- example on jsfiddle does not work for me I came up with this solution.
(thanks to Serge Seletskyy and Shourav for their bits I used in the code below)
Below is the function that can be used to test how much space is available for localStorage and (if any keys are already in lS) how much space is left.
It is a little brute force but it works in almost every browser... apart from Firefox.
Well in desktop FF it takes ages (4-5min) to complete, and on Android it just crashes.
Underneath the function is a short summary of tests that I have done in different browsers on different platforms. Enjoy!
function testLocalStorage() {
var timeStart = Date.now();
var timeEnd, countKey, countValue, amountLeft, itemLength;
var occupied = leftCount = 3; //Shurav's comment on initial overhead
//create localStorage entries until localStorage is totally filled and browser issues a warning.
var i = 0;
while (!error) {
try {
//length of the 'value' was picked to be a compromise between speed and accuracy,
// the longer the 'value' the quicker script and result less accurate. This one is around 2Kb
localStorage.setItem('testKey' + i, '11111111112222222222333333333344444444445555555555666661111111111222222222233333333334444444444555555555566666');
} catch (e) {
var error = e;
}
i++;
}
//if the warning was issued - localStorage is full.
if (error) {
//iterate through all keys and values to count their length
for (var i = 0; i < localStorage.length; i++) {
countKey = localStorage.key(i);
countValue = localStorage.getItem(localStorage.key(i));
itemLength = countKey.length + countValue.length;
//if the key is one of our 'test' keys count it separately
if (countKey.indexOf("testKey") !== -1) {
leftCount = leftCount + itemLength;
}
//count all keys and their values
occupied = occupied + itemLength;
}
;
//all keys + values lenght recalculated to Mb
occupied = (((occupied * 16) / (8 * 1024)) / 1024).toFixed(2);
//if there are any other keys then our 'testKeys' it will show how much localStorage is left
amountLeft = occupied - (((leftCount * 16) / (8 * 1024)) / 1024).toFixed(2);
//iterate through all localStorage keys and remove 'testKeys'
Object.keys(localStorage).forEach(function(key) {
if (key.indexOf("testKey") !== -1) {
localStorage.removeItem(key);
}
});
}
//calculate execution time
var timeEnd = Date.now();
var time = timeEnd - timeStart;
//create message
var message = 'Finished in: ' + time + 'ms \n total localStorage: ' + occupied + 'Mb \n localStorage left: ' + amountLeft + "Mb";
//put the message on the screen
document.getElementById('scene').innerText = message; //this works with Chrome,Safari, Opera, IE
//document.getElementById('scene').textContent = message; //Required for Firefox to show messages
}
And as promised above some test in different browsers:
GalaxyTab 10.1
Maxthon Pad 1.7 ~1130ms 5Mb
Firefox 20.0(Beta 20.0) crashed both
Chrome 25.0.1364.169 ~22250ms /5Mb
Native (identifies as Safari 4.0/Webkit534.30) ~995ms /5Mb
iPhone 4s iOS 6.1.3
Safari ~ 520ms /5Mb
As HomeApp ~525ms / 5Mb
iCab ~ 710ms /5mb
MacBook Pro OSX 1.8.3 (Core 2 Duo 2.66 8Gb memory)
Safari 6.0.3 ~105ms /5Mb
Chrome 26.0.1410.43 ~3400ms /5Mb
Firefox 20.0 300150ms(!) /10Mb (after complaining about script running to long)
iPad 3 iOS 6.1.3
Safari ~430ms /5Mb
iCab ~595ms /5mb
Windows 7 -64b (Core 2 Duo 2.93 6Gb memory)
Safari 5.1.7 ~80ms /5Mb
Chrome 26.0.1410.43 ~1220ms /5Mb
Firefox 20.0 228500ms(!) /10Mb (after complaining about script running to long)
IE9 ~17900ms /9.54Mb ( if any console.logs are in the code does not work until DevTools are opened)
Opera 12.15 ~4212ms /3.55Mb (this is when 5Mb is selected, but Opera asks nicely if we want increase the amount of lS, unfortunately it crashes if test conducted a few times in a row)
Win 8 (Under Parallels 8)
IE10 ~7850ms /9.54Mb
You can calculate your localstorage by following methods:
function sizeofAllStorage(){ // provide the size in bytes of the data currently stored
var size = 0;
for (i=0; i<=localStorage.length-1; i++)
{
key = localStorage.key(i);
size += lengthInUtf8Bytes(localStorage.getItem(key));
}
return size;
}
function lengthInUtf8Bytes(str) {
// Matches only the 10.. bytes that are non-initial characters in a multi-byte sequence.
var m = encodeURIComponent(str).match(/%[89ABab]/g);
return str.length + (m ? m.length : 0);
}
console.log(sizeofAllStorage());
Finally size in bytes will be logged in browser.
I would use the code of #tennisgen which get all and count the content, but I count the keys themselves:
var localStorageSpace = function(){
var allStrings = '';
for(var key in window.localStorage){
allStrings += key;
if(window.localStorage.hasOwnProperty(key)){
allStrings += window.localStorage[key];
}
}
return allStrings ? 3 + ((allStrings.length*16)/(8*1024)) + ' KB' : 'Empty (0 KB)';
};
The way I went about this problem is to create functions for finding out the used space and remaining space in Local Storage and then a function that calls those functions to determine the max storage space.
function getUsedSpaceOfLocalStorageInBytes() {
// Returns the total number of used space (in Bytes) of the Local Storage
var b = 0;
for (var key in window.localStorage) {
if (window.localStorage.hasOwnProperty(key)) {
b += key.length + localStorage.getItem(key).length;
}
}
return b;
}
function getUnusedSpaceOfLocalStorageInBytes() {
var maxByteSize = 10485760; // 10MB
var minByteSize = 0;
var tryByteSize = 0;
var testQuotaKey = 'testQuota';
var timeout = 20000;
var startTime = new Date().getTime();
var unusedSpace = 0;
do {
runtime = new Date().getTime() - startTime;
try {
tryByteSize = Math.floor((maxByteSize + minByteSize) / 2);
//localStorage.setItem(testQuotaKey, new Array(tryByteSize).join('1'));
//Recommended by #pkExec and #jrob007
localStorage.setItem(testQuotaKey, String('1').repeat(tryByteSize));
minByteSize = tryByteSize;
} catch (e) {
maxByteSize = tryByteSize - 1;
}
} while ((maxByteSize - minByteSize > 1) && runtime < timeout);
localStorage.removeItem(testQuotaKey);
if (runtime >= timeout) {
console.log("Unused space calculation may be off due to timeout.");
}
// Compensate for the byte size of the key that was used, then subtract 1 byte because the last value of the tryByteSize threw the exception
unusedSpace = tryByteSize + testQuotaKey.length - 1;
return unusedSpace;
}
function getLocalStorageQuotaInBytes() {
// Returns the total Bytes of Local Storage Space that the browser supports
var unused = getUnusedSpaceOfLocalStorageInBytes();
var used = getUsedSpaceOfLocalStorageInBytes();
var quota = unused + used;
return quota;
}
In addition to #serge's answer which is most voted here, size of the keys need to be considered. Code below will add the size of the keys stored in localStorage
var t = 0;
for (var x in localStorage) {
t += (x.length + localStorage[x].length) * 2;
}
console.log((t / 1024) + " KB");
As the spec goes, each character of a string is 16 bit.
But inspecting with chrome (Settings>Content Settings>Cookies & Site data) shows us that initiating localStorage takes 3kB (overhead size)
And stored data size follows this relation (accurate to 1kB)
3 + ((localStorage.x.length*16)/(8*1024)) kB
where localStorage.x is your storage string.
Yes, this question was asked like 10 years ago. But for those interested (like myself, as I am building an offline text editor that saves data with local storage) and suck at programming, you could use something simple like this:
var warning = 1;
var limit = 2000000; //2 million characters, not really taking in account to bytes but for tested number of characters stored
setInterval(function() {
localStorage["text"] = document.getElementById("editor").innerHTML; //gets text and saves it in local storage under "text"
if(localStorage["text"].length > limit && warning == 1){
alert("Local Storage capacity has been filled");
warning = 2; //prevent a stream of alerts
}
}, 1000);
//setInterval function saves and checks local storage
The best way to get the amount of storage filled is to view the site settings (say, if you stored an image in local storage). At least in chrome, you can see the amount of bytes used (ie: 1222 bytes). However, the best ways to see filled local storage with js have already been mentioned above, so use them.
//Memory occupy by both key and value so Updated Code.
var jsonarr=[];
var jobj=null;
for(x in sessionStorage) // Iterate through each session key
{
jobj={};
jobj[x]=sessionStorage.getItem(x); //because key will also occupy some memory
jsonarr.push(jobj);
jobj=null;
}
//https://developer.mozilla.org/en/docs/Web/JavaScript/Data_structures
//JavaScript's String type is used to represent textual data. It is a set of "elements" of 16-bit unsigned integer values.
var size=JSON.stringify(jsonarr).length*2; //16-bit that's why multiply by 2
var arr=["bytes","KB","MB","GB","TB"]; // Define Units
var sizeUnit=0;
while(size>1024){ // To get result in Proper Unit
sizeUnit++;
size/=1024;
}
alert(size.toFixed(2)+" "+arr[sizeUnit]);
window.localStorage.remainingSpace
Hey again everyone. Yet again i am having some problems with trying to get the match correct on this Excel Spreadsheet to JavaScript conversion.
Here is the excel formula:
=IF(IF($B$7=TRUE,$B$28/$B$10,$B$28/$B$5)>1,1,IF($B$7=TRUE,$B$28/$B$10,$B$28/$B$5))
WHERE
B7 = TRUE
B28 = 76800
B10 = 892015
B5 = 999500
And this is my JavaScript i have so far:
function percent(x) { return Math.round((x-0)*100) + '%'; }
if($('#section179').is(':checked'))
{
var percentRepaid = $("#rev3DScanYear").val() / $("#section179Real").val();
if (percentRepaid > 1)
{
$("#paymentCashPer").val('100.00');
}else
{
percentRepaid = $("#rev3DScanYear").val() / $("#SalePrice").val();
$("#paymentCashPer").val(percent(percentRepaid));
}
}else
{
//to be done
}
WHERE
rev3DScanYear = 76800
SalePrice = 999500
section179Real = 892015
For the JavaScript code i keep getting a value of 8% and i should be getting a value of 8.61% as it has on the spreadsheet.
As always, any help would be great! :o)
David
Math.round((x-0)*100) makes x an integer.
You could try Math.round(((x-0)*100)*100)/100 which makes the x = 8.609720... into x=861 and then divides it to get the x=8.61 you're looking for, which is what they would suggest here.
...Also, not really sure why you're subtracting 0 from x...?
Ok, so I've been looking at this again, and I think I didn't look deeply enough the first time.
The logic, if I understand it, is this:
If Section179 is checked then Divisor is Section179Real, else it is SalePrice.
Give me the smaller of 1.00 or (rev3DScanYear / Divisor).
If that's correct, you can do it in excel with =MIN(1,$B28/IF($B$7=TRUE,$B$10,$B$5)) (same references), which means that the following should do what you want it to:
var Divisor = $("#SalePrice");
if($('#section179').is(':checked'))
{
Divisor = $("#section179Real");
}
$("#paymentCashPer").val(Math.round(100*(Math.min(1, $("#rev3DScanYear")/Divisor)*100)/100;