Variables not saving after reloading a page - javascript

When I ran the code below, it would usually add a number to testUses if there was a successful login. However, when I reloaded, you could still access home.html and the variable testUses still stayed 0 which meant that for some reason, it did not change. Should I put testUses outside the function? Please answer a fix or tip to change this.
<!DOCTYPE html>
<html>
<head>
<script>window.history.replaceState(null, document.title, "/");</script>
<meta http-equiv="Cache-Control" content="no-cache, no-store, must-revalidate"/>
<meta http-equiv="Pragma" content="no-cache"/>
<meta http-equiv="Expires" content="0"/>
<title>A-ENGINE</title>
<meta name="viewport" content="width=device-width">
<link href='https://fonts.googleapis.com/css?family=Quicksand' rel='stylesheet'>
<style>
.full {
width: 100%;
height: 100%;
top: 0px;
left: 0px;
position: absolute;
overflow: hidden;
}
.center {
left: 50%;
top:50%;
transform: translate(-50%, -50%);
position: absolute;
}
</style>
</head>
<body style='overflow:hidden;padding:0px;visibilty:hidden'>
<div class='full'>
<div class='center' style='width:300px;padding:2px'>
<div class="cursor"><div class="planet"></div></div>
<input type= password id="access" placeholder="Access Key" onchange="access()"><br>
<script>
function access() {
let input = document.getElementById("access").value;
let testUses = +localStorage.getItem('testUses') || 0;
const testHash = "cyrb53('a') -> 4625896200565286";
const adminHash = "cyrb53('a') -> 4413594719508086";
const cyrb53 = (str, seed = 0) => {
let h1 = 0xdeadbeef ^ seed,
h2 = 0x41c6ce57 ^ seed;
for (let i = 0, ch; i < str.length; i++) {
ch = str.charCodeAt(i);
h1 = Math.imul(h1 ^ ch, 2654435761);
h2 = Math.imul(h2 ^ ch, 1597334677);
}
h1 = Math.imul(h1 ^ (h1 >>> 16), 2246822507) ^ Math.imul(h2 ^ (h2 >>> 13), 3266489909);
h2 = Math.imul(h2 ^ (h2 >>> 16), 2246822507) ^ Math.imul(h1 ^ (h1 >>> 13), 3266489909);
return 4294967296 * (2097151 & h2) + (h1 >>> 0);
};
let inputHash = (`cyrb53('a') -> ${cyrb53(input)}`);
function home() {
document.write('<iframe src="home.html" height="100%" width="100%"></iframe>');
}
if (inputHash == adminHash || inputHash == testHash) {
home();
} else if (inputHash == testHash && testUses <= 1) {
home();
testUses++;
localStorage.setItem('testUses', testUses);
} else {
document.getElementById('access').value = '';
}
}
</script>
</div>
</body>
</html>

You can store testUses in localStorage.
let testUses = +localStorage.getItem('testUses') || 0;
// update value:
testUses++;
localStorage.setItem('testUses', testUses);

Related

TypeError: Attempted to assign to readonly property - Vanilla Javascript Mouse Position

My expected result is for the image to move within the container according to the calculations made on the x-axis mouse position. That is why Xratio ranges from -1 to 1.
I am not sure what is the readonly property here?
I used console.log(typeof Xratio) and got "number".
I also used console.log(typeof easeOutExpo) and saw "function".
Could this be a simple mistake I am not understanding with assigning?
const bxImg = document.querySelector('.bx-pic');
document.addEventListener('mousemove', (e) => {
const xRatio = (e.clientX / window.innerWidth) * 2 - 1;
console.log(typeof xRatio);
const xRatioEased = 0;
if (xRatio >= 0) {
xRatioEased = easeOutExpo(xRatio);
} else {
xRatioEased = easeOutExpo(-xRatio * -1)
}
bxImg.style.transform = `scale(1.2) translate3D(${-xRatioEased * 10}px, ${0}, ${0})`;
})
function easeOutExpo(n) {
if (n === 1) {
return 1;
} else {
return 1 - Math.pow(2, -10 * n);
}
}
console.log(typeof easeOutExpo);
html, body {
width: 100%;
height: 100%;
}
body {
background-color: #FDFDFD;
}
img {
width: 100%;
height: 100%;
object-fit: cover;
}
.bx-wp {
position: absolute;
top: 50%;
left: 50%;
transform: translate(-50%, -50%);
overflow: hidden;
width: 350px;
height: 350px;
outline: 30px solid royalblue;
}
.bx {
position: relative;
transform: scale(1.2);
}
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<title></title>
<meta name="description" content="">
<meta name="viewport" content="width=device-width, initial-scale=1">
<link rel="stylesheet" href="style.css">
</head>
<body>
<div class="bx-wp">
<img src="https://images.unsplash.com/photo-1641113994135-a9f230b1f9b0?ixlib=rb-1.2.1&ixid=MnwxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8&auto=format&fit=crop&w=2670&q=80" alt="A Mountain" class="bx bx-pic">
</div>
<script src="script.js"></script>
</body>
</html>
You've declared xRatioEased as a const, so it can only be set on initialisation. Replace const xRatioEased with let xRatioEased and it should all work.
xRatioEased is a constant. Constants can be changed only on initialization. If you declare xRatioEased as a variable (with let or var), you can fix the issue.
If you want to know more about constants and when to use them, you can head over to this link

How to prevent a function form executing multiple times in a row in JS?

*It works now.
I am trying to make onEnter() and onSpace() functions not execute more then once in a row. For example, if I call onEnter(), it should execute the function only the first time, any calls in a row afterwards shouldn't execute. This is the same for onSpace().
The program should run in an order of onEnter() then onSpace() or vice versa, however, if one of the functions is repeated, it should just run it once.
If you run the code below, you can see the problem, press the "Enter" key to get the next question and press the "Space" bar to find the answer.
Thank you for taking the time to help, this is my first project after learning a bit of JavaScript, any tips on improving my code is much appreciated.
const onEnter = () => {
if (document.getElementById("answer").style.visibility="visible") {
document.getElementById("answer").style.visibility="hidden";
}
let x = Math.floor((Math.random() * 10) + 0);
let y = Math.floor((Math.random() * 10) + 0);
let addition = x + " + " + y;
let answer = x + y;
document.getElementById("question").innerHTML = addition;
document.getElementById("answer").innerHTML = answer;
toggleQuestion();
};
const toggleQuestion = () => {
let qTop = document.getElementById("question");
qTop.classList.toggle("questionAlt")
};
const onSpace = () => {
toggleQuestion();
document.getElementById("answer").style.visibility="visible";
}
document.body.addEventListener("keydown", function keyEnter() {
if (event.keyCode == 13) {
onEnter();
}
});
document.body.addEventListener("keydown", function keySpace() {
if (event.keyCode == 32) {
onSpace();
}
});
body {
overflow: hidden;
}
div {
position: fixed;
top: 0;
left: 0;
height: 97.9%;
width: 98.9%;
border: 10px solid rgb(0, 0, 0);
background-color: rgb(155, 163, 167);
}
#answer {
visibility: hidden;
}
button {
visibility: hidden;
}
#question {
position: absolute;
text-align: center;
margin-top: 15vw;
left: 40.6vw;
font-family: 'Knewave';
font-size: 8vw;
}
.question1 {
position: absolute;
animation: qBottom;
animation-duration:0.2s;
transition: 0.18s;
opacity: 1;
bottom: 13vw;
}
#keyframes qBottom {
0% {bottom:0.01px;}
100% {bottom: 13vw;}
}
#answer {
position: absolute;
color: white;
text-align: center;
width: 100%;
margin-top: 20%;
font-family: 'Knewave';
font-size: 5.8vw;
background-color: rgb(0, 0, 0);
}
.questionAlt {
position: absolute;
animation: qTop;
animation-duration:0.2s;
transition: 0.18s;
opacity: 0.5;
font-size: 20vw;
top: -10vw;
}
#keyframes qTop {
0% {top:0.01px;}
100% {top:-10vw;}
}
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width">
<title>repl.it</title>
<link href="style.css" rel="stylesheet" type="text/css" />
<link href='https://fonts.googleapis.com/css?family=Knewave' rel='stylesheet'>
</head>
<body>
<script src="script.js"></script>
<div id="plusBackground">
<button onclick="keyEnter()"> Next Question </button>
<button for="generate" onclick="" onclick="keySpace()"> Reveal </button>
<h1 id="question"> 8 + 8 </h1>
<h2 id="answer"> 16 </h2>
</div>
</body>
</html>
I updated my answer to meet your updated question
Actually you dont need to register multiple eventlistener :
let current;
document.body.addEventListener("keydown", function keyEnter() {
if (event.keyCode == 13 && event.keyCode != current) {
console.log("Enter")
current = event.keyCode;
}
if (event.keyCode == 32 && event.keyCode != current) {
console.log("space")
current = event.keyCode;
}
});
It's not quite clear what you mean by "once in a row" but does removeEventListener or the once option for addEventListener help get you to where you want to be?
You can create some simple flag for that, i.e:
// Set flag to false
let entered = false;
document.body.addEventListener("keydown", function keyEnter() {
if (event.keyCode == 13) {
// Check flag, if false, run function
if(!entered) {
// Set flag to true
entered = true;
// run your function once
onEnter();
}
}
});
I would use two global flag variables both initialized to true: okToRunEnter and okToRunSpace.
Each related function should return immediately if its associated global flag variables is false. If it passes that check, it should set both flag variables to false. Right before exiting, the function should set the other flag variable to true.

How to make an bouncing of element smooth onclick (only using vanilla JS)?

I want to make something that is like this:
http://www.lessmilk.com/imgtut/FB1/3.gif
But my square dosen't seem to bounce up properly (it should move up to a certain distance then fall back. Like that in example), especially when it is falling, it stops for in same position on first click and then requires second click to move up . What did I do wrong or is it not just tuned properly? Can it be done in some other way? Need help and suggestions.
Here is my code.
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8" />
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<title>Bounce</title>
<meta name="viewport" content="width=device-width, initial-scale=1">
<style>
.container {
background-color: aqua;
height: 300px;
width: 500px;
position: relative;
}
.square {
height: 25px;
position: absolute;
width: 25px;
background-color: brown;
}
</style>
</head>
<body>
<div class="container" onclick="accelerateUp()">
<div class="square" style="top:0; left:20px"></div>
</div>
<script>
var square = document.querySelector('.square');
var updateInterval, gravitySpeed = 0, gravity = 0.05;
function accelerateUp() {
clearInterval(updateInterval)
gravity = -0.2;
setTimeout(() => { gravity = 0.05 }, 100)
updateInterval = setInterval(() => accelerateDown(), 5)
}
function accelerateDown() {
let topValue = parseInt(square.style.top);
let leftValue = parseInt(square.style.left);
gravitySpeed += gravity;
square.style.top = topValue + gravitySpeed + 'px';
hitBottom();
}
function hitBottom() {
if (parseInt(square.style.top) > 250 || parseInt(square.style.top) < 0) {
gravitySpeed = 0;
}
}
updateInterval = setInterval(() => accelerateDown(), 5);
</script>
</body>
</html>
Instead of having an "accelerateUp" you should just consider setting the velocity to a specific/set value on each click OR changing the velocity by a set amount.
I think part of the problem is trying to manage how the acceleration changes as a result of the click hitting the square up, and I think it's just easier to change the velocity and let the acceleration remain constant.
const square = document.querySelector('.square');
const frameRate = 60; // fps
const yAcceleration = .5; // change in px / frame
const hitUpForce = -10;
let yVelocity = 0; // px / frame
let yPosition = 0; // px
function timeStep() {
// velocity changes position
const willHitGround = yPosition + yVelocity > 275
yPosition = willHitGround ? 275 : yPosition + yVelocity;
// accerlation changes velocity
yVelocity = willHitGround ? 0 : yVelocity + yAcceleration;
square.style.top = `${yPosition}px`
}
function hitUp() {
// just set contant velocity as result of hit
yVelocity = hitUpForce; // Or possibly yVelocity += hitUpForce
}
updateInterval = setInterval(timeStep, 1000/frameRate);
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8" />
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<title>Bounce</title>
<meta name="viewport" content="width=device-width, initial-scale=1">
<style>
.container {
background-color: aqua;
height: 300px;
width: 500px;
position: relative;
}
.square {
height: 25px;
position: absolute;
width: 25px;
background-color: brown;
}
</style>
</head>
<body>
<div class="container" onclick="hitUp()">
<div class="square" style="top:0; left:20px"></div>
</div>
</body>
</html>
Ok, I just figured it out that I have to reset the gravitySpeed variable to 0 on click (because when falling it's value is negative and that was stoping the ball from jumping on first click). So resetting the variable helped me. I posted the answer here so that it can help someone.
function accelerateUp() {
clearInterval(updateInterval);
gravitySpeed = 0;
gravity = -0.2;
setTimeout(() => { gravity = 0.05 }, 100)
updateInterval = setInterval(() => accelerateDown(), 5)
}

Downloading iFramePlayer Video

I want to download a video available here. Like the top right corner indicates, it might be hosted on Crunchyroll so let's inspect the page source.
This is the html code snippet of interest:
<div id="zype_5387dd4269702d063f000000" style="position: relative; padding-bottom: 56.25%; padding-top: 0; height: 0; overflow: hidden;">
<div style="position: relative; padding-bottom: 56.25%; padding-top: 0; height: 0; overflow: hidden;">
<iframe frameborder="0" width="100%" height="100%" id="_video_5387dd4269702d063f000000" src="https://www.crunchyroll.com/affiliate_iframeplayer?aff=af-88206-hkyj&media_id=663121&video_format=0&video_quality=0&auto_play=0" style="position: absolute; top: 0; left: 0; width: 100%; height: 100%;" nuan_newframe="true"></iframe>
</div>
</div>
Inspection reveals that the video is embedded in an iframe and indeed is hosted on Crunchyroll. It is also important to note that the src attribute is the link going directly to the video player page.
On the player page the HTML looks as follows:
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html xmlns="http://www.w3.org/1999/xhtml"lang="de" xml:lang="de">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<meta http-equiv="X-UA-Compatible" content="IE=EmulateIE7" />
<link rel="icon" href="/favicon.png" />
<title></title>
<script type="text/javascript" src="https://www.crunchyroll.com/common/static/js/swfobject.js"></script>
<link rel="stylesheet" type="text/css" href="https://www.crunchyroll.com/css//20150727144515.1ae5987b9d8aa2552cc16fb8eadc8e78/crcommon/reset.css"/>
<style>
body {
width: 100%;
height: 100%;
margin: 0;
padding: 0;
background-color: #000;
color: #FFF;
}
#content {
position: absolute;
top: 0;
right: 0;
bottom: 0;
left: 0;
}
</style>
<!--[if IE]>
<style type="text/css">
.clearfix { zoom: 1; /* triggers hasLayout */ display: block; /* resets display for IE/Win */}
.clearfix {display: inline-block;} /* for IE/Mac */
</style>
<![endif]-->
</head>
<body>
<div id="content"><div id="the_embedded_player" style="display:block;" ><div style="color:red; text-align:center; margin:16px 0px;">You either have Javascript turned off or an old version of Flash Player.<br/><br/> Get the latest Flash Player</div></div><script type="text/javascript"><!--
swfobject.embedSWF("https:\/\/www.crunchyroll.com\/flash\/20150615120132.eb0aab8f716ea6981edb6397bd93ffc3\/StandardVideoPlayer.swf",'the_embedded_player','100%', '100%', '9.0.115','https://www.crunchyroll.com/common/static/flash/express_install.swf',{"config_url":"http%3A%2F%2Fwww.crunchyroll.com%2Fxml%2F%3Freq%3DRpcApiVideoPlayer_GetStandardConfig%26media_id%3D663121%26video_format%3D0%26video_quality%3D0%26auto_play%3D0%26aff%3Daf-88206-hkyj%26show_pop_out_controls%3D0%26enable_next%3D0%26lang%3DdeDE"},{"wmode":"transparent","allowFullScreen":"true","allowscriptaccess":"always","allownetworking":"all"},{"id":"the_embedded_player","style":"display:block;"},null);
//--></script></div>
<!-- pylon16 : c64387480c -->
</body>
</html>
It becomes clear that the video must be a swf flash video file. embedSWF is called which is defined here and looks like this (after beautifying):
embedSWF: function(ab, ah, ae, ag, Y, aa, Z, ad, af, ac) {
var X = {
success: false,
id: ah
};
if (M.w3 && !(M.wk && M.wk < 312) && ab && ah && ae && ag && Y) {
w(ah, false);
K(function() {
ae += "";
ag += "";
var aj = {};
if (af && typeof af === r) {
for (var al in af) {
aj[al] = af[al]
}
}
aj.data = ab;
aj.width = ae;
aj.height = ag;
var am = {};
if (ad && typeof ad === r) {
for (var ak in ad) {
am[ak] = ad[ak]
}
}
if (Z && typeof Z === r) {
for (var ai in Z) {
if (typeof am.flashvars != D) {
am.flashvars += "&" + ai + "=" + Z[ai]
} else {
am.flashvars = ai + "=" + Z[ai]
}
}
}
if (F(Y)) {
var an = u(aj, am, ah);
if (aj.id == ah) {
w(ah, true)
}
X.success = true;
X.ref = an
} else {
if (aa && A()) {
aj.data = aa;
P(aj, am, ah, ac);
return
} else {
w(ah, true)
}
}
if (ac) {
ac(X)
}
})
} else {
if (ac) {
ac(X)
}
}
}
This obfuscated code doesn't look like it's going to lead anywhere.
Copying and pasting each of the links found in the html into the browser doesn't seem to allow downloading the video (idea taken from here). How do I get the correct url?
Note:
The programming code for downloading the video file is not the main focus here, but I would use this for html parsing and this for download the file.

Trying to create multiple shakes using shake.js

What I'm trying to accomplish here is to get an alert to show up every time the phone is shaken. But I keep getting an error saying:
Uncaught TypeError: Cannot call method 'addEventListener' of undefined
Is it because it doesn't know what 'shake' is? The reason for more than one shake is because I'll be adding different animations depending on what shake its on.
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="initial-scale=1.0, width=device-width, user-scalable=no" />
<meta name="apple-mobile-web-app-capable" content="yes" />
<title>Shake animation</title>
<style type="text/css">
body {
background: #E9E9E9;
color: #333;
font: 1em/1.3em "Helvetica Neue", Helvetica, Arial, Verdana, sans-serif; /* 16px / 21px */
text-shadow: rgba(255,255,255,0.8) 0 1px 0;
text-align: center;
}
</style>
<script type="text/javascript" src="shake.js"></script>
</head>
<body>
<div class="answerListener" id="answer1"></div>
<div class="answerListener" id="answer2"></div>
<div class="answerListener" id="answer3"></div>
<div class="answerListener" id="answer4"></div>
<script type="text/javascript">
window.onload = function() {
var answer = document.getElementsByClassName('answerListener');
var current = 1;
for (i = 0; answer.length; i++) {
answer[i].addEventListener('shake', function() {
if (current == 1) {
alert('shake1');
}
if (current == 2) {
alert('shake2');
}
if (current == 3) {
alert('shake3');
}
if (current == 4) {
alert('shake4');
}
current = current + 1;
}, false);
}
};
</script>
</body>
Your code looks good except for one small problem: your for loop does not terminate:
for (i = 0; answer.length; i++) {
should be
for (i = 0; i < answer.length; i++) {
You are getting the error because once i exceeds answer.length, answer[i] is undefined and therefore answer[i].addEventListener is attempting to call the method of a non-existing element.
Good luck.

Categories