Add a class iteratively with javascript - javascript

I'm creating a grid 16x16 with javascript. I also want the grid to do something when the mouse hover over each square. The problem is that I do not know how to add a class in a iterative way that every div get the same class.
Doing so, I would make jQuery do the action with one function applied to that class.
This is my present code
var contador = 1;
var outra = document.createElement('div');
outra.id = 'container';
document.body.appendChild(outra);
for (i=1;i<=16;i++){
for (j=1;j<=16;j++){
var divCreation = document.createElement('div');
var created = divCreation;
created.id = "numero"+ contador;
console.log(created.id);
created.textContent = ". ";
contador = contador + 1;
outra.appendChild(created);
}
}
$('#numero'+contador).hover(function(){
$(this).css('background-color','yellow');
});

If you want to give a specific class to your dynamically created elements, you can do it using className property.
Your code would be like this:
divCreation.className = "someClass";
Note:
I don't see why you are setting divCreation in a new variable, it's
just useless.
And instead of detecting hover with jQuery, you can just do it with css, look at my Demo below, or if you want to keep jquery you can use the class selector like this $('.box').hover(...).
Demo:
var outra = document.createElement('div');
outra.id = 'container';
var contador = 1;
document.body.appendChild(outra);
for (i = 1; i <= 16; i++) {
for (j = 1; j <= 16; j++) {
var created = document.createElement('div');
created.className = "box";
created.id = "numero" + contador;
created.textContent = ". ";
contador++;
outra.appendChild(created);
}
}
.box:hover {
background-color: yellow;
}

No need for use of ID for this at all...just use a common class. Also since using jQuery can create all this with a lot less code using by using it.
var $outra = $('<div>', { id: 'container'});
for (i = 1; i <= 16; i++) {
for (j = 1; j <= 16; j++) {
$outra.append( $('<div>', { class: 'box', text: '.'}) );
}
}
$('body').append($outra);
$('.box').hover(function() {
$(this).toggleClass('yellow');
});
.box {
width: 50px;
height: 50px;
display: inline-block;
border: 1px solid #ccc
}
.box.yellow {
background-color: yellow
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>

You can use the attribute starts with selector
$('[id^=numero').hover(
or provide a class to the element and target the elements using the class
This will select all the elements whose id starts with the value you are specifying and attach a hover event.
And when you are using jQuery, why do you want to mix in both Vanilla JS and jQuery. You can just stick with one.
var contador = 1;
var $outra = $('<div/>', {
id: 'container',
class: 'container'
});
$('body').append($outra);
for (i=1;i<=16;i++){
for (j=1;j<=16;j++) {
var $divCreation = $('<div/>', {
id: 'numero' + contador,
text: '. ',
class: 'box'
});
$outra.append($divCreation);
contador = contador + 1;
}
}
$('[id^=numero').hover(function(){
$(this).css('background-color','yellow');
});
.container {
width: 200px;
height: 200px;
border: 1px solid green;
}
.box {
width: 20px;
height: 20px;
border: 1px solid black;
background: green;
float: left;
cursor: pointer;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>

Related

Javascript: cannot access "style" property for div elements in array

I'm making a simple tic tac toe game as my introduction to JS and I ran into a problem almost immediately. I have a div with the class="container", and I use JS to create 9 more div elements inside it.
I have created the div elements with and put them in the cells[] array with no problem. The problem arrises when i try to access .style from the array elements.
const container = document.getElementById("container");
const cells = [];
for (let i = 0; i < 9;) {
cells[i] = document.createElement("div");
container.appendChild(cells[i]);
cells[i].onclick = function(){cells[i].style.backgroundColor = "red";} //this line is where the problem is
i++;
}
I have gone about this using addEventHandler() too, still with me not being able to access the .style property. When I type it in it doesn't show up on that autofill thing VSCode does.
Help?
Ps. I have noticed the cells[] array can't always access it's elements when inside a block.
This issue is due to how closures work in JavaScript.
Here's a demo with your current code (plus some CSS to make it clear what's happening):
const container = document.getElementById("container");
const cells = [];
for (let i = 0; i < 9;) { // actually, the problem is here...
cells[i] = document.createElement("div");
container.appendChild(cells[i]);
cells[i].onclick = function(){cells[i].style.backgroundColor = "red";} // ...here...
i++; // ...and here
}
div:not([class]) {
height: 20px;
border: 1px solid white;
background: cornflowerblue;
}
div:hover {
opacity: .5;
}
<container id="container"></container>
Note that the next div is always highlighted, not the one that was clicked.
Because you increment i within the block itself, that value is captured by the onclick callback, so it's always 1 higher than it should be.
Instead, you need to increment i within the parentheses as the third setup statement for the loop itself.
Here's the fix:
const container = document.getElementById("container");
const cells = [];
for (let i = 0; i < 9; ++i) { // increment here...
cells[i] = document.createElement("div");
container.appendChild(cells[i]);
cells[i].onclick = function() { cells[i].style.backgroundColor = "red"; }
// ...not here
}
div {
height: 20px;
border: 1px solid white;
background: cornflowerblue;
}
div:hover {
opacity: .5;
}
<container id="container"></container>
const container = document.querySelector('.container');
for (let i = 0; i < 9; ) {
const div = document.createElement('div');
container.appendChild(div);
div.addEventListener('click', chanegColor);
div.classList.add('setWidth');
i++;
}
function chanegColor() {
this.style.backgroundColor = 'red';
}
.setWidth {
width: 100px;
height: 100px;
border: 1px solid black;
}
<div class="container"></div>
const container = document.querySelector('.container');
for (let i = 0; i < 9; ) {
const div = document.createElement('div');
container.appendChild(div);
div.addEventListener('click', chanegColor);
div.classList.add('setWidth');
i++;
}
function chanegColor() {
this.style.backgroundColor = 'red';
}

Replacing values in a div

Been working on hangman using javascript and HTML, problem is whenever i click on a letter it doesn't replace the "_"
var myList=["Computer","Algorithm","Software","Programming","Developer"];
var n;
var star=" _";
console.log(myList)
computer=myList[Math.floor(Math.random() * myList.length)];
console.log(computer);
var word= document.getElementById("word").innerHTML=star.repeat(computer.length);
var letter=document.getElementsByClassName("col")
function myFunction(){
n=word.replace(star,letter);
};
for (var i=0; i<letter.length;i++){
letter[i].addEventListener("click",myFunction());
}
myFunction();
letter is basically alphabet(they are not buttons they are divs)
word is also an empty div in which the "-" goes in
in conclusion i want to replace word("-") with letters(which ever letter you click on)
Here is the working example:
var myList=["Computer","Algorithm","Software","Programming","Developer"];
var star="_";
var wrapper = document.querySelector('.wrapper');
for(var i = 0; i<myList.length; i++) {
var list = document.createElement('div');
list.setAttribute('class', 'wrapper-list');
list.setAttribute('id', 'list'+i);
wrapper.appendChild(list);
for(var j=0; j<myList[i].length;j++) {
var item = document.createElement('div');
item.setAttribute('class', 'wrapper-list__item');
item.innerText = myList[i][j];
list.appendChild(item);
item.onclick = function(e) {
this.innerText = star;
}
}
}
.wrapper .wrapper-list {
display: flex;
}
.wrapper .wrapper-list__item {
padding: 5px 10px;
border: 1px solid #dedede;
margin: 5px;
text-transform: uppercase;
cursor: pointer;
}
<div class="wrapper"></div>

Creating div's from an array

So I am creating a platformer game with jQuery, JavaScript and HTML. I would like to make every level with an array containing numbers. Each number will then be a "block" of the platformer.
For instance:
var level = ["10101"];
Would create 3 different blocks, each of with are seperated by a blank space.
However, in the platformer, every number of the array caracterises the height, so a 2 would be on top of a 1.
See where I'm going?
Thing is, I have no clue how to append a series of div's to the game so that they have diffrent x position to fill the .game div.
Plus, I added a for loop with a variable named j, however, if I take out anything to do with jand the loop itself, the code doesn't work... why?
I have the code on CodePen, but here is what I have done so far anyway (for some reason it doesn't work on stackoverflow):
IMPORTANT: The CodePen uses SCSS, not CSS, I converted the code using SassMeister !
$(document).ready(function() {
var level = ["1112222111111111111"];
for (var i = 0; i < level.length; i++) {
for (var j = 0; j < level[i].length; j++) {
var n = level[i][j];
var s = $(".block").width();
if (n === "1") {
$("<div>", {
"class": "block pos1" //or any other logic applied to your borad
}).appendTo(".game");
$(this).css("left", i * s + "px")
}
if (n === "2") {
$("<div>", {
"class": "block pos2" //or any other logic applied to your borad
}).appendTo(".game");
}
}
}
});
.game {
position: absolute;
left: calc((100% - 800px)/2);
height: 500px;
width: 800px;
border: 2px solid black;
}
.block {
background-color: black;
height: 50px;
width: 50px;
position: absolute;
border: 0.5px solid red;
}
.pos1 {
bottom: 0;
}
.pos2 {
bottom: 50px;
}
.pos3 {
bottom: 50px;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="game">
<!-- examples of positions -->
<!--<div class = "block pos1"></div>
<div class = "block pos2"></div>
<div class = "block pos5"></div>
<div class = "block pos4"></div>-->
</div>
Please Help!
Thank you! Tell me if I need to be more clear!
To append the element using jQuery, replace
for(var each in level) {
level[each].$(".game").append("<div class = 'block pos3'></div>");
}
with
for(var i = 0, length = level.length; i < length; i++){
$("<div>", {
"class": "block pos" + level[i] //or any other logic applied to your borad
}).appendTo(".game");
}
Also, for(var i in obj) is for iterating through the properties of an object, the sequence of the element being iterated is not guaranteed. For arrays, you should use for(var i = 0; i < x; i++) Javascript for loop

Dynamically map button with div

I want to link a button with div dynamically using id’s for example.
I have two buttons and two div this is been dynamically created if i click the second button it has to go second div if i click first button it first button has to visible. Using pure vanila javascript.
var inputElement = document.getElementById("inputAdd_page");
var totalCount = 0;
inputElement.addEventListener('blur', function() {
var count = this.value;
if(count && !isNaN(count)) {
fragment = document.createDocumentFragment();
for (var j = 0; j < count; ++j) {
spancount = document.createElement('span');
prevPage = document.createElement('div');
navbutton = document.createElement('button');
preview_PageSize = document.getElementById('page');
navpageBtn = document.getElementById('pageBtn');
navbutton.className = "div_navig";
navbutton.setAttribute('id', ['pag_navg' + totalCount]);
navbutton.innerHTML=[1 + totalCount];
spancount.className = "spanCount";
spancount.innerHTML=[1 + totalCount];
prevPage.className = "preview_windowSize_element";
prevPage.setAttribute('id', ['page' + (totalCount)]);
prevPage.appendChild(spancount);
navpageBtn.appendChild(navbutton);
prevPage.setAttribute('id', ['page' + (totalCount)]);
preview_PageSize.childNodes[0]);
totalCount++;
}
inputElement.value="";
document.body.appendChild(fragment);
}
});
Here is the fiddle Link
Kindly help me actually I am trying I am not getting it
Thanks in advance
I would suggest not using a partial id or anything like that to link your elements. Instead, use an attribute specifically created for the purpose. In the following code, I'm using an attribute named data-page which is simply set to the value you're appending to the ids. I also added an event handler which just sets the z-index of all pages to 0, then sets the selected page's z-index to 10.
//create div
var inputElement = document.getElementById("inputAdd_page");
var totalCount = 0;
inputElement.addEventListener('blur', function() {
var count = this.value;
// Gaurd condition
// Only if it is a number
if (count && !isNaN(count)) {
fragment = document.createDocumentFragment();
for (var j = 0; j < count; ++j) {
spancount = document.createElement('span');
prevPage = document.createElement('div');
navbutton = document.createElement('button');
preview_PageSize = document.getElementById('page');
navpageBtn = document.getElementById('pageBtn');
navbutton.className = "div_navig";
navbutton.setAttribute('id', ['pag_navg' + totalCount]);
navbutton.setAttribute('data-page', totalCount);
navbutton.innerHTML = [1 + totalCount];
navbutton.addEventListener('click', function (e) {
var el = e.target;
var page = parseInt(el.getAttribute('data-page'), 10);
var allPages = document.querySelectorAll('.preview_windowSize_element');
Array.prototype.forEach.call(allPages, function (pageElement) {
pageElement.style.zIndex = 0;
});
var pageEl = document.querySelector('div[data-page="' + page + '"]');
pageEl.style.zIndex = 10;
});
spancount.className = "spanCount";
spancount.innerHTML = [1 + totalCount];
prevPage.className = "preview_windowSize_element";
prevPage.setAttribute('id', ['page' + (totalCount)]);
prevPage.setAttribute('data-page', totalCount);
prevPage.appendChild(spancount);
navpageBtn.appendChild(navbutton);
preview_PageSize.insertBefore(prevPage, preview_PageSize.childNodes[0]);
totalCount++;
}
inputElement.value = "";
document.body.appendChild(fragment);
}
});
.title_Textbox {
border: 1px solid rgb(152, 152, 152);
width: 230px;
padding: 5px 0 5px 5px;
}
.preview_windowSize {
margin: 15px 15px 15px 15px;
height: 300px;
padding: 5px;
}
.preview_windowSize_element {
position: absolute;
background-color: lightGrey;
border: 1px solid rgb(155, 155, 155);
border-bottom-right-radius: 10px;
border-bottom-left-radius: 10px;
padding: 5px;
width: 93.5%;
height: 300px;
}
<input type="text" class="form-control title_Textbox" id="inputAdd_page" placeholder="No Of Pages">
<div class="preview_windowSize" id="page">
</div>
<div id="pageBtn" class="row pagination_btn">
</div>

Using JavaScript to create and append nested div elements

I am trying to use JavaScript to update the CSS layout as the webpage loads. My code looks like so:
var container = 0; // Add Total UI
var containerTitle = 0; // Container Title
var article = 0;
var articleTitle = 0;
var divName = 0; // temp variable for article id names
var divNameT = 0; // temp variable for title id names
function setLayout(id) {
container = document.getElementById(id);
for(var x = 0; x < 18; ++x) {
// CREATE CONTAINER FOR ALL PANELS
divName = "articleCon"+ x;
article = document.createElement('div');
article.id = divName;
// SETUP CSS STYLE
article.style.cssText = 'height: 205px; width: 300px; background: red; margin-right: 20px; margin-bottom: 20px; display: block; float: left;';
setNewsTitle(count,divName); // Function Call to set Title Panel
container.appendChild(article);
}
}
function setNewsTitle(count,id) {
containerTitle = document.getElementById(id);
// CREATE CONTAINER FOR TITLE
divNameT = "articleTitle"+ count;
articleTitle = document.createElement('div');
articleTitle.id = divNameT;
// SETUP CSS STYLE
articleTitle.style.cssText = 'position: absolute; height: 45px; width: 100px; background: yellow; display: inline;';
containerTitle.appendChild(articleTitle);
}
When I compile my code without making the call to function setNewsTitle(count,id) all the CSS elements are working fine.
The issue I am facing here is whenever the function call is made, my page appears blank. Nothing displays on the screen.
I tried adding screenshots for better understanding, but i don't have the reputation yet.
Try ...
container.appendChild(article);
setNewsTitle(x,divName); // Function Call to set Title Panel
The article needs to be in place before setNewsTitle is run, since you are looking for the element by id. Also, you do not have count, you have x ...
jsFiddle: http://jsfiddle.net/rfornal/o1wyae74/
Try this, append child in DOM before call funtion setNewsTitle, replace count with x :
var container = 0; // Add Total UI
var containerTitle = 0; // Container Title
var article = 0;
var articleTitle = 0;
var divName = 0; // temp variable for article id names
var divNameT = 0; // temp variable for title id names
function setLayout(id) {
container = document.getElementById(id);
for(var x = 0; x < 18; ++x) {
// CREATE CONTAINER FOR ALL PANELS
divName = "articleCon"+ x;
article = document.createElement('div');
article.id = divName;
// SETUP CSS STYLE
article.style.cssText = 'height: 205px; width: 300px; background: red; margin-right: 20px; margin-bottom: 20px; display: block; float: left;';
container.appendChild(article);
setNewsTitle(x,divName); // Function Call to set Title Panel
}
}
function setNewsTitle(count,id) {
containerTitle = document.getElementById(id);
// CREATE CONTAINER FOR TITLE
divNameT = "articleTitle"+ count;
articleTitle = document.createElement('div');
articleTitle.id = divNameT;
// SETUP CSS STYLE
articleTitle.style.cssText = 'position: absolute; height: 45px; width: 100px; background: yellow; display: inline;';
containerTitle.appendChild(articleTitle);
}
You have 2 issues in your code:
You have not actually added the element to the DOM yet, so when you attempt document.getElementById in your function setNewsTitle() - it won't find anything.
You have an error in the method call to setNewsTitle(count,id). You are passing "count", but count doesn't exist. You need to call it as setNewsTitle(x, divName) but only AFTER you have made the call to container.appendChild(article).
The setLayout function would end up something like this:
function setLayout(id) {
container = document.getElementById(id);
for(var x = 0; x < 18; ++x) {
// CREATE CONTAINER FOR ALL PANELS
divName = "articleCon"+ x;
article = document.createElement('div');
article.id = divName;
// SETUP CSS STYLE
article.style.cssText = 'height: 205px; width: 300px; background: red; margin-right: 20px; margin-bottom: 20px; display: block; float: left;';
// Add it to the DOM first
container.appendChild(article);
// need to pass "X", not count
setNewsTitle(x,divName); // Function Call to set Title Panel
}
}

Categories