How to stop Looping - Javascript 100% - javascript

I was hoping someone could help me figure this out. I will list the code, and it works just fine, as it is an animation. However, when I check it out in the console it wont stop looping even though it hit the last item in the array. The image itself stops, but if you view the console it shows it looping.
Here is the code, have at it!
var position_X = ["0px", "-525px", "-1050px", "-1575px", "-2100px", "-2625px", "-3150px", "-3675px", "-4200px", "-4725px", "-5250px", "-5775px", "-6300px", "-6825px", "-7350px"];
var _lock = document.getElementById('hi');
// console.log(_lock);
_lock.style.border = "1px solid black";
_lock.style.backgroundImage = "url('http://handbagmanufacturing.com/wp-content/CDN/images/lock.png')";
function lockAnimation(){
setInterval(function(){
var _count = position_X.length;
for(var i = 0; i < _count; i++){
if(i == _count) break;
_lock.style.backgroundPosition = position_X[i] + " 263px";
console.log("Here is the background positions : " + i + ") " + position_X[i]);
}
}
, 100);
}
#hi {
width: 525px;
height: 263px;
background-position-x: "-7875px"
}
<button onclick="lockAnimation()">Click Me I'm Irish!</button>
<div id="hi"></div>

Change setInterval to setTimeout. This will run the function only once instead of running it every 100 ms.
var position_X = ["0px", "-525px", "-1050px", "-1575px", "-2100px", "-2625px", "-3150px", "-3675px", "-4200px", "-4725px", "-5250px", "-5775px", "-6300px", "-6825px", "-7350px"];
var _lock = document.getElementById('hi');
// console.log(_lock);
_lock.style.border = "1px solid black";
_lock.style.backgroundImage = "url('http://handbagmanufacturing.com/wp-content/CDN/images/lock.png')";
function lockAnimation(){
setTimeout(function(){
var _count = position_X.length;
for(var i = 0; i < _count; i++){
if(i == _count) break;
_lock.style.backgroundPosition = position_X[i] + " 263px";
console.log("Here is the background positions : " + i + ") " + position_X[i]);
}
}
, 100);
}
#hi {
width: 525px;
height: 263px;
background-position-x: "-7875px"
}
<button onclick="lockAnimation()">Click Me I'm Irish!</button>
<div id="hi"></div>

Related

function that targets DOM to display game results not responding despite calling function and there are no console errors either

I am trying to understand why the function endResult() does not work when either winning or losing a game of hangman.
I have called the function at the bottom of the code and there are no errors in the console.
But when the game finishes (either guessing the word completely within 5 guesses or running out of guesses), there is no action taken from this function.
This is my first intermediate challenge and I still clearly have a lot to learn but any help would be extremely welcome.
Thanks
//global variables.
//counter to display how many tries you have left at guessing correct characters.
var triesLeft = 5;
//dom targets.
var guessCount = document.querySelector("#guesses, p"); //display how many tries you have left in dom target.
var resetButton = document.querySelector(".button"); // reset buton
var displayWord = document.getElementById("puzzle") //dom target to show random word
//arrays
var words = ["hello world", "happy birthday", "you got talent", "china town", "leap frog",
"true lies", "artificial inteligence", "knoledge is power", "monday blues", "autonomous vehicles"];
var wrongGuess = [];
//pick a word randomly.
var randomiseWord = words[Math.floor(Math.random() * words.length)];
//hide all characters within [a-z] and replace with *.
var randomiseWordHide = randomiseWord.replace(/[a-z]/gi, '*');
function displayGame() {
//insert each character of the random word into a span tag hidden as *.
for (var i = 0; i < randomiseWord.length; i++) {
var spanTag = document.createElement("span");
displayWord.appendChild(spanTag);
spanTag.textContent = randomiseWordHide[i];
}
};
function makeAGuess(event) {
//if correct guess, reveal characters,
for (var j = 0; j < randomiseWord.length; j++) {
if (randomiseWord[j] === event.key) {
document.querySelectorAll("span")[j].textContent = event.key;
//else reduce tries left by 1.
} else if (!randomiseWord.includes(event.key)) {
guessCount.textContent = "Guesses Left:" + " " + (triesLeft - wrongGuess.length);
}
}
//if incorrect guess, push to array to keep count. keep this condition out of the loop.
if (!randomiseWord.includes(event.key)) {
wrongGuess.push(event.key);
}
};
function endResult() {
//if word is guessed correctly before running out of guesses.
for (var k=0; k<randomiseWord; k++) {
if (triesLeft >0 && !document.querySelectorAll("span")[j].includes("*")) {
document.querySelector("#guesses, p").textContent = "Well done, you guessed the word with" + triesLeft + " tries left.";
//if all guesses are used and word not complete.
} else if (triesLeft === 0) {
document.querySelector("#guesses, p").textContent = "Nice try, the word was" + '"' + randomiseWord + '".';
}
};
//create a reload button that displays a new random word when clicked.
function reloadScreen() {
reload = location.reload();
}
//listener for keydown
document.addEventListener("keydown", makeAGuess); // can also pass function from here.
//listener for reload button.
resetButton.addEventListener("click", reloadScreen, false);
//call functions.
displayGame();
endResult();
The function endResult() isn't called when the guess was correct or if there are no tries left. You just call the function once at script load. Therefor you should call it in the function makeAGuess():
function makeAGuess(event) {
//if correct guess, reveal characters,
for (var j = 0; j < randomiseWord.length; j++) {
if (randomiseWord[j] === event.key) {
document.querySelectorAll("span")[j].textContent = event.key;
//else reduce tries left by 1.
} else if (!randomiseWord.includes(event.key)) {
guessCount.textContent = "Guesses Left:" + " " + (triesLeft - wrongGuess.length);
}
}
//if incorrect guess, push to array to keep count. keep this condition out of the loop.
if (!randomiseWord.includes(event.key)) {
wrongGuess.push(event.key);
}
endResult();
};
Furthermore there are two issues in endResult():
triesLeft never gets updated an remains 5 -> use wrongGuess.length instead
!document.querySelectorAll("span")[j].includes("*") isn't valid - you have to loop over all span tags and check the condition separately:
function endResult() {
//if word is guessed correctly before running out of guesses.
const letters = document.querySelectorAll("span");
let solved = false;
for (let m = 0; m < letters.length; m++) {
if (letters[m].textContent == "*") {
solved = false;
break;
}
else {
solved = true;
}
}
if (wrongGuess.length < 5 && solved) {
document.querySelector("#guesses, p").textContent = "Well done, you guessed the word with" + (triesLeft - wrongGuess.length) + " tries left.";
//if all guesses are used and word not complete.
} else if (wrongGuess.length >= 5) {
document.querySelector("#guesses, p").textContent = "Nice try, the word was" + '"' + randomiseWord + '".';
}
};
Working example:
//global variables.
//counter to display how many tries you have left at guessing correct characters.
var triesLeft = 5;
//dom targets.
var guessCount = document.querySelector("#guesses, p"); //display how many tries you have left in dom target.
var resetButton = document.querySelector(".button"); // reset buton
var displayWord = document.getElementById("puzzle") //dom target to show random word
//arrays
var words = ["hello world", "happy birthday", "you got talent", "china town", "leap frog",
"true lies", "artificial inteligence", "knoledge is power", "monday blues", "autonomous vehicles"
];
var wrongGuess = [];
//pick a word randomly.
var randomiseWord = words[Math.floor(Math.random() * words.length)];
//hide all characters within [a-z] and replace with *.
var randomiseWordHide = randomiseWord.replace(/[a-z]/gi, '*');
function displayGame() {
//insert each character of the random word into a span tag hidden as *.
for (var i = 0; i < randomiseWord.length; i++) {
var spanTag = document.createElement("span");
displayWord.appendChild(spanTag);
spanTag.textContent = randomiseWordHide[i];
}
};
function makeAGuess(event) {
//if correct guess, reveal characters,
for (var j = 0; j < randomiseWord.length; j++) {
if (randomiseWord[j] === event.key) {
document.querySelectorAll("span")[j].textContent = event.key;
//else reduce tries left by 1.
} else if (!randomiseWord.includes(event.key)) {
guessCount.textContent = "Guesses Left:" + " " + (triesLeft - wrongGuess.length - 1);
}
}
//if incorrect guess, push to array to keep count. keep this condition out of the loop.
if (!randomiseWord.includes(event.key)) {
wrongGuess.push(event.key);
}
endResult();
};
function endResult() {
//if word is guessed correctly before running out of guesses.
const letters = document.querySelectorAll("span");
let solved = false;
for (let m = 0; m < letters.length; m++) {
if (letters[m].textContent == "*") {
solved = false;
break;
} else {
solved = true;
}
}
if (wrongGuess.length < 5 && solved) {
document.querySelector("#guesses, p").textContent = "Well done, you guessed the word with" + (triesLeft - wrongGuess.length) + " tries left.";
//if all guesses are used and word not complete.
} else if (wrongGuess.length >= 5) {
document.querySelector("#guesses, p").textContent = "Nice try, the word was" + '"' + randomiseWord + '".';
}
};
//create a reload button that displays a new random word when clicked.
function reloadScreen() {
reload = location.reload();
}
//listener for keydown
document.addEventListener("keydown", makeAGuess);
//listener for reload button.
resetButton.addEventListener("click", reloadScreen, false);
//call functions.
displayGame();
* {
box-sizing: border-box;
margin: 0;
padding: 0;
}
html {
font-size: 62.5%;
}
body {
background: #2B292E;
color: #fafafa;
font-family: Helvetica, Arial, sans-serif;
font-size: 1.6rem;
display: flex;
align-items: center;
justify-content: center;
min-height: 100vh;
}
span {
border-bottom: 1px solid #534f59;
display: inline-block;
font-size: 2rem;
height: 2.4rem;
line-height: 2.4rem;
margin: 0 .1rem;
text-align: center;
text-transform: uppercase;
width: 2.4rem;
}
p {
font-weight: 300;
margin-bottom: .8rem;
}
.puzzle {
display: flex;
margin-bottom: 4.8rem;
}
.button {
background: #7044a0;
border: none;
border-bottom: 2px solid #603a88;
cursor: pointer;
color: white;
font-size: 1.4rem;
font-weight: 300;
padding: .8rem;
transition: background .3s ease, color .3s ease;
}
.button:hover {
background: #5F3A87;
}
<div>
<div id="puzzle" class="puzzle"></div>
<p id="guesses"></p>
<button id="reset" class="button">Reset</button>
</div>

using jQuery to append div's and each div has a different ID

So I'm trying to to use jQuery to append a div which will generate a card using the assigned class. The problem is I need to create a different ID each time so I can put random number on the card. I'm sure there's an easier way to do this. So i'm posing two questions. how to make the code where it put the random number on the card go endlessly. and how to append divs with unique ID's. Sorry if my code isn't the best. It's my first project.
<!DOCTYPE html>
<html>
<head>
<script src="https://code.jquery.com/jquery-1.11.2.min.js"></script>
<title></title>
<style>
.cardLook {
border: 1px solid black;
width: 120px;
height: 220px;
border-radius: 5px;
float: left;
margin: 20px;
padding: 5px;
background-color: #fff;
}
#card1,#card2,#card3,#card4,#card5 {
transform:rotate(180deg);
}
#cardTable {
background-color: green;
height: 270px
}
.reset {
clear: both;
}
</style>
<script src="//code.jquery.com/jquery-1.12.0.min.js"></script>
</head>
<body>
<button id="deal">Deal</button>
<button id="hit">hit</button>
<button id="stand">Stand</button>
<button id="hi">hi</button>
<div id="number"></div>
<div id="arrayOutput"></div>
<div id="someId"></div>
<div id="out2"></div>
<div id="cardTable">
</div>
<div class="reset"></div>
<script>
var what;
//Services helper functon
document.getElementById('deal').onclick = function deal() {
var score1 = Math.floor(Math.random() *10 + 1);
var score2 = Math.floor(Math.random() *10 + 1);
var firstCard = score1;
var secondCard = score2;
//myNumberArray.push(firstCard, score2);
//card1.innerHTML = myNumberArray[0];
//card2.innerHTML = myNumberArray[1];
$("#deal").click(function(){
$("#cardTable").append("<div class='cardLook' id='card1'></div>");
});
console.log(score2, score1)
}
var myNumberArray = [];
$("#hit").click(function(){
$("#cardTable").append("<div class='cardLook' id="uniqueIdNumberOne"></div>");
if (myNumberArray > 1) {
#cardTable
}
var card = Math.floor(Math.random() * 10) + 1;
document.getElementById('number').innerHTML=card;
myNumberArray.push(card);
var number = myNumberArray.value;
var arrayOutput = document.getElementById('number');
var someId = document.getElementById('someId');
someId.innerHTML = myNumberArray;
card1.innerHTML = myNumberArray[0];
card2.innerHTML = myNumberArray[1];
card3.innerHTML = myNumberArray[2];
card4.innerHTML = myNumberArray[3];
card5.innerHTML = myNumberArray[4];
// console.log("myNumberArray: ", myNumberArray);
what = calcTotal(myNumberArray);
showMe(calcTotal(myNumberArray));
});
//var output = myNumberArray = calcTotal(list);
function calcTotal(myNumberArray) {
var total = 0;
for(var i = 0; i < myNumberArray.length; i++){
total += myNumberArray[i];
}
return total;
}
//document.getElementById('out2').innerHTML = out2;
console.log("myNumberArray: ", myNumberArray);
function showMe(VAL) {
var parent = document.getElementById('out2');
parent.innerHTML = VAL;
if (calcTotal(myNumberArray) > 21) {
alert('you lose');
}
};
document.getElementById('stand').onclick = function stand() {
var compterDeal1 = Math.floor(Math.random() *10 + 1);
var computerCards = compterDeal1;
console.log(computerCards);
computerArray.push(computerCards);
if (computerCards < 21) {
stand();
}
}
var computerArray = [];
</script>
</body>
</html>
Use an unique class with all of then, and call then by class
Add a global integer:
var cardNumber = 0;
A function to generate an id:
function newCardId() {
cardNumber ++;
return 'uniqueCardId' + cardNumber.toString();
}
And use:
var newId = newCardId();
$("#cardTable").append("<div class=\"cardLook\" id=\"" + newId + "\"></div>");
Finally to access your new div:
$('#' + newId).
Note: Escape quotes within a string using backslash!

JavaScript countdown with css circles

I have a countdown I am trying to have a visual display with css circles of the count down. But I cant figure out what to do to take away one circle at a time. My code duplicates the number of circles each loop. I know why, but what can I now do to get it to take one away each time?
JS Fiddle: http://jsfiddle.net/L0o9jmw9/
JS:
var sec = 5
function setClock() {
var totalSec = sec--;
var s = parseInt(totalSec % 60, 10);
var result = s + " seconds to go!";
document.getElementById('timeRemaining').innerHTML = result;
if(totalSec === 0){
document.getElementById('timeRemaining').innerHTML = 'time out';
}else{
for(var i = 0; i < s; i++){
//console.log(i);
$('.cont-s').prepend('<div class="cir-s"></div>');
}
setTimeout(setClock, 1000);
}
}
setClock();
HTML:
<div id="timeRemaining"></div>
<div class="cont-s"></div>
CSS:
.cir-s{
width: 20px;
height: 20px;
background: #802A2A;
-moz-border-radius: 50px;
-webkit-border-radius: 50px;
border-radius: 50px;
float:left;
}
Simply empty the HTML before each iteration:
function setClock() {
$('.cont-s').empty(); // empty the circles div
var totalSec = sec--;
var s = parseInt(totalSec % 60, 10);
var result = s + " seconds to go!";
document.getElementById('timeRemaining').innerHTML = result;
if(totalSec === 0){
document.getElementById('timeRemaining').innerHTML = 'time out';
} else {
for(var i = 0; i < s; i++){
$('.cont-s').prepend('<div class="cir-s"></div>');
}
setTimeout(setClock, 1000);
}
}

Create infinite loop with moving divs using javascript or jQuery

I need to simulate a band that moves from left to right continuously, carrying 15 divs on it and moving them in a circle, like a carousel. When they reach the right margin to appear from the left.
I have the code that works for 1 div(more or less), but Im having troubles making the loop that includes all 15 divs.
What am I missing?
Here's what I have so far:
HTML
<body>
<div id="fooObject0">1</div>
<div id="fooObject1">2</div>
....
<div id="fooObject13">14</div>
<div id="fooObject14">15</div>
</body>
CSS
body {
font:76% normal verdana,arial,tahoma;
width:600px;
height:600px;
position:relative;
margin:0 auto;
border:1px solid;
}
div {
position:absolute;
left:0px;
top:8em;
width:55px;
height:70px;
line-height:3em;
background:#99ccff;
border:1px solid #003366;
white-space:nowrap;
padding:0.5em;
}
javascript
var foo = null; // object
function doMove(id) {
foo = document.getElementById(id);
foo.style.left = parseInt(foo.style.left)+1+'px';
setTimeout(doMove(id),20); // call doMove in 20msec
if(foo.style.left == "600px") {
foo.style.left = 0;
}
}
function init() {
for(i=0;i<15;i++){
var foo = document.getElementById('fooObject' + i); // get the "foo" object
foo.style.left = -i*55+'px'; // set its initial position to 0px
doMove('fooObject' + i); // start animating
console.log('fooObject' + i);
}
}
window.onload = init;
Thank you in advance!
It call an invalid function setTimeout(doMove(id), 20);.
doMove(id) return undefined, or you use "shared var" (Orientad Object) or doMove need return other function.
Note: var foo = null; // object this variable causes conflict when using setTimeout or setInterval
Try this (read my comments in code):
function doMove(id) {
return function() {
var foo = document.getElementById(id);//Global variable causes conflict when using `setTimeout` or `setInterval`
foo.style.left = parseInt(foo.style.left)+1+'px';
setTimeout(doMove(id),20); //setTimeout need an valid function
if(foo.style.left == "600px") {
foo.style.left = 0;
}
}
}
function init() {
for(i=0;i<15;i++){
var foo = document.getElementById('fooObject' + i);
foo.style.left = -i*55+'px';
doMove('fooObject' + i)(); //doMove need "()", because not run "direct"
console.log('fooObject' + i);
}
}
I modified the code for effect "carousel" and fix the problem with "left" (In 1 to 5 div):
function carrousel() {
var numberOfItems = 15; //Change this if needed
var delay = 1; //Change delay time if needed
var limitArea = 599; //Size limit your carousel area (600px, used 599 for limit with `>`)
var sizeObject = 58; //Width size of objects
//Don't change
var index = 0; //Current index
var allItems = []; //Indexed objects
//Get and index all objects
for(index = 0; index < numberOfItems; index++){//user var
allItems[index] = document.getElementById("fooObject" + index);
}
//Convert position left for int and detect "NaN"
var getPosition = function(pos) {
pos = parseInt(pos);
if (isNaN(pos)) {
return parseInt(-(index * sizeObject));
} else {
return parseInt(pos + 1);
}
};
var doMoveAll = function() {
var foo, post;
for(index = 0; index < numberOfItems; index++){//user var
foo = allItems[index];//Current object
pos = getPosition(foo.style.left);//Get position
//Detect if object are in out area
if(pos > limitArea) {
var beforeItem;
//Get before object for effect carousel
switch(index + 1) {
case 1:
beforeItem = "fooObject" + (numberOfItems - 1);
break;
default:
beforeItem = "fooObject" + (index - 1);
}
//Get position again, but used before object
pos = (
getPosition(document.getElementById(beforeItem).style.left) - sizeObject
);
foo.style.left = pos + "px";
} else {
foo.style.left = pos + "px";
}
}
//Timeout delay
window.setTimeout(doMoveAll, delay);
};
doMoveAll();//Init
};
window.onload = carrousel;

Javascript positioning element

I try to create input controls dynamically , works fine apart from the positioning, for some reason I cant put the elements under the previous one, because I'm unable to get "style.top" property.
What I'm doing wrong and how can I fix it?
the HTML code:
<div id='div_attach' class='scrollbox' style='top: 380px; height: 65px; left: 100px; right: 135px;'>
<a href='goes_nowhere' style='top: 5px; left: 5px;'>click_me_if_you_dare</a>
</div>
<button type='button' style='top: 380px; width: 120px; right: 10px; height: 20px;' onclick='createFileInput("div_attach");'>new input</button>
the JS code:
function createFileInput(parentID) {
var atop, index;
var parent = document.getElementById(parentID);
var control = document.createElement('input');
control.setAttribute('type', 'file');
elements = parent.getElementsByTagName('*');
// debug only ...
for (index = 0; index < elements.length; ++index) {
alert(elements[index].style.top);
alert(elements[index].style.height);
};
if (elements.length > 0)
atop = elements[elements.length - 1].style.top + elements[elements.length - 1].style.height + 5;
else
atop = 5;
control.setAttribute('name', 'FILE_' + elements.length);
control.className = 'flat';
control.style.left = 5 + 'px';
control.style.top = atop + 5 + 'px';
// control.style.top = (elements.length * 30) + 5 + 'px';
control.style.width = 500 + 'px';
parent.appendChild(control);
control.focus();
}
The code:
atop = elements[elements.length - 1].style.top + elements[elements.length - 1].style.height + 5;
will return something like "5px5" because it's a string to which you append 5.
Replace it with
atop = parseInt(elements[elements.length - 1].style.top, 10) + parseInt(elements[elements.length - 1].style.height, 10) + 5;
Make sure those element have a top and height value, or else parseInt() will return NaN.
edit: In the example, the <a> has no height.

Categories