Module - IIFE isn't automatically called - javascript

I created a module but it is not automatically rendered in my page, I have to manually call Board.renderBoard() in the console for the Board to appear. What am I doing wrong ?
here's the entire code:
const Board = (() => {
const board = document.querySelector('.board');
const createTiles = () => {
tile = document.createElement('div');
tile.classList.add('tile');
return tile;
};
const renderBoard = () => {
for (let i = 0; i < 9; i++) {
createTiles();
board.appendChild(createTiles());
}
};
return {
renderBoard
};
})();

I created a module but it is not automatically rendered in my page, I have to manually call Board.renderBoard() in the console for the Board to appear.
JS doesn't just call function unless you tell it to call these functions.
Your module simply defines an object Board with a method renderboard. There's nothing that tells JS to call this method.
You could add the call right after declaring the module.
const Board = (() => {
...
})();
Board.renderBoard();
But if all you want is that the code initially builds the board you can do:
(() => {
const board = document.querySelector('.board');
const createTiles = () => {
const tile = document.createElement('div'); // please declare your variables
tile.classList.add('tile');
return tile;
};
for (let i = 0; i < 9; i++) {
createTiles(); // what is this line for?
board.appendChild(createTiles());
}
})();
or
(() => {
const board = document.querySelector('.board');
for (let i = 0; i < 9; i++) {
const tile = document.createElement('div');
tile.classList.add('tile');
board.appendChild(tile);
}
})();
or maybe even
document.querySelector('.board').innerHTML = '<div class="tile"></div>'.repeat(9);

Related

How to break loop in javascript?

const arrow = document.querySelector("#arrow");
const callAllPie = document.querySelector(".allPie");
eventList();
function eventList(e) {
arrow.addEventListener("click", showSkills);
}
function showSkills() {
let element = callAllPie;
for (let i = 0, n = 4; i < n; i++) {
const pie = document.createElement("div");
pie.classList.add("pie1");
callAllPie.appendChild(pie);
const rightDiv = document.createElement("div");
rightDiv.classList.add("slice-right1");
const leftDiv = document.createElement("div");
leftDiv.classList.add("slice-left1");
const percentDiv = document.createElement("div");
percentDiv.classList.add("percent1");
const numberDiv = document.createElement("div");
numberDiv.classList.add("number1");
numberDiv.innerHTML = "%99";
const nameDiv = document.createElement("div");
nameDiv.classList.add("name1");
nameDiv.innerHTML = "HTML";
pie.appendChild(rightDiv);
pie.appendChild(leftDiv);
pie.appendChild(percentDiv);
percentDiv.appendChild(numberDiv);
percentDiv.appendChild(nameDiv);
callAllPie.appendChild(pie);
}
}
I want to break the loop after the click event runs once, how do I do it? When run the click event, added pie div to my page but when I clicked again, it being created again.
You could simply remove the click listener at the beginning of your showSkills() function so no further clicks trigger an action:
function showSkills() {
arrow.removeEventListener('click', showSkills);
let element = callAllPie;
....
}
Or as Teemu points out, a much cleaner approach is to set once: true in the options parameter:
arrow.addEventListener("click", showSkills, {once: true});
You can make a boolean isLoopRunning and use it to see if the loop Is already running
const arrow = document.querySelector("#arrow");
const callAllPie = document.querySelector(".allPie");
eventList();
let isLoopRunning = false;
function eventList(e) {
arrow.addEventListener("click", showSkills);
}
function showSkills() {
let element = callAllPie;
isLoopRunning = !isLoopRunning;
for (let i = 0, n = 4; i < n; i++) {
if (isLoopRunning) {
// your code here
} else {
break;
}
}
}
The break statement terminates the current loop.
if condition satisfies requirement just use break keyword inside loop
for(let i=0; i<10; i++){
if(i==6){
console.log(i)
break;
}
console.log("hi")
}
"hi" will not print after 6 times
When using a status variable outside the function you will have the option to reset the status elsewhere in the code and have the loop run once again.
var showSkills = true;
// Runs once upon user click
function showSkills() {
if (showSkills) {
for {
/* Do the loop */
};
showSkills = false;
};
}
// If you need to run it again upon user click.
// E.g. attach it to some 'reset' button.
function reset() {
showSkills = true;
}

I converted this forEach code to for loop and the code is not working

Clicking the red exit button removes the player from the forEach code, but not for loop.
You click the blue button, next you click the red exit button to remove the player.
How would I get the for loop code to work the same as the forEach code?
This code is working.
https://jsfiddle.net/n1t3kjdw/
function removePlayerHandler(evt) {
const el = evt.target;
const container = el.closest(".container");
const wrapper = container.querySelectorAll(".wrap");
wrapper.forEach(function(wrapper) {
if (wrapper.player) {
return removePlayer(wrapper);
}
});
}
What did I do wrong here? https://jsfiddle.net/rbwsL8hf/
Why is this code not working, what needs to be fixed?
function removePlayerHandler(evt) {
const el = evt.target;
const container = el.closest(".container");
const wrappers = container.querySelectorAll(".wrap"); {
for (let i = 0; i < wrappers[i].length; i++) {
if (wrappers[i].player) {
return removePlayer(wrappers[i]);
}
}
}
}
In your changed code you have made the iteration condition check for wrappers[i].length instead of what I believe was intended wrappers.length. Otherwise, you are for each iteration checking if i is smaller than the i-th wrapper's length which may or may not be defined.
function removePlayerHandler(evt) {
const el = evt.target;
const container = el.closest(".container");
const wrappers = container.querySelectorAll(".wrap"); {
for (let i = 0; i < wrappers[i].length; i++) { // HERE
if (wrappers[i].player) {
return removePlayer(wrappers[i]);
}
}
}
}
Complementing #Salim answer, there is also an extra bracket in your code, try this:
function removePlayerHandler(evt) {
const el = evt.target;
const container = el.closest(".container");
const wrappers = container.querySelectorAll(".wrap");
for (let i = 0; i < wrappers.length; i++) {
if (wrappers[i].player) {
return removePlayer(wrappers[i]);
}
}
}

How to run a line based on user input in Javascript?

I want to run v-network-graph when the user presses enter, basically, I wrote a function that will create nodes and edges when it runs, once that function runs I want to run the line <v-network-graph #keypress.enter="gr" :nodes='nodes' :edges='edges'/>
I tried writing everything inside the function but it didn't work.
I am new to javascript and Vue, so I'll be grateful for any suggestions.
My template looks like this:
<template>
<div>
<v-network-graph #keypress.enter="gr" :nodes='nodes' :edges='edges'/>
</div>
</template>
My function looks like this:
methods: {
gr() {
const nodes={}
const edges={}
// const { prac } = toRefs(props)
// const n = reactive( prac.value )
// const n= prac.length
const n = this.prac
console.log(n.Organizations)
for (let i = 0; i < n.length; i++) {
nodes[`${n[i].Organizations}`] = {
name: `${n[i].Organizations}`
},
nodes[`${n[i].Title}`] = {
name: `${n[i].Title}`
};
}
for (let i=0;i<n.length;i++){
edges[`edge${i}`]={
source:`${n[i].Organizations}`,
target:`${n[i].Title}`
}
}
console.log(nodes)
console.log(edges)
return { nodes, edges }
}
}

Global variable undefined inside a function

I am using webpack and have one global variable inside a module, when I try to return it from inside a function I get undefined. I do not really understand the scope since I thought I can access global variables from a functional and return them.
here is my code:
import Gameboard from './factory/gameboard';
import Player from './factory/player';
import helpers from './helpers';
import dom from './dom';
const game = (() => {
let gameStatus = false;
var player;
var computer;
let turn = 0;
const getPlayers = () => {
const name = 'Player1';
player = Player(name);
computer = Player('Computer');
};
const whosTurn = function whosTurn() {
if (turn % 2 === 0) {
return player;
}
return computer;
};
const getPeg = (index = null) => {
const playerTurn = whosTurn();
if (playerTurn.getName() === 'Computer') {
helpers().computerMove();
dom().createPlayerBoard(playerBoard);
} else {
const gameboard = computerBoard;
makeAttack(playerTurn, gameboard, index);
dom().createCompBoard(gameboard);
}
};
return {
getPlayers,
whosTurn,
getPeg,
};
});
export {
game as
default
};
I want the whosTurn function to return me the player or computer variable. What am I doing wrong?

React, accessing variable defined in componentDidMount from another function

I am trying to build a responsive drop down navbar in React and have come to a roadblock. I have these variables defined in componentDidMount
componentDidMount = () => {
let nav = document.getElementById("topNav")
let main = document.getElementById("main")
let menu = document.getElementsByClassName("menuitems")
let close = document.getElementById("closeBtn")
nav.style.height = "50px";
main.style.marginTop = "50px";
for (let i = 0; i < menu.length; i++) {
menu[i].style.marginTop = "100px";
};
close.addEventListener("click", function () {
const menuIcon = close.children;
for (let i = 0; i < menuIcon.length; i++) {
menuIcon[i].classList.toggle("active");
}
});
}
and I am attempting to access them in an onClick function on the same react component here
navToggle = () => {
console.log(this.nav)
}
the variable is logged as undefined.
So, my question, how can I access variables that are defined in the compnentDidMount?
thank you
Variabled defined within the scope of componentDidMount will stay within that function itself. You need to assign them to the class instance like
componentDidMount = () => {
this.nav = document.getElementById("topNav")
this.main = document.getElementById("main")
this.menu = document.getElementsByClassName("menuitems")
this.close = document.getElementById("closeBtn")
this.nav.style.height = "50px";
this.main.style.marginTop = "50px";
for (let i = 0; i < menu.length; i++) {
this.menu[i].style.marginTop = "100px";
};
this.close.addEventListener("click", function () {
const menuIcon = this.close.children;
for (let i = 0; i < menuIcon.length; i++) {
menuIcon[i].classList.toggle("active");
}
});
}

Categories