Unable to add all content to parent div inside a loop - javascript

The array gets console logged fine, but only the last person of the array is inserted in the HTML <div>.
Why or what is the failure?
document.getElementById("team").addEventListener("click", show)
function show(){
document.getElementById("fritz").style.display = "block";
document.getElementById("bill").style.display = "block";
document.getElementById("fran").style.display = "block";
for (i = 0; i < people.length; i++) {
var persoxn = people[i].printinfos()
document.getElementById('insert_text').innerHTML = persoxn
console.log(persoxn)
}
}
(https://imgur.com/IJbxvbR)
console

You are overriding (replacing) the <div> content in each iteration, therefore all of the elements except the last one get overwritten.
Maybe you meant to use .insertAdjacentHTML():
for (let i = 0; i < people.length; i++) {
var person = people[i].printinfos();
document.getElementById('insert_text').insertAdjacentHTML(person, "beforeend");
console.log(person);
}
Also don't forget to declare i inside the loop.

Related

createElement and loops [duplicate]

In JavaScript I am creating a grid (the type of grid you see in Photoshop) with HTML tables. The grid size is going to be variable, i.e., changeable by the user, so the size of each grid square must be calculated and divided by the number of pixels available to get an exact size grid.
I've done all this, but I have a problem adding in the necessary table elements to create the grid. My code is in full working order, except when I use the appendChild() function inside a for loop it only ever appends a single child, when it should be appending up to a couple of hundred.
My code:
grid.show = function(event)
{
var e = event;
if(grid.show_grid == false)
{
grid.show_grid = true;
parent.document.getElementById("grid_table").style.display = "block";
// Get grid (table) and create some elements.
grid.get_grid = parent.document.getElementById("grid_table");
grid.tr = parent.document.createElement("tr");
grid.td = parent.document.createElement("td");
// Clear the grid of all squares so we don't have to worry about subtracting anything.
grid.get_grid.innerHTML = "";
// Calculate the number of horizontal and vertical squares.
var horizontal = Math.ceil(grid.total_width / grid.size);
var vertical = Math.ceil(grid.total_height / grid.size);
// This was a nested loop, removed for demonstration.
// Attempting to add 10 "<tr><td></td></tr>" to the table.
for(var j = 0; j < 10; j++)
{
grid.tr.appendChild(grid.td);
}
//console.log(grid.tr);
// Add the elements to the table.
grid.get_grid.appendChild(grid.tr);
}
else
{
grid.show_grid = false;
parent.document.getElementById("grid_table").style.display = "none";
}
}
This only ever returns a single table row with single table data inside, like so:
<tr>
<td></td>
</tr>
I've already looked at this page and this page, and they sound promising but I just can't figure out how to make this work.
EDIT: Code now working, solution:
grid.show = function(event)
{
var e = event;
if(grid.show_grid == false)
{
grid.show_grid = true;
parent.document.getElementById("grid_table").style.display = "block";
grid.get_grid = parent.document.getElementById("grid_table");
grid.tr = null;
grid.td = null;
grid.get_grid.innerHTML = "";
var horizontal = Math.ceil(grid.total_width / grid.size);
var vertical = Math.ceil(grid.total_height / grid.size);
for(var i = 0; i < vertical; i++)
{
grid.tr = parent.document.createElement("tr");
for(var j = 0; j < horizontal; j++)
{
grid.td = parent.document.createElement("td");
grid.td.width = grid.size;
grid.td.height = grid.size;
grid.tr.appendChild(grid.td);
}
grid.get_grid.appendChild(grid.tr);
}
}
else
{
grid.show_grid = false;
parent.document.getElementById("grid_table").style.display = "none";
}
}
You are appending the same element over and over. You need to call document.createElement each time you wish to have a new element.
EDIT: If the element setup is really complicated and potentially includes children then you can also use Node.cloneNode
If you want to make one copy of the element, you will need to clone it. Use cloneNode()
So change
grid.tr.appendChild(grid.td);
to
grid.tr.appendChild(grid.td.cloneNode(true));
for(var j = 0; j < 10; j++)
{
grid.tr.appendChild(grid.td);
}
should be
for(var j = 0; j < 10; j++) {
var newTd = parent.document.createElement('td');
grid.tds.push(newTd); // if you need it, not sure why though
grid.tr.appendChild(newTd);
}

How to Change Color of Div within a for statement?

Inside my php while loop I output a div with id divborder, and class div-border
Inside that div i have another div with id title
<div id='divborder' class='div-border'>
<div id='Title'>This is Title</div> <br/> video elements
</div>
I have a JavaScript function that get called when the video ends
for (var i = 0; i < videos.length; i++) {
videos[i].addEventListener("ended", function(event)
{
var divBoader2 = document.getElementsByClassName("divborder")[3];
divBoader2.style.borderColor = "#b1ff99";
}
My Question is how do i change the border color of the div and the title of second div?
I can do it like this:
var divBoader2 = document.getElementsByClassName("divborder")[3];
divBoader2.style.borderColor = "#b1ff99";
which works but its not dynamic
Save the value of value at i in another variable declared with let
for (var i = 0; i < videos.length; i++) {
let index = i; //save the value as let so that its binding stays
videos[i].addEventListener("ended", function(event)
{
var divBoader = document.querySelectorAll("div-border")[index];
divBoader.style.borderColor = "#b1ff99";
}
}
Or if the video elements are within the div-border, then use closest
for (var i = 0; i < videos.length; i++) {
videos[i].addEventListener("ended", function(event)
{
var divBoader = event.currentTarget.closest(".div-border");
divBoader.style.borderColor = "#b1ff99";
}
}
A little less verbose code
[...videos].forEach( s => s.closest( ".div-border" ).style.color = "#b1ff99" )
Try this,
Give class name div-border instead of divborder
for (var i = 0; i < videos.length; i++) {
videos[i].addEventListener("ended", function(event)
{
var divBoader2 = document.getElementsByClassName("div-border")[3];
divBoader2.style.borderColor = "#b1ff99";
}
What you need is probably a videos[i].parentNode instead of document.getElementsByClassName("div-border")[3] (see https://developer.mozilla.org/en-US/docs/Web/API/Node/parentNode)

JS: getElementByID wildcard

I have a table and a button.
If i click the button, all <tr> which have an id starting with "tr" (in the example the first 3) should be set to display = "none";
Here is a Fiddle
Has anyone a Idea how i get this to work?
Give all the elements that have id="tr_NNNN" a distinct class, e.g. class="tr tr_NNNN". Then use the following loop:
var hide_trs = document.getElementsByClassName('tr_NNNN');
for (var i = 0; i < hide_trs.length; i++) {
hide_trs[i].style.display = "none";
}
You can simply iterate through your tr elements using the IDs:
function doJS() {
for(var i = 1; i <= 3; i ++) {
document.getElementById("tr_" + i).style.display="none";
}
}
You can't supply a wildcard to gEBI, but you can use the attribute starts with selector in qSA:
document.querySelectorAll("[id^='tr_']")[0].style.display="none";
I agree with using classes instead of IDs for this, but this should satisfy your original question:
function doJS() {
var rows = document.getElementsByTagName("tr");
for (var i = 0; i < rows.length; i++) {
var row = rows[i];
if(row.getAttribute("id") && /^tr/.test(row.getAttribute("id"))){
row.style.display = 'none';
}
}
}
http://jsfiddle.net/eHSwJ/14/
And while this isn't a jQuery question, I would point out that by leveraging jQuery, this can be reduced to:
$('tr[id^="tr"]').css('display', 'none');

Access elements in ul list

I have the following list hierarchy:
<ul id="ulid">
<li><a><div class="mydiv">content</div></a></li>
<li><a><div class="mydiv">content</div></a></li>
...
</ul>
I want to add some css rules to the div and this is what i've tried so far:
var myul = document.getElementById("ulid");
var myli = myul.getElementsByTagName("li");
for(var i = 0; i < myli.length; i++) {
//myli[i].parentNode.style.display = "none"; // that works
var links = myli[i].getElementsByTagName("a");
for(var ii = 0; ii < links.length; ii++) {
links[ii].parentNode.style.display = "none"; // doesnt work
}
}
I can hide the li items but cant do the same for a So i cant reach the div. What am i doing wrong here?
EDIT: getElementsByClassName seems not working in greasemonkey scripts as it simply works in Emmanuel N's fiddle.
Your code seems to work. Check out this Fiddle
var myul = document.getElementById("ulid");
var myli = myul.getElementsByTagName("li");
for(var i = 0; i < myli.length; i++)
{
var links = myli[i].getElementsByTagName("a");
for(var ii = 0; ii < links.length; ii++)
{
links[ii].parentNode.style.display = "none";
}
}
Your code actually does work, but I don't think it does what you're intending it to do. The last line: links[ii].parentNode.style.display = "none" will actually hide the parent node of the a tag (i.e. the li) tag, rather than the div. parentNode will go one level UP, not down.
Instead of trying to get myli[i].getElementsByTagName("a") and then working down to the div, why not myli[i].getElementsByTagName("div"), and then simply do:
var myul = document.getElementById("ulid");
var myli = myul.getElementsByTagName("li");
for(var i = 0; i < myli.length; i++) {
//myli[i].parentNode.style.display = "none"; // that works
var links = myli[i].getElementsByTagName("div");
for(var ii = 0; ii < links.length; ii++) {
links[ii].style.display = "none";
}
}
Of course, there are many more efficient ways to do it. You already have classnames on the divs, so
document.getElementsByClassName("mydiv");
would work just as well.
Or, if you use jQuery, you can do the same thing without having to iterate explicitly:
$("div.mydiv").css(etc.); // style this however you want
If you aren't opposed to using jQuery, the following would hide your divs for you.
$(document).ready(function () {
var myDivs = $('div.mydiv');
for(var eachDiv in myDivs) {
$(eachDiv).hide();
}
});

How do I access DOM nodes from an array in javascript?

I am trying to build a drop-down menu that will show a row to the side of it when you hover over one of the cells with the mouse. I'm really new with using the DOM, and javascript as well.
The problem I'm running into is that the array I have created doesn't seem to access what I thought it should. Is it just my syntax, or do I need to approach this differently? Here is my code:
window.onload = function () {
var tableID = "strokerKitMenu";
var table = document.getElementById(tableID);
var tableRows = table.getElementsByTagName("tr");
var tableCell = [];
var counter = 0;
for (i = 0; i < tableRows.length; i++) {
tableCell[i] = new Array();
tableCell[i].push(tableRows[i].getElementsByTagName("td"));
}
for (i = 0; i < tableCell.length; i++) {
tableCell[0, i].style.display = "block"; //This doesn't compile
alert(tableCell[0, i].Text); //This comes back "undefined"
for (j = 1; j < tableCell[i].length; j++) //I haven't even tested this part yet
{
tableCell[i][j].onmouseover = function showCell() {
tableCell[i][j + 1].style.display = "block";
}
tableCell[i][j].onmouseout = function hideCell() {
this.style.display = "none";
}
} //end inner for loop
} //end outer for loop
}
tableCell[0, i].style.display="block"; //This doesn't compile
This syntax is invalid in JavaScript: you have specified two indices for tableCell but I guess you meant tableCell[0][i].style.display="block";
alert(tableCell[0, i].Text); //This comes back "undefined"
Once you fix the first error, you will want to change this to tableCell[0][i].textContent.
tableCell[i].push.apply(tableCell[i], tableRows[i].getElementsByTagName("td"));
You don't want to push the single array in. You want to push all the elements in. Otherwise you would have to access them as tableCell[i][0][j]

Categories

Resources