Here is my code.
var i = 0;
var submenues = document.getElementsByClassName("submenu");
var click = 1;
function submenuvisible() {
if (click == 1) {
for (i; i < submenues.length; i++) {
submenues[i].style.display = "block";
}
click = 2;
return;
}
if (click == 2) {
for (i; i < submenues.length; i++) {
submenues[i].style.display = "none";
}
click = 1;
return;
}
}
Though when i onclick=submenuvisible() it works only 1 time. What am I doing wrong?
Your mistake is in your for loops.
Where you have: for (i; i < submenues.length; i++) {
You need to reset the variable i to 0 at the beginning of the for loops.
for (i = 0; i < submenues.length; i++) {
If you don't reset it, then i will remain at the same value it was after the first time you run your function. You could improve your code further by not making i a global variable, but overall, I hope this explains your issue.
Related
Ok this is my very first ever coding project. I'm self taught and thought creating a hangman game my 2 young kiddos could enjoy would be fun.
I have the game coded and it runs perfectly fine the first time through however, once I click on my reset button to restart the game, my lives start going down by 2 instead of one. After a third reset it goes down by three, and so on. Any console.log()s I put in to check run as many times as well.
I've spend hours racking my brain trying to figure it out and I've looked all over and I'm just not getting what's wrong. I thought about just saying screw it and resort to refreshing the page after every play through to avoid the problem but my brain wont let me do that.
Does anyone have any idea how to fix the problem? I know my code is probably not the most efficient and can definitely use to touch ups, but like I said, this is my first ever project and I know efficiency and skill will come with time and practice (like this). Below is the main chunk of my code.
function gameStart() {
// user writes in a word
pickedWord = prompt('pick a word').toUpperCase();
pickLetterHeading.innerText = 'Pick a Letter'
numLivesSec.hidden = false;
startBtn.disabled = true;
gameIsGoing = true;
resetBtn.disabled = false;
// enables buttons to press
for (let j = 0; j < alphabet.length; j++) {
document.getElementsByClassName('letterBtnClass')[j].disabled = false;
}
numLives = 7;
numLivesRemaining.innerText = numLives;
// calls the main game function
gameInProgress();
}
function reset() {
startBtn.disabled = false;
pickedWord = '';
gameIsGoing = false;
resetBtn.disabled = true;
pickLetterHeading.hidden = true;
numLivesSec.hidden = true;
while (guessedSec.firstChild) {
guessedSec.removeChild(guessedSec.firstChild);
}
for (let l = 0; l < alphabet.length; l++) {
document.getElementsByClassName('letterBtnClass')[l].disabled = true;
letters[l].classList.replace('correct', 'letterBtnClass');
letters[l].classList.replace('incorrect', 'letterBtnClass');
}
numLives = 7;
}
function gameInProgress() {
pickLetterHeading.hidden = false;
wordInProgress = '';
for (let i = 0; i < pickedWord.length; i++) {
let lettersToGuess = document.createElement('span');
lettersToGuess.innerText = '_';
guessedSec.appendChild(lettersToGuess);
wordInProgress += '_';
}
for (let btn = 0; btn < letters.length; btn++) {
letters[btn].addEventListener('click', function (e) {
letters[btn].disabled = true;
if (pickedWord.indexOf(letters[btn].innerText) == -1) {
console.log('letter not there!');
numLives -= 1;
numLivesRemaining.innerText = numLives;
console.log('TESTING!')
// checks if you have any tries left. If you have 0, then runs game over
if (numLives == 0) {
console.log('GAME OVER!')
gameIsGoing = false;
pickLetterHeading.innerText = 'You lose. Try again.'
for (let j = 0; j < alphabet.length; j++) {
document.getElementsByClassName('letterBtnClass')[j].disabled = true;
}
}
}
// checks if the letter picked matches anything in the chosen word
for (let x = 0; x < pickedWord.length; x++) {
if (letters[btn].innerText == pickedWord[x]) {
// adds class to chosen letter to show you guess correctly
letters[btn].classList.add('correct');
document.getElementsByTagName('span')[x].innerText = pickedWord[x];
wordInProgress[x] = pickedWord[x];
// if picked letter matches something in the chosen word, changes the "_" to the correct letter to show user progress
String.prototype.replaceAt = function (index, char) {
let a = this.split("");
a[index] = char;
return a.join("");
}
wordInProgress = wordInProgress.replaceAt(x, pickedWord[x]);
// when the word is complete. will show you win
if (wordInProgress == pickedWord) {
console.log("WINNER WINNER CHICKEN DINNER!");
pickLetterHeading.innerText = 'YOU WIN!'
for (let j = 0; j < alphabet.length; j++) {
document.getElementsByClassName('letterBtnClass')[j].disabled = true;
}
}
} else {
// since you chose incorrectly it adds a class to the button to show a bad choice
letters[btn].classList.add('incorrect');
}
}
})
}
}
I wanted to make a specific form show and the other forms disappear when I click on one of four dropdown buttons. When I tested the code, no from is showing when I clicked on a button.
Here is my javascript code:
function showClass(className)
{
var allItems = document.getElementsByClassName('change-form');
for (var i = 0; i < allItems.length; i++)
{
allItems[i].style.display = "none";
}
var formItems = document.getElementsByClassName(className);
for (var i = 0; i < formItems.length; i++)
{
formItems[i].style.display = "block";
}
}
It shows the form if I remove the top for loop.
Edit: Sorry guys I made a typo
Your code is going in and hiding all the items and then showing them right away. What you want to do is split the hide and show into different functions to trigger them at different times.
function showClass(className)
{
var formItems = document.getElementsByClassName(className);
for (var i = 0; i < formItems.length; i++)
{
formItems[i].style.display = "block";
}
}
function hideClass(className){
var allItems = document.getElementsByClassName(className);
for (var i = 0; i < allItems.length; i++)
{
allItems[i].style.display = "none";
}
}
If you want to be able to swap them with one function you could use this:
function swapHide(className){
var firstItem = document.getElementsByClassName(className)[0];
var isDisplayed = firstItem.style.display == "block"
if(isDisplayed){
hideClass(className);
}else{
showClass(className)
}
}
function albumCoverDisplay() {
var i = 0;
for (i = 0; i < albumCover.length; i++) {
albumCover[i].addEventListener("click", function() {
for (var i = 0; i < albumCover.length; i++) {
albumInfo[i].style.display = "none";
}
albumInfo[i].style.display = "block";
});
}
}
Looks like you want to be able to hide other albumCover elements on clicking one of them.
There are a couple of mistakes
Your inner for-loop re-localize the scope of i, use different variable
i's value (assuming another variable is used in inner for-loop) will not remain same when the click will happen.
Make it
function albumCoverDisplay()
{
for (let i = 0; i < albumCover.length; i++) //use let instead of var
{
albumCover[i].addEventListener("click", function() {
for (var j = 0; j < albumCover.length; j++)
{
albumInfo[j].style.display = "none";
}
albumInfo[i].style.display = "block";
});
}
}
I'm trying to create a tabbed interface in Javascript which will allow a user to click on a button atop each interface in order to make the div under it become active while the other 'tabs'/divs recede to the background. I'm not quite sure I got that out right so attached is a screenshot of what I'm trying to make:
My code attaches one button -- beside the first div-- instead of all three and returns an error that says nodeChildren[j].getAttribute("data-tabname") is not a function although as far as I know, it seems it is.
I'll post my JavaScript code then add a link to fiddle where everything is.
function asTabs(node) {
var button = document.createElement("BUTTON");
var tempArray = [];
var nodeChildren = Array.prototype.slice.call(node.childNodes);
nodeChildren.filter(function(){
for (var i = 0; i < nodeChildren.length; i++) {
if (nodeChildren[i].nodeType === 1) {
tempArray += nodeChildren[i];
return tempArray;
}
}
});
nodeChildren.forEach(function (){
for (var j = 0; j < nodeChildren.length; j++) {
node.insertBefore(button, nodeChildren[j]);
var buttons = document.getElementsByTagName("button");
for (var k = 0; k < buttons.length; k++) {
buttons[k].innerHTML = nodeChildren[j].getAttribute("data-tabname").textContent;
}
}
});
var hide = nodeChildren.slice(1);
for (var l = 0; l < hide.length; l++) {
hide[l].className = "hide";
}
buttons[k].addEventListener("click", function (){
if (nodeChildren[j].className = "") {
nodeChildren[j].className = "hide";
}
else nodeChildren[j].className = "";
});
}
asTabs(document.querySelector("#wrapper"));
Then here's my fiddle containing comments explaining what is being tried to achieve on each line
https://jsfiddle.net/nmeri17/nmswdota/
So, I'm new to javascript.
My code is the following, it is based on a xaml file with a canvas and a couple of borders in it:
var defaultPage = null;
var aantalKliks;
var correcteBorders;
var incorrecteBorders;
var geenAntwBorders;
function onLoaded() {
defaultPage = document.getElementById('DefaultPage');
alert('In onloaded van Default.xaml.');
aantalKliks = 0;
aantalBorderKliks = 0;
correcteBorders = new Array();
for (var i = 0; i < 3; i++) {
correcteBorders[i] = defaultPage.content.findName('CorrecteBorder' + i);
}
incorrecteBorders = new Array();
for (var i = 0; i < 3; i++) {
incorrecteBorders[i] = defaultPage.content.findName('IncorrecteBorder' + i);
}
geenAntwBorders = new Array();
for (var i = 0; i < 3; i++) {
geenAntwBorders[i] = defaultPage.content.findName('GeenAntwBorder' + i);
}
}
function OnCanvasClicked() {
if (aantalKliks == 2) {
aantalKliks = 0;
}
if (aantalKliks == 0) {
for (var i = 0; i < correcteBorders.length; i++) {
correcteBorders[i].Visibility = 'Visible';
}
for (var i = 0; i < incorrecteBorders.length; i++) {
incorrecteBorders[i].Visibility = 'Visible';
}
for (var i = 0; i < geenAntwBorders.length; i++) {
geenAntwBorders[i].Visibility = 'Visible';
}
} else if (aantalKliks == 1) {
for (var i = 0; i < correcteBorders.length; i++) {
correcteBorders[i].Visibility = 'Collapsed';
}
for (var i = 0; i < incorrecteBorders.length; i++) {
incorrecteBorders[i].Visibility = 'Collapsed';
}
for (var i = 0; i < geenAntwBorders.length; i++) {
geenAntwBorders[i].Visibility = 'Collapsed';
}
aantalKliks++;
}
function borderClicked(sender) {
for (var i = 0; i < correcteBorders.length; i++) {
correcteBorders[i].Visibility = 'Collapsed';
}
for (var i = 0; i < incorrecteBorders.length; i++) {
incorrecteBorders[i].Visibility = 'Collapsed';
}
for (var i = 0; i < geenAntwBorders.length; i++) {
geenAntwBorders[i].Visibility = 'Collapsed';
}
sender['Visibility'] = 'Visible';
}
The function OnCanvasClicked is triggered when I click anywhere in the canvas and makes all borders disappear/reappear. The function borderClicked is triggered when I click a specific border. The function borderClicked does trigger when I click a specific border, however the OnCanvasClicked function also gets executed right after, which causes an unwanted result.I think I need some way to ignore the OnCanvasClicked function if I click on a border, I did google this but to be honest I didn't really understand what they meant in most of the solutions, so I was hoping someone could explain it to me in a simple way what I need to do (and what I'm doing).
You need to set event.stopPropagation() when borderClicked function is fire
Try this which will prevent Javascript to further execution
event.preventDefault()
#Harshit is correct
You need to set event.stopPropagation() when borderClicked function is fire
I just wanted to add this link/sample which I found very usefull to understand bubbling
http://samples.msdn.microsoft.com/workshop/samples/author/dhtml/refs/ie9_event_phases.htm