JavaScript: How Do I Prevent A User From Crashing setInterval / setTimeout Event? - javascript

To see the problem click on https://jsfiddle.net/kjz1myL2/16/ and when the fade is complete move your mouse from button to button REALLY FAST.
Is there a way to prevent events from crashing or reset them when they crash? I made a JavaScript event that happens with setInterval. This helps work the fades. It is a very crucial part of the code, but it crashes SUPER EASILY! If a user switches between two elements too fast, it will crash the setInterval. I wanted to make a mouse pause event in which it stops the user's mouse or a mouse slow event that slows the mouse speed to the slowest possible speed until the setInterval is over, but people have stated that taking the control from the user is VERY DANGEROUS for VERY OBVIOUS REASONS. Not exploring that option, I decided to come here and ask for a more user-friendly solution to prevent the crash from happening. I have this code (PART OF THE CODE) [ADJUSTED]:
JavaScript
window.addEventListener("load", TourFunction);
var TourFadeInEvent;
var TourYesMouseEnterTimeEvent, TourNoMouseEnterTimeEvent;
var TourYesMouseEnterEvent, TourNoMouseEnterEvent;
var TourYesMouseLeaveEvent, TourNoMouseLeaveEvent;
Steps = 3;
TourFunction()
function TourFunction(){
if (Steps == 3){
Opacity = 0;
TourFadeInEvent = window.setInterval(TourFadeIn, 20);
}else{
TourYesMouseEnterEvent = TourInputYes.addEventListener("mouseenter", TourYesMouseEnter);
TourNoMouseEnterEvent = TourInputNo.addEventListener("mouseenter", TourNoMouseEnter);
}
function TourFadeIn(){
if (Opacity <= 0 || Opacity < 1){
Opacity = Opacity + .01;
TourContainer.style.opacity = Opacity;
}else{
clearInterval(TourFadeInEvent);
Steps += 1;
TourFunction();
return Steps;
}
}
function TourYesMouseEnter(){
TourYesMouseEnterTimeEvent = window.setInterval(TourYesMouseEnterTime, 10);
function TourYesMouseEnterTime(){
if (YesfgcR < 255){
YesfgcR += 5;
YesfgColor = "rgb(" + YesfgcR + ", " + YesfgcG + ", " + YesfgcB + ")";
TourInputYes.style.color = YesfgColor;
}if (YesbcR < 255){
YesbcR += 5;
YesbColor = "rgb(" + YesbcR + ", " + YesbcG + ", " + YesbcB + ")";
TourInputYes.style.borderColor = YesbColor;
}if (NofgcR > 0){
NofgcR = 0;
NofgColor = "rgb(" + NofgcR + ", " + NofgcG + ", " + NofgcB + ")";
TourInputNo.style.color = NofgColor;
}if (NobcR > 0){
NobcR = 0;
NobColor = "rgb(" + NobcR + ", " + NobcG + ", " + NobcB + ")";
TourInputNo.style.borderColor = NobColor;
}if (YesfgcR >= 255 && YesbcR >= 255 && NofgcR == 0 && NobcR == 0){
clearInterval(TourYesMouseEnterTimeEvent);
return YesfgcR, YesbcR, YesfgColor, YesbColor;
}
}
}
function TourNoMouseEnter(){
TourNoMouseEnterTimeEvent = window.setInterval(TourNoMouseEnterTime, 10);
function TourNoMouseEnterTime(){
if (NofgcR < 255){
NofgcR += 5;
NofgColor = "rgb(" + NofgcR + ", " + NofgcG + ", " + NofgcB + ")";
TourInputNo.style.color = NofgColor;
}if (NobcR < 255){
NobcR += 5;
NobColor = "rgb(" + NobcR + ", " + NobcG + ", " + NobcB + ")";
TourInputNo.style.borderColor = NobColor;
}if (YesfgcR > 0){
YesfgcR = 0;
YesfgColor = "rgb(" + YesfgcR + ", " + YesfgcG + ", " + YesfgcB + ")";
TourInputYes.style.color = YesfgColor;
}if (YesbcR > 0){
YesbcR = 0;
YesbColor = "rgb(" + YesbcR + ", " + YesbcG + ", " + YesbcB + ")";
TourInputYes.style.borderColor = YesbColor;
}if (NofgcR >= 255 && NobcR >= 255 && YesfgcR == 0 && YesbcR == 0){
clearInterval(TourNoMouseEnterTimeEvent);
return NofgcR, NobcR, NofgColor, NobColor;
}
}
}
}
The code runs fine if you don't switch from each button too fast but if you go to fast, it will crash. I have been experiencing this a lot and have not gotten an answer. PLEASE give me something to work off of.

Use CSS transitions for the color fade instead -
document.getElementById('Game1_TourInputYes').addEventListener('mouseover', switchActive);
document.getElementById('Game1_TourInputNo').addEventListener('mouseover', switchActive);
function switchActive(e) {
var others = document.getElementsByClassName('btn-tour-input');
for (let i = 0; i < others.length; i++) {
others[i].classList.remove('active');
}
this.classList.add('active');
}
input[type=button] {
background: transparent;
border: 3px solid black;
color: black;
transition: all .4s ease-in-out;
padding: 10px 30px;
}
input.active {
border: 3px solid red;
color: red;
}
<input class="btn-tour-input Tour_Input_Yes" id="Game1_TourInputYes" type="button" value="Yes" />
<input class="btn-tour-input Tour_Input_No" id="Game1_TourInputNo" type="button" value="No" />

Related

JavaScript text is not showing

I am having trouble with this html loading javascript animation - from https://codepen.io/atunnecliffe/pen/siqjd
The script is not printing the text inside the javascript but the screen is fading out at the end, like in the codepen example. Here is the JS right now:
var textarea = $(".term");
var speed = 50; //Writing speed in milliseconds
var text = "sh andrew_website.sh";
var i = 0;
runner();
function runner() {
textarea.append(text.charAt(i));
i++;
setTimeout(function () {
if (i < text.length) runner();
else {
textarea.append("<br>");
i = 0;
setTimeout(function () {
feedbacker();
}, 1000);
}
}, Math.floor(Math.random() * 220) + 50);
}
var count = 0;
var time = 1;
function feedbacker() {
textarea.append("[ " + count / 1000 + "] " + output[i] + "<br>");
if (time % 2 == 0) {
i++;
textarea.append("[ " + count / 1000 + "] " + output[i] + "<br>");
}
if (time == 3) {
i++;
textarea.append("[ " + count / 1000 + "] " + output[i] + "<br>");
i++;
textarea.append("[ " + count / 1000 + "] " + output[i] + "<br>");
i++;
textarea.append("[ " + count / 1000 + "] " + output[i] + "<br>");
}
window.scrollTo(0, document.body.scrollHeight);
i++;
time = Math.floor(Math.random() * 4) + 1;
count += time;
setTimeout(function () {
if (i < output.length - 2) feedbacker();
else {
textarea.append("<br>Initialising...<br>");
setTimeout(function () {
$(".load").fadeOut(1000);
}, 500);
}
}, time);
}
var output = [
One error that has occurred is the VAR speed is defined but not used anywhere in the JS code however I am at a loss of as to where it could be used. Any help would be appreciated, Thanks, Oliver.
Make sure to embed jQuery, works fine for me.
var textarea = $('.term');
var speed = 50; //Writing speed in milliseconds
var text = 'sh andrew_website.sh';
var i = 0;
runner();
function runner() {
textarea.append(text.charAt(i));
i++;
setTimeout(
function() {
if (i < text.length)
runner();
else {
textarea.append("<br>")
i = 0;
setTimeout(function() {feedbacker();}, 1000);
}
}, Math.floor(Math.random() * 220) + 50);
}
var count = 0;
var time = 1;
function feedbacker() {
textarea.append("[ " + count / 1000 + "] " + output[i] + "<br>");
if (time % 2 == 0) {
i++;
textarea.append("[ " + count / 1000 + "] " + output[i] + "<br>");
}
if (time == 3) {
i++;
textarea.append("[ " + count / 1000 + "] " + output[i] + "<br>");
i++;
textarea.append("[ " + count / 1000 + "] " + output[i] + "<br>");
i++;
textarea.append("[ " + count / 1000 + "] " + output[i] + "<br>");
}
window.scrollTo(0, document.body.scrollHeight);
i++;
time = Math.floor(Math.random() * 4) + 1;
count += time;
setTimeout(
function() {
if (i < output.length - 2)
feedbacker();
else {
textarea.append("<br>Initialising...<br>");
setTimeout(function() {$(".load").fadeOut(1000);}, 500);
}
},time);
}
var output = ["TESTING",
"WORKING",
"fsdfsdfsdfsdf",
"Initialising...", ""];
html,
body {
margin: 0 auto;
height: 100%;
}
pre {
padding: 0;
margin: 0;
}
.load {
margin: 0 auto;
min-height: 100%;
width: 100%;
background: black;
}
.term {
font-family: monospace;
color: #fff;
opacity: 0.8;
font-size: 2em;
overflow-y: auto;
overflow-x: hidden;
padding-top: 10px;
padding-left: 20px;
}
.term:after {
content: "_";
opacity: 1;
animation: cursor 1s infinite;
}
#keyframes cursor {
0% {
opacity: 0;
}
40% {
opacity: 0;
}
50% {
opacity: 1;
}
90% {
opacity: 1;
}
100% {
opacity: 0;
}
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/2.1.3/jquery.min.js"></script>
<div class="load">
<pre class="term">andrew#dev:~$ </pre>
</div>

Function not get called from dynamically created html code

I'am changing the html code from javascript and want to call same function from created "div"s. but it is not called.
As you can see 'html' which is formed after function invoke also has class="screen" but created 'div's doesn't support it.
var i;
var clear = 2;
$("#container").click(function() {
var clickid = $(this).attr('id');
var left = document.getElementById(clickid).offsetLeft;
var top = document.getElementById(clickid).offsetTop;
var height = document.getElementById(clickid).offsetHeight;
var width = document.getElementById(clickid).offsetWidth;
var x = document.getElementById(clickid).value;
orient = prompt("vertical or horizontal ?");
numdiv = prompt("How many divisions should be created ?");
var divsper = [];
var html = "";
for (i = 0; i < numdiv; i++) {
per = prompt("Percentage of " + (i + 1) + "th division ?");
divsper.push(per);
}
if (orient == "vertical") {
for (i = 0; i < numdiv; i++) {
l = Math.floor(left + ((i * divsper[i] * width) / 100));
w = Math.floor((divsper[i] * width) / 100);
html = html + "<div id=" + clickid + " class=\"screen\" style=\"float:left; top:" + (top) + "px; left:" + (l) + "px; height:" + (height - clear) + "px; width:" + (w - clear) + "px; border:1px solid black;\"></div>"
}
document.getElementById(clickid).outerHTML = html;
//document.getElementById(clickid).unwrap();
}
});
* {
padding: 0px;
margin: 0px;
}
body {}
#container {
background-color: pink;
top=0%;
left=0%;
height: 100vh;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div id="container" class="screen">
</div>
Replace '$("#container").click(function() {' this line with '$("html").on('click', '[id*=container]', function() {'.
It will work for you.
var i;
var clear = 2;
$("html").on('click', '[id*=container]', function() {
var clickid = $(this).attr('id');
var left = this.offsetLeft;
var top = this.offsetTop;
var height = this.offsetHeight;
var width = this.offsetWidth;
var x = this.value;
orient = prompt("vertical or horizontal ?");
numdiv = prompt("How many divisions should be created ?");
var divsper = [];
var html = "";
for (i = 0; i < numdiv; i++) {
per = prompt("Percentage of " + (i + 1) + "th division ?");
divsper.push(per);
}
if (orient == "vertical") {
for (i = 0; i < numdiv; i++) {
l = Math.floor(left + ((i * divsper[i] * width) / 100));
w = Math.floor((divsper[i] * width) / 100);
html = html + "<div id=" + clickid + (i + 1) + " class=\"screen\" style=\"float:left; top:" + (top) + "px; left:" + (l) + "px; height:" + (height - clear) + "px; width:" + (w - clear) + "px; border:1px solid black;\"></div>"
}
this.outerHTML = html;
//this.unwrap();
}
});
* {
padding: 0px;
margin: 0px;
}
body {}
#container {
background-color: pink;
top=0%;
left=0%;
height: 100vh;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div id="container" class="screen">
</div>
Try using $('#container').on('click') instead. Dynamically generated html event handling is slightly different.

Javascript If statement not acknowledged

Here is the code
setHighScore: function() {
var highScore = 0;
if (!window.snake || !window.fpsls || !window.fmlts) {
return;
}
if (++bot.tickCounter >= 20) {
bot.tickCounter = 0;
var currentScore = parseInt(Math.floor(150 * (window.fpsls[window.snake.sct] +
window.snake.fam / window.fmlts[window.snake.sct] - 1) - 50) / 10);
if (Number(currentScore) > Number(highScore)) {
highScore = currentScore;
window.localStorage.setItem('highScoreLoc', highScore);
console.log('Current Score: ' + currentScore);
}
}
},
onFrameUpdate: function() {
// Botstatus overlay
var generalStyle = '<span style = "opacity: 0.35";>';
window.fps_overlay.innerHTML = generalStyle + 'FPS: ' +
userInterface.framesPerSecond.getFPS() + '</span>';
if (window.position_overlay && window.playing) {
// Display Personal High Score
userInterface.setHighScore();
window.scoreHuD.innerHTML = generalStyle +
'Your High Score: ' + parseInt(Number(window.localStorage.getItem('highScoreLoc')));
// Display the X and Y of the snake
window.position_overlay.innerHTML = generalStyle +
'X: ' + (Math.round(window.snake.xx) || 0) +
' Y: ' + (Math.round(window.snake.yy) || 0) +
'</span>';
}
It's meant to check if the score is bigger than the high score then save the new high score (if its bigger) and after that print it on screen. But it isn't for some reason
line 10 is the if statement
the 2 lines above it are to find the current score and i know it outputs the current score because of line 13
Its Tampermonkey
and the actual script https://github.com/Classicanon/Slither.io-bot/blob/master/bot.user.js For (Slither.io)

Scale Background CSS with Slider

I am working with some CSS Backgrounds (http://css3pie.com/demos/gradient-patterns/) in an application and want to be able to scale the design with a slider. Here's a JSFiddle. I was able to scale X & Y separately on some like the Stripes and Picnic designs where I just had to play with background-size:50px 50px; like this:
//setup the variables based off the css which was set using dropdown
gridItems = $(document.activeElement).val().split("; ");
for (i = 0; i < gridItems.length -1; i++) {
gridSettings = gridItems[i].split(":");
if (gridSettings[0]=="background-size"){
gridSize = gridSettings[1].split(" ");
gridX = gridSize[0];
gridY = gridSize[1]
}
//on the action of the slide - update value
$('#gridXY-'+key).on("slide", function(slideEvt) {
gridXY = slideEvt.value;
$('.draggable-' + currentLayer).css("background-size", "calc("+ gridX +" * "+ gridXY +") calc("+ gridY +" * "+ gridXY +")");
});
Which can be set either numerically or using but when it gets to something like the Blue Print it has a lot more settings background-size:100px 100px, 100px 100px, 20px 20px, 20px 20px;
I am trying to do this right so that it can take a variable number of those, and can write something that could work, but the method I have in mind is really messy, hoping for some help scaling this that might be a little cleaner than what I would do.
I did find this:http://codepen.io/Erik/pen/JGnsB but he is using LESS to declare variables, if possible I would like to stay away from that.
UPDATE:
Here is a JSFiddle of it: http://jsfiddle.net/4L3d9qh2/
I added a function that should have let me update it, but for some reason the calc() function doesn't seem to be working to update the div style. After processing, it looks like this:
$('.draggable-0').css("background-size", calc(100px - 4) calc(100px - 4), calc(100px - 4) calc(100px - 4), calc(20px - 4) calc(20px - 4), calc(20px - 4) calc(20px - 4));
$.each(gridSizeArray, function( k, v ){
if (gridIncrement==1)
{
gridXY = "calc(" + v +" - " + value + ") ";
}else{
if(isOdd(gridIncrement)){
gridXY = gridXY + "calc(" + v +" - " + value + ") ";
}else{
gridXY = gridXY + "calc(" + v +" - " + value + "), ";
}
}
gridIncrement++
})
Here was the final code that works. Using .each() loop through and if it is even, add a comma, then remove the last comma at the end.
gridItems = $(document.activeElement).val().split("; ");
for (i = 0; i < gridItems.length -1; i++) {
gridSettings = gridItems[i].split(":");
if (gridSettings[0]=="background-size"){
gridSizeString = gridSettings[1].replace(/,/gi, '');
gridSizeArray = gridSizeString.split(" ");
}
$('[data-type="sliderLayer"][data-layer="'+currentLayer+'"][data-slide="'+currentSlide+'"]').css(gridSettings[0], gridSettings[1]);
}
$.each(gridSizeArray, function( k, v ){
if (gridIncrement==1)
{
gridXY = "calc(" + v +" + " + value + "px) ";
}else{
if(isOdd(gridIncrement)){
gridXY = gridXY + " calc(" + v +" + " + value + "px) ";
}else{
gridXY = gridXY + "calc(" + v +" + " + value + "px),";
}
}
gridIncrement++
})
if (isOdd(gridIncrement))
{
gridXY = gridXY.substring(0, gridXY.length - 1);
}

How to cancel first iteration of a function if function is reactivated

I have a function that takes about 10 seconds to complete and it breaks if reactivated before the first iteration is completed - It acts as a text-fader - JQuery is not an option I want to use pure JS
My function:
//Text fading effect
function fadeText() {
var hex1 = 153,
hex2 = 204,
hex3 = 51;
function innerFade() {
if (hex1 >= 30) {
hex1 -= 1;
document.getElementById('confirmation').style.color = "rgb(" + hex1 + "," + hex2 + "," + hex3 + ")";
}
if (hex2 >= 30) {
hex2 -= 1;
document.getElementById('confirmation').style.color = "rgb(" + hex1 + "," + hex2 + "," + hex3 + ")";
}
if (hex3 >= 30) {
hex3 -= 1;
document.getElementById('confirmation').style.color = "rgb(" + hex1 + "," + hex2 + "," + hex3 + ")";
}
setTimeout(innerFade, 20);
}
innerFade();
}
This is activated on button press, I want the first iteration to cancel or set the innerHTML of the div the text has been assigned to to innerHTML=""; if it is activated again before the animation is completed.
Big Edit:
//Set colour function
function setColor(elementName, r, g, b) {
document.getElementById(elementName).style.color = "rgb(" + r + "," + g + "," + b + ")";
}
//Text fading effect
var animationActive = false;
function fadeText() {
if (animationActive) return;
animationActive = true;
var hex1 = 153,
hex2 = 204,
hex3 = 51;
function innerFade() {
var rDone, gDone, bDone;
if (hex1 >= 30) {
hex1 -= 1;
setColor('confirmation', hex1, hex2, hex3);
} else {rDone = true;}
if (hex2 >= 30) {
hex2 -= 1;
setColor('confirmation', hex1, hex2, hex3);
} else {gDone = true;}
if (hex3 >= 30) {
hex3 -= 1;
setColor('confirmation', hex1, hex2, hex3);
} else {bDone = true;}
if (rDone && gDone && bDone) {
animationActive = false;
}
}
setTimeout(innerFade, 20);
}
You could disable the button to prevent calling the function again:
HTML:
<button onclick="fadeText(this)"> Fade text </button>
JavaScript:
function fadeText(btn) {
var elm = document.getElementById('confirmation'),
c = [153, 204, 51];
function loop() {
for (var i = 0; i < c.length; i++) {
if (c[i] >= 30) c[i] -= 1;
}
elm.style.color = 'rgb(' + c[0] + ',' + c[1] + ',' + c[2] + ')';
return c[0] < 30 && c[1] < 30 && c[2] < 30 ?
btn.disabled = false : setTimeout(loop, 20);
}
btn.disabled = true;
loop();
}
Live demo: http://jsfiddle.net/nKV7A/

Categories

Resources