selectionSort Javascript animation - javascript

I'm trying to build a visual representation of some famous sorting algorithms in javascript, but I can't understand why my code doesn't print each iteration even if the print function is in the for loop. I only get the final result.
This is the sorting function, in particular the selection sort algorithm:
function selectionSort(array) {
var i, j, min_idx;
let n = array.length;
for (i = 0; i < n-1; i++)
{
min_idx = i;
for (j = i + 1; j < n; j++)
{
if (array[j] < array[min_idx])
{
min_idx = j;
}
}
var temp = array[min_idx];
array[min_idx] = array[i];
array[i] = temp;
printArray(array);
}
}
And this is the printing function:
function printArray(array) {
document.getElementById('container').innerHTML ='';
for(let i = 0; i < array.length; i++)
{
document.getElementById('container').innerHTML += '<div class = "column '+i+'" id = "'+i+'" style = "height: '+array[i]+'px;"></div>';
}
}
Thank you a lot

It's what #Bravo states in the comments. The screen is updates at least 60 times per second, but it takes less time to do the sorting. So you need to add a timeout in a recursive loop so you can actually see the animation.
I replaced the first for loop with this recursive loop. I think the code it self-explanatory.
I did some optimization in your printArray(), where it takes time to constantly doing DOM changes. Instead, loop through to create a text string and then add it once to #container.innerHTML. There were also some faulty thinking in the value that you gave the visualized divs, where you only added the order (i), instead of adding the actual value (array[i]).
const iterationLegend = document.getElementById('iterations');
const containerDiv = document.getElementById('container');
const ANIMATION_SPEED = 1000;
const RESTART = 0;
var firstIteration;
function startSelectionSort(array) {
firstIteration = RESTART;
selectionSort(array);
}
function selectionSort(array) {
let min_idx = firstIteration,
n = array.length;
for (let j = firstIteration + 1; j < n; j++) {
if (array[j] < array[min_idx]) {
min_idx = j;
}
}
var temp = array[min_idx];
array[min_idx] = array[firstIteration];
array[firstIteration] = temp;
visualizeArray(array);
iterationLegend.textContent = 'iteration ' + firstIteration;
if (firstIteration < n - 1) {
firstIteration++;
setTimeout(selectionSort.bind(this, array), ANIMATION_SPEED);
} else {
iterationLegend.textContent = 'Done';
}
}
function visualizeArray(array) {
let elementStr = '';
let value = 0;
for (let i = 0; i < array.length; i++) {
value = array[i];
elementStr += `<div class="column${value}" data-value="${value}"></div>`;
}
containerDiv.innerHTML = elementStr;
}
startSelectionSort([2, 3, 5, 5, 1, 1, 1, 1, 4]);
fieldset {
display: inline;
}
#iterations {
font-size: 13px;
text-transform: uppercase;
}
#container {
display: inline-flex;
}
#container > div {
width: 10px;
height: 100px;
margin: 2px 1px 0px;
}
.column1 {
background-color: brown;
}
.column2 {
background-color: black;
}
.column3 {
background-color: teal;
}
.column4 {
background-color: red;
}
.column5 {
background-color: indigo;
}
<fieldset>
<legend id="iterations">Iterations</legend>
<div id="container"></div>
</fieldset>

Related

Hide all spans that are close to cursor on mouseover? [closed]

Closed. This question needs to be more focused. It is not currently accepting answers.
Want to improve this question? Update the question so it focuses on one problem only by editing this post.
Closed 1 year ago.
Improve this question
I am working on a project where I have several hundred spans next to each other, with a letter of the text in each span. When I hover over one of the spans, I want to hide it, as well as the other spans nearby.
It makes an image like this:
##############
##############
##############
##############
My goal is to hide all of the spans in a given distance away from the mouse, like this:
HTML
<span id="overlay-1">#</span>
<!-- ... -->
<span id="overlay-142">#</span>
<span id="overlay-143">#</span>
I'm able to hide 1 of the spans by calling their ids on mouseover and changing the style to display=none, but I want to hide all that are in close proximity to the mouse. Any ideas on what I should do?
I tried to solve this through JS. Here is my code:
function paint() {
let txt = "";
for (let j = 0; j < 100; j++) {
txt += "<div>"
for (let i = 0; i < 100; i++) {
txt += `<span onmouseout="hoverOut()" onmouseover="hover(this)" onmouseuop id="overlay-${i}-${j}">#</span>`
}
txt += "</div>"
}
document.getElementById('painting').innerHTML += txt
}
function hover(x) {
let id = x.id;
let i = x.id.split('-')[1];
let j = x.id.split('-')[2];
for (let a = -2; a <= 2; a++) {
for (let b = -1; b <= 1; b++) {
const elem = document.getElementById(`overlay-${i-a}-${j-b}`);
elem ? elem.style.opacity = 0 : null;
}
}
x.style.opacity = '0';
}
function hoverOut() {
for (let i = 0; i < document.getElementsByTagName('span').length; i++) {
document.getElementsByTagName('span')[i].style.opacity = 1;
}
}
<body onload="paint()">
<div id="painting">
</div>
</body>
Another approach without using ids would be to use Element.getBoundingClientRect() to get the size and position of the hovered element and then use Document.elementFromPoint() inside a loop to access elements near the hovered one:
const main = document.querySelector('main')
for (let i = 0; i < 800; i++) main.innerHTML += '<span>#</span>'
const spans = document.querySelectorAll('span')
const areaWidth = 50
const areaHeight = 50
const hidden = []
function getElements(currentSpan, color) {
const { top, right, bottom, left, width, height } = currentSpan.getBoundingClientRect()
for (let col = left - areaWidth / 2; col < right + areaWidth / 2; col += width || 14) {
for (let row = top - areaHeight / 2; row < bottom + areaHeight / 2; row += height || 14) {
const el = document.elementFromPoint(col, row)
if (el?.tagName === 'SPAN') {
el.style.color = color
hidden.push(el)
}
}
}
}
spans.forEach(span => {
span.addEventListener('mouseover', () => getElements(span, 'transparent'))
span.addEventListener('mouseout', () => {
hidden.forEach(el => (el.style.color = ''))
hidden.length = 0
})
})
main {
display: flex;
flex-wrap: wrap;
width: 640px;
cursor: default;
}
<main></main>
You could use a CSS solution - overwrite the adjacent characters with a pseudo element on the clicked character.
This snippet uses a monospace font and it's set line height and letter spacing as CSS variables so you can alter them as required.
function clicked(ev) {
ev.target.classList.add('obscure');
}
const container = document.querySelector('.container');
for (let i = 0; i < 200; i++) {
const span = document.createElement('span');
span.innerHTML = '#';
if (i % 10 == 0) {
container.innerHTML += '<br>';
}
container.appendChild(span);
}
container.addEventListener('click', clicked);
.container {
width: 50vw;
height: auto;
font-family: Courier, monospace;
--line-height: 20px;
--letter-spacing: 5px;
line-height: var(--line-height);
letter-spacing: var(--letter-spacing);
}
.container span {
position: relative;
margin: 0;
padding: 0;
}
.obscure::before {
content: '';
width: calc(5ch + (6 * var(--letter-spacing)));
height: calc(3 * var(--line-height));
background-color: white;
position: absolute;
top: 0;
transform: translate(calc(-50% + 0.5ch), calc(-50% + (1ch)));
left: 0;
z-index: 1;
display: inline-block;
}
<body>
<div class="container"></div>
</body>
If I understand you right, you want the span to vanish, but you don't want its space to also vanish. display:none is the wrong solution. you need visibility:hidden.
hiding the hovered element and elements before and after it is easy. the difficulty is in hiding element that are above or below it.
to do that, you would need to do some math.
assuming the answer doesn't need to be exact, you could do it something like this:
calculate the centre positions of all spans and keep them in an array (so you don't need to recalculate every time)
when a span is mouse-entered, check the array and calculate all spans that are within radius r of that span's centre point - or just above/below/left/right - whatever works.
create a new array of spans that should be hidden
check all hidden spans - if any of them are not in that new array, unhide them (visibility:visible)
finally, go through the new array and set visibility:hidden on all spans in that array
Here is a bit diffrent and custumisable aproch:
// Variables
const ROW = 10; // Total number of rows
const COL = 35; // Total number of items in a row (i.e. columns)
const RANGE = 2; // Total number of items to be selected in each direction
const values = []; // To colect ids of items to be selected
// Utility Function
const push = (value) => {
if (value > 0 && value <= ROW * COL && !values.includes(value)) values.push(value);
};
// Add items in the root div
const root = document.querySelector("#root");
for (let i = 0; i < ROW; i++) {
root.innerHTML += `<div id="row-${i + 1}"></div>`;
for (let j = 0; j < COL; j++) {
document.querySelector(`#row-${i + 1}`).innerHTML += `<span id="item-${COL * i + (j + 1)}">#</span>`;
}
}
// Add class to the items as per the RANGE
root.addEventListener("mouseover", (e) => {
values.length = 0;
const id = e.target.id;
if (!id.includes("item-")) return;
const current = +id.replace("item-", "");
push(current);
for (let i = -RANGE; i < RANGE; i++) {
push(current + i);
for (let j = -RANGE; j <= RANGE; j++) {
push(current + COL * i + j);
push(current - COL * i + j);
}
}
for (let i = 0; i < values.length; i++) {
const item = document.querySelector(`#item-${values[i]}`);
item.classList.add("selected");
}
});
// Remove class from the items as per the RANGE
root.addEventListener("mouseout", () => {
for (let i = 0; i < values.length; i++) {
const item = document.querySelector(`#item-${values[i]}`);
item.classList.remove("selected");
}
});
/* Just for styling purposes */
body {
background-color: #111;
color: #fff;
}
#root [id*="item-"] {
padding: 1px;
}
/* Styles for the selected item */
#root [id*="item-"].selected {
/* color: transparent; */ /* 👈 Use this to get your intended effect */
color: #ffa600;
}
<div id="root"></div>

How to create real-time changes in JavaScript

So I wrote a pretty basic code. I'm a real noob. Started JavaScript 3 days back. I want the sorting process to be visualized while the sorting is going on. But when the SORT button is clicked after a while the sorted array is show. But what I want is to show the changes happening to the array in real-time.
Please help me out.
var array = [];
container_content= "";
for (var i=0; i < 50; i++) {
array.push(Math.random() *500)
}
container_content = "";
function myFunction(element) {
container_content += '<div class="array-bar"></div>';
}
array.forEach(myFunction);
$(".container").html(container_content);
function another(element, index){
element.style.height = array[index]
}
$( "div" ).each( function( index, element ){
$( this ).css('height', array[index]);
});
$('button').click(function(){
var i, j, temp;
for(i = 0; i < array.length; i++)
{
for(j = 0; j < array.length-1; j++)
{
if( array[j] > array[j+1])
{
// swap the elements
temp = array[j];
array[j] = array[j+1];
array[j+1] = temp;
}
}
$( "div" ).each( function( index, element ){
$( this ).css('height', array[index]);
});
}
})
I took what you were trying to do and broke it down into 4 basic functions (1 main function and 3 helper functions).
runSort is the main function that uses all the other helper functions to do everything.
makeArrayAndUnsyncedBars generates your random array and basic divs that you'll use as green "bars", but it doesn't set the heights of these divs according to the values in the array.
syncArrayToBars sets the heights of these "bar" divs according to the values in the array
sortUntilNextSwap sorts the array until either a swap occurs or the sort completes. this function returns false if it made a swap (meaning that it's still working its way through the array) or true otherwise.
var FRAMES_PER_SECOND = 50;
var sortInterval = null;
function runSort() {
clearInterval(sortInterval);
makeArrayAndUnsyncedBars(50);
syncArrayToBars();
sortInterval = setInterval(function() {
var finishedSorting = sortUntilNextSwap();
syncArrayToBars();
if (finishedSorting) clearInterval(sortInterval);
}, Math.round(1000 / FRAMES_PER_SECOND));
}
var array = [];
function makeArrayAndUnsyncedBars(numberOfValues) {
var htmlToAdd = "";
array = [];
for (var i = 0; i < numberOfValues; i++) {
htmlToAdd += "<div class=\"bar\"></div>";
array.push(rando(150));
}
$("#bars").html(htmlToAdd);
}
function syncArrayToBars() {
for (var i = 0; i < array.length; i++) $(".bar").eq(i).css({
height: array[i] + "px"
});
}
var i, j, temp;
function sortUntilNextSwap() {
for (i = 0; i < array.length; i++) {
for (j = 0; j < array.length - 1; j++) {
if (array[j] > array[j + 1]) {
// swap the elements
temp = array[j];
array[j] = array[j + 1];
array[j + 1] = temp;
return false;
}
}
}
return true;
}
.bar {
width: 5px;
background: #5aedab;
border-radius: 3px;
display: inline-block;
margin: 0px 3px;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.5.1/jquery.min.js"></script>
<script src="https://randojs.com/1.0.0.js"></script>
<div id="bars"></div>
<button onclick="runSort();">Run sort</button>
EDIT: I should mention that I used rando.js for the randomness out of habit, but it's not super necessary here given that you use Math.random() very little anyway. Take it out or leave it in according to your preference.

Javascript - For loop only affecting last element in array

I'm trying to make a script that gives whatever you're pointing at (that has the class foxrainbowhover) an asynchronous rainbow effect.
I've got it working for the most part but unfortunately it, for some reason, only affects the last element inside of the array. I've ran it all through mentally several times but cannot find a single thing wrong with it. I'm hoping you'll be able to help. Here's what the effect should look like: https://jsfiddle.net/Laoderv6/
(function(){let rainbowhover = document.getElementsByClassName('foxrainbowhover');
let rainbowelements = [];
let hoverinterval = [];
let hovercounters = [];
for(let i = 0; i < rainbowhover.length; i++) {
rainbowelements[i] = spanElementContents(rainbowhover[i]);
}
//Set up the wavey effect with counters.
for(let id = 0; id < rainbowelements.length; id++) {
for(let i = 0; i < rainbowelements[id].length; i++) {
hovercounters[id] = [];
hovercounters[id][i] = 0 + i;
}
}
// Add event listeners for every item classed foxrainbowhover.
for(let id = 0; id < rainbowhover.length; id++) {
rainbowhover[id].addEventListener("mouseenter", function startanimation() {
console.log('hit');
hoverinterval[id] = setInterval(() => {
for(let i = 0; i < rainbowelements[id].length; i++) {
rainbowelements[id][i].style.color = 'hsl(' + (hovercounters[id][i] + Math.floor(i * 1)) + ', 100%, 70%';
console.log(rainbowelements[id]);
hovercounters[id][i]++;
}
}, 8);
}, false);
rainbowhover[id].addEventListener("mouseleave", function stopanimation() {
console.log('agh');
clearInterval(hoverinterval[id]);
for(let i = 0; i < rainbowelements[id].length; i++) {
rainbowelements[id][i].style.color = 'black';
}
}, false);
}
})()
function spanElementContents(element) {
let spans = [];
let chars = [];
chars.push(element.innerText.split(""));
for(let i = 0; i < chars.length; i++){
element.innerHTML = chars[i].map(function(char) {
return '<span>' + char + "</span>";
}).join('');
}
let temphtmlcollection = [].slice.call(element.children)
for(let j = 0; j < temphtmlcollection.length; j++) {
spans.push(temphtmlcollection[j]);
}
return spans;
}
body {
background-color: black;
}
h1 {
color: white;
}
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<title>Page Title</title>
<meta name="viewport" content="width=device-width, initial-scale=1">
</head>
<body>
<h1 class="foxrainbowhover">test1</h1>
<h1 class="foxrainbowhover">test111</h1>
<h1 class="foxrainbowhover">test111111</h1>
</body>
</html>
You are constantly resetting your array. You need to initialize it in the outer loop.
Change this:
for(let id = 0; id < rainbowelements.length; id++) {
for(let i = 0; i < rainbowelements[id].length; i++) {
hovercounters[id] = [];
hovercounters[id][i] = 0 + i;
}
}
to this:
for(let id = 0; id < rainbowelements.length; id++) {
hovercounters[id] = [];
for(let i = 0; i < rainbowelements[id].length; i++) {
hovercounters[id].push(i);
}
}
or more simply:
or (let id = 0; id < rainbowelements.length; id++) {
hovercounters[id] = rainbowelements[id].map((_, i) => i);
}
let rainbowhover = document.getElementsByClassName('foxrainbowhover');
let rainbowelements = [];
let hoverinterval = [];
let hovercounters = [];
for (let i = 0; i < rainbowhover.length; i++) {
rainbowelements[i] = spanElementContents(rainbowhover[i]);
}
//Set up the wavy effect with counters.
for (let id = 0; id < rainbowelements.length; id++) {
hovercounters[id] = rainbowelements[id].map((_, i) => i);
}
// Add event listeners for every item classed foxrainbowhover.
for(let id = 0; id < rainbowhover.length; id++) {
rainbowhover[id].addEventListener("mouseenter", function startanimation() {
hoverinterval[id] = setInterval(() => {
for(let i = 0; i < rainbowelements[id].length; i++) {
rainbowelements[id][i].style.color = 'hsl(' + (hovercounters[id][i] + Math.floor(i * 1)) + ', 100%, 70%';
hovercounters[id][i]++;
}
}, 8);
}, false);
rainbowhover[id].addEventListener("mouseleave", function stopanimation() {
clearInterval(hoverinterval[id]);
for(let i = 0; i < rainbowelements[id].length; i++) {
rainbowelements[id][i].style.color = 'black';
}
}, false);
}
function spanElementContents(element) {
let spans = [];
let chars = [];
chars.push(element.innerText.split(""));
for(let i = 0; i < chars.length; i++){
element.innerHTML = chars[i].map(function(char) {
return '<span>' + char + "</span>";
}).join('');
}
let temphtmlcollection = [].slice.call(element.children)
for(let j = 0; j < temphtmlcollection.length; j++) {
spans.push(temphtmlcollection[j]);
}
return spans;
}
h1 {
color: black;
}
<h1 class="foxrainbowhover">test1</h1>
<h1 class="foxrainbowhover">test111</h1>
<h1 class="foxrainbowhover">test111111</h1>
This is what happens when you use asynchronous functions inside a for loop. Here are a couple of ways to fix the problem:
Use let instead of var
Create a function that uses closure and returns a new function
Use a try catch or IIFE block to create a new scope
Let
for (let index = 0; index < 5; index++) {
setTimeout(() => {
console.log(index)
}, 250);
}
Function Wrapper
for (let index = 0; index < 5; index++) {
setTimeout(getFunction(index), 250);
}
function getFunction(index) {
return function() {
console.log(index);
};
}
Try Catch Block
for (let index = 0; index < 5; index++) {
try {
throw index;
} catch (index) {
setTimeout(() => {
console.log(index);
}, 250);
}
}
IIFE Block
for (let index = 0; index < 5; index++) {
(function(index) {
setTimeout(() => {
console.log(index);
}, 250);
})(index);
}

Making an HTML page to display n rows of pascal's triangle, cannot array.push the current row to page

I am new to JavaScript, and decided to do some practice with displaying n rows of Pascal's triangle. I have everything working, and the rows are displayed in the console, however when I try to push the currentRow to the array of triangle, nothing shows up on the page. Here is how I am attempting to do so:
if (typeof currentRow !== 'undefined') {
console.log('Row ', i - 2);
currentRow = currentRow.join(' ');
console.log(currentRow);
console.log(triangle);
triangle.push('n', currentRow)
triangle = triangle.join('');
}
Any help/advice would be apreciated. I am sure this code is not that efficient (I know it is not optimal to just write out the first 3 rows). Below is a code snippet, and a jsfiddle.
https://jsfiddle.net/keuo8za0/
var row0 = [1];
var row1 = [1, 1];
var row2 = [1, 2, 1];
row0 = row0.join(' ');
row1 = row1.join(' ');
row2 = row2.join(' ');
var triangle = [row0];
triangle.push('\n', row1);
triangle.push('\n', row2);
triangle = triangle.join('');
lastRow = [1, 2, 1];
var submit = document.getElementById('submit');
function buildTriangle(pascalNumber) {
for (let i = 4; i < pascalNumber; i++) {
if (typeof currentRow !== 'undefined') {
console.log('Row ', i - 2);
currentRow = currentRow.join(' ');
console.log(currentRow);
console.log(triangle);
}
var x = i;
var currentRow = [1, 1];
for (let y = 1; y + 1 < x; y++) {
var nextNumber = (lastRow[y - 1] + lastRow[y]);
currentRow.splice(1, 0, nextNumber);
}
lastRow = currentRow;
}
}
function drawTriangle() {
document.getElementById('triangle').innerText = triangle;
}
submit.onclick = function() {
var rownum = document.getElementById('pn').value;
buildTriangle(rownum - 1);
drawTriangle();
return false;
}
body {
background: #4286f4;
font-family: arial;
}
h1 {
font-size: 36px;
text-align: center;
}
h1:hover {
color: #ff35c5;
}
form {
font: sans-serif;
text-align: center;
}
p {
font-size: 36px;
font: sans-serif;
text-align: center;
}
#map {
margin: 0 auto;
width: 80%;
height: 80%;
}
<html>
<head>
<title>Pascal's Triangle</title>
<link rel="stylesheet" href="fancy.css" />
</head>
<body>
<h1>Pascal's Triangle</h1>
<form id='numberOfRows'>
Number of Rows:<br>
<input id='pn' type='number'><br>
<button id='submit'>Submit</button>
</form>
<p id='triangle'></p>
<script src="triangler.js"></script>
</body>
</html>
Interesting... I did it row by row. Found really good help from google..
<style>
body {
background: #4286f4;
font-family: arial;
}
h1 {
font-size: 36px;
text-align: center;
}
h1:hover {
color: #ff35c5;
}
form {
font: sans-serif;
text-align: center;
}
p {
font-size: 36px;
font: sans-serif;
text-align: center;
}
#map {
margin: 0 auto;
width: 80%;
height: 80%;
}
</style>
<h1>Pascal's Triangle</h1>
<form id='numberOfRows'>
Number of Rows:<br>
<input id='pn' type='number'><br>
<button id='submit'>Submit</button>
</form>
<p id='triangle'></p>
<script>
var div = document.getElementById('triangle');
submit.onclick = function() {
div.innerHTML = "";
var rownum = document.getElementById('pn').value;
printPascal(rownum);
return false;
};
function printPascal(n) {
// Iterate through every line and
// print entries in it
for (var line=0; line < n; line++)
{
var lineHTML = "<div class='text-center'>";
// Every line has number of
// integers equal to line
// number
for (var i = 0; i <= line; i++) {
lineHTML += "" + binomialCoeff(line, i) + " ";
}
lineHTML += "</div>\n";
div.innerHTML += lineHTML;
}
}
// for details of this function
function binomialCoeff(n, k)
{
var res = 1;
if (k > n - k)
k = n - k;
for (var i = 0; i < k; ++i)
{
res *= (n - i);
res /= (i + 1);
}
return res;
}
</script>

What is the best way to give support `nth-child` in one shot to all IE version?

What is the best way to give support nth-child in one shot to all IE version?
I want to give style like this. for some particular pages.
#products tr:nth-child(even) {
background-color: red;
}
#products tr:nth-child(odd) {
background-color: white;
}
You can do it in javascript.
var table = document.getElementById('products');
var rows = table.getElementsByTagName('tr');
for (var i = 0; i < rows.length; ++i)
{
if ( (i % 2) == 0 )
{
rows[i].className = 'even';
}
}
then do your CSS like this:
#products tr td
{
background-color: white;
}
#products tr.even td
{
background-color: red;
}
If you have used a javascript library, you could have done this :
$('#products tr:even').addClass('even');
That project gives you "native" support for these and many others CSS3 selectors for at least IE7/8.
But here you'll have a problem with IE7 which doesn't support background-color for tr.
I made something that should work in every browser:
https://gist.github.com/yckart/5652296
var nthChild = function (elem, num) {
var len = elem.length;
var ret = [];
// :nth-child(num)
if (!isNaN(Number(num))) {
for (var i = 0; i < len; i++) {
if (i === num - 1) return elem[i];
}
}
// :nth-child(numn+num)
if (num.indexOf("+") > 0) {
var parts = num.match(/\w/g);
for (var i = parts[2] - 1; i < len; i += parts[0] << 0) {
if (elem[i]) ret.push(elem[i]);
}
}
// :nth-child(odd)
if (num === "odd") {
for (var i = 0; i < len; i += 2) {
ret.push(elem[i]);
}
}
// :nth-child(even)
if (num === "even") {
for (var i = 1; i < len; i += 2) {
ret.push(elem[i]);
}
}
return ret;
};
var rows = document.getElementsByTagName('li');
var num = nthChild(rows, 2);
var formula = nthChild(rows, "3n+1");
var even = nthChild(rows, "even");
var odd = nthChild(rows, "odd");
// Note, forEach needs to be polyfilled for oldIE
even.forEach(function (li) {
li.className += " even";
});
odd.forEach(function (li) {
li.className += " odd";
});
formula.forEach(function (li) {
li.className += " formula";
});
num.style.backgroundColor = "black";
You can do this in jQuery too, and they'll likely have solved your cross browser issue.
$('#products').children('tr:even').css('background-color', 'red');
$('#products').children('tr:odd').css('background-color', 'white');

Categories

Resources