Modify <span/> text depending on class names JAVASCRIPT - NO jQUERY - javascript

What I'm trying to do is write a function that will iterate over all different html elements which have a class name beginning with rnum- followed by a number. A complete example of a span would be <span class="rnum-293"></span>.
I then want to implement the function that I have written below and have it do the increasing effect up to each of their given numbers(specified in the class name).
Does anyone have an idea how I can achieve this? Thanks!
var count = 0;
var target = 126;
var increment = target / 198;
var elements = document.getElementsByClassName('rnum');
function calc() {
if(count < target) {
count += increment;
}
for(var i = 0; i < elements.length; i++) {
elements[i].innerHTML = Math.round(count);
}
}
setInterval(calc, 10)
#import url('https://fonts.googleapis.com/css?family=Bangers');
body {
font-family: 'Bangers';
display: flex;
align-items: center;
justify-content: center;
}
.rnum {
font-size: 55px;
margin: 50px;
}
<span class="rnum"></span>
<span class="rnum"></span>
<span class="rnum"></span>

To select the elements, use:
var elements = document.querySelectorAll('[class^="rnum-"]');
Or, if only span elements, use:
var elements = document.querySelectorAll('span[class^="rnum-"]');
I am unsure about the second part of your question. For all I see, the only issue was selecting the elements.
For the second part:
JavaScript:
var elements = document.querySelectorAll('span[class^="rnum-"]');
function calc() {
var el = null;
var val = 0;
var currentValue = 0;
var incrementFactor = 198;
var increment = 0;
var maxValue = 0;
for (var i = 0, len = elements.length; i < len; i++) {
el = elements[i];
maxValue = Number(el.getAttribute('data-max-val'));
currentValue = Number(el.getAttribute('data-current-val'));
increment = maxValue / incrementFactor;
if ((currentValue + increment) > maxValue)
continue;
val = currentValue + increment;
el.innerHTML = Math.round(val);
el.setAttribute('data-current-val', Math.round(val));
}
}
setInterval(calc, 10)
HTML:
<span class="rnum-198000" data-current-val="0" data-max-val="198000">0</span>
<span class="rnum-299000" data-current-val="0" data-max-val="299000">0</span>
<span class="rnum-399000" data-current-val="0" data-max-val="399000">0</span>
<span class="rnum-499000" data-current-val="0" data-max-val="499000">0</span>
Pen: http://codepen.io/anon/pen/rjyqMd?editors=1111

Related

CSS formatting doesn't apply to new tags created by Javascript

I wrote a bunch of JS code to add click listeners to the HTML buttons. I have some CSS that applies to the existing HTML. But the CSS doesn't appear to apply to the HTML generated by the JavaScript.
Link to JSfiddle
As you can see, line 1 has all the proper spacing. But any of the generated lines by clicking any of the three buttons lose the spacing.
Here's the CSS:
.form-block {
padding: 5px;
margin: 5px;
border: 1px solid #000;
span {
padding-right: 15px;
}
}
Thanks for the help in advance! :)
What you see are actual spaces between the elements in your original HTML/row, and then a lack of spaces between the elements in your JS generated elements.
I would either remove the spaces between the elements in your HTML, and use a left/right margin value to create that space instead, or add a space or carriage return/new line between the elements when you add them in your JS.
I removed the spaces (by inserting HTML comments) in your original HTML, and added margin-right: 1em to the input and buttons in your element row.
/*This function interprets the line position.
//input is a lpos string which is in the form of x.x.x.x
//splits it by the '.'
//returns the array with position
*/
function lposToAr(lpos) {
var ar = lpos.split('.');
for (var i = 0; i < ar.length; i++) {
ar[i] = parseInt(ar[i], 10);
}
return ar;
}
//This function turns the position array back into a string
function lposToStr(posAr) {
return posAr.join('.');
}
//This function creates a new line after clicking the NL button.
function NL(lpos, e) {
e.preventDefault();
var cLine = document.getElementsByClassName('line')[0].cloneNode(true);
var cNL = document.getElementsByClassName('new-line')[0].cloneNode(true);
var cNN = document.getElementsByClassName('new-nested')[0].cloneNode(true);
var cI = document.getElementsByClassName('input')[0].cloneNode(true);
cI.value = '';
var cNI = document.getElementsByClassName('new-input')[0].cloneNode(true);
//figure out which position
var posAr = lposToAr(lpos);
var clickNode = document.getElementsByTagName('form')[0];
for (var i = 0; i < posAr.length; i++) {
clickNode = clickNode.children;
var skipCount = 0;
for (var j = 0; j < clickNode.length - 1; j++) {
if (clickNode[j].tagName != 'DIV') {
skipCount++;
}
}
clickNode = clickNode[posAr[i] + skipCount - 1];
}
//set the last element of the posAr the total number of same level <div>+1
var siblingDivCount = 0;
for (var i = 0; i < clickNode.parentNode.children.length; i++) {
if (clickNode.parentNode.children[i].tagName == 'DIV') {
siblingDivCount++;
}
}
var newPosAr = posAr;
newPosAr[newPosAr.length - 1] = siblingDivCount + 1;
//Update the cloned items with the new line info
var newPosStr = lposToStr(newPosAr);
cLine.innerHTML = newPosStr;
cNL.addEventListener('click', function(event) {
NL(newPosStr, event);
});
cNN.addEventListener('click', function(event) {
NN(newPosStr, event);
});
//cI doesn't need to change, unless there's a bug
cNI.addEventListener('click', function(event) {
NI(newPosStr, event);
});
//Make the new Div
var newDiv = document.createElement('div');
newDiv.setAttribute('class', 'form-block');
newDiv.appendChild(cLine);
newDiv.appendChild(cNL);
newDiv.appendChild(cNN);
newDiv.appendChild(cI);
newDiv.appendChild(cNI);
//Add the new Div
clickNode.parentNode.appendChild(newDiv);
}
function NN(lpos, e) {
e.preventDefault();
var cLine = document.getElementsByClassName('line')[0].cloneNode(true);
var cNL = document.getElementsByClassName('new-line')[0].cloneNode(true);
var cNN = document.getElementsByClassName('new-nested')[0].cloneNode(true);
var cI = document.getElementsByClassName('input')[0].cloneNode(true);
cI.value = '';
var cNI = document.getElementsByClassName('new-input')[0].cloneNode(true);
var posAr = lposToAr(lpos);
var clickNode = document.getElementsByTagName('form')[0];
for (var i = 0; i < posAr.length; i++) {
clickNode = clickNode.children;
var skipCount = 0;
for (var j = 0; j < clickNode.length - 1; j++) {
if (clickNode[j].tagName != 'DIV') {
skipCount++;
}
}
clickNode = clickNode[posAr[i] + skipCount - 1];
}
var childDivCount = 0;
for (var k = 0; k < clickNode.children.length; k++) {
if (clickNode.children[k].tagName == 'DIV') {
childDivCount++;
}
}
posAr.push(childDivCount + 1);
//Update the cloned items with the new line info
var newPosStr = lposToStr(posAr);
cLine.innerHTML = newPosStr;
cNL.addEventListener('click', function(event) {
NL(newPosStr, event);
});
cNN.addEventListener('click', function(event) {
NN(newPosStr, event);
});
//cI doesn't need to change, unless there's a bug
cNI.addEventListener('click', function(event) {
NI(newPosStr, event);
});
//Make the new Div
var newDiv = document.createElement('div');
newDiv.className = 'form-block';
newDiv.appendChild(cLine);
newDiv.appendChild(cNL);
newDiv.appendChild(cNN);
newDiv.appendChild(cI);
newDiv.appendChild(cNI);
//Add the new Div
clickNode.appendChild(newDiv);
}
function NI(lpos, event) {
event.preventDefault();
//copy text box
var cI = document.getElementsByClassName('input')[0].cloneNode(true);
cI.value = '';
//find the node that has been clicked
var posAr = lposToAr(lpos);
var clickNode = document.getElementsByTagName('form')[0];
for (var i = 0; i < posAr.length; i++) {
clickNode = clickNode.children;
var skipCount = 0;
for (var j = 0; j < clickNode.length - 1; j++) {
if (clickNode[j].tagName != 'DIV') {
skipCount++;
}
}
clickNode = clickNode[posAr[i] + skipCount - 1];
}
//add the new textbox
clickNode.insertBefore(cI, clickNode.getElementsByClassName('new-input')[0]);
}
document.getElementsByClassName('new-line')[0].addEventListener('click', function(event) {
NL(document.getElementsByClassName('line')[0].innerHTML, event);
});
document.getElementsByClassName('new-nested')[0].addEventListener('click', function(event) {
NN(document.getElementsByClassName('line')[0].innerHTML, event);
});
document.getElementsByClassName('new-input')[0].addEventListener('click', function(event) {
NI(document.getElementsByClassName('line')[0].innerHTML, event);
});
/**
* Add styling to the form to make it look appealing
*/
.form-block {
padding: 5px;
margin: 5px;
border: 1px solid #000;
}
span {
padding-right: 15px;
}
.form-block button, .form-block input {
margin-right: 1em;
}
<!--
DO NOT CHANGE THE CONTENTS OF THIS BLOCK
-->
<form class='myform'>
<div class='form-block'>
<span class='line'>1</span><!--
--><button class='new-line'>New Line</button><!--
--><button class='new-nested'>New Nested Line</button><!--
--><input class='input' type='text' placeholder='Enter Value...'><!--
--><button class='new-input'>Add input</button>
</div>
</form>

Change background color of Div to value of variable using Javascript

I have been trying to change the color of a div to a randomly generated hex color code which is passed into a variable. How do I make this work?
HTML
<p id="demo">NULL</p>
<button onclick="generatePassword()">Generate</button>
<div id="showcase" style="background: #FFFFFF; width: 200px; height: 200px; margin: 20px; border-radius: 3px;"></div>
JAVASCRIPT
var result = document.getElementById('demo').innerHTML;
function generatePassword() {
var length = 6,
charset = "ABCDEF0123456789",
retVal = "";
for (var i = 0, n = charset.length; i < length; ++i) {
retVal += charset.charAt(Math.floor(Math.random() * n));
}
document.getElementById('demo').innerHTML = "#" + retVal;
return document.getElementById('showcase').style.backgroundColor = retVal;
}
Link to fiddle: https://jsfiddle.net/elliotsoomro/gngg89t5/5/
You've almost got it, here's the fix: https://jsfiddle.net/yL1uu6bz/1/
var result = document.getElementById('demo').innerHTML;
function generatePassword() {
var length = 6,
charset = "ABCDEF0123456789",
retVal = "";
for (var i = 0, n = charset.length; i < length; ++i) {
retVal += charset.charAt(Math.floor(Math.random() * n));
}
var finalVal = "#" + retVal;
document.getElementById('demo').innerHTML = finalVal;
return document.getElementById('showcase').style.backgroundColor = finalVal;
}
I simply added the hash symbol and appended it in the same way you've already done for outputting the value ("#" + retVal), I added this in a variable (finalVal) and output it instead.

Continuously create div's

I want to create div continuously and it should come on the next line if it reaches the outer div's width in JavaScript without using canvas and float.
for(i = 0; i < 20; i++) {
var ind = (Math.round(Math.random(0,2)*2));
var child = document.createElement("div");
child.setAttribute("id","div"+i);
child.style.backgroundColor=colors[ind];
maindiv.appendChild(child);
}
You can use display: inline-block; css property. Refer this
var maindiv = document.getElementById('parent');
for (var i = 0; i < 100; i++) {
var ind = (Math.round(Math.random(0, 2) * 2));
var child = document.createElement("div");
child.setAttribute("id", "div" + i);
child.setAttribute("class", "inline");
child.innerText = 'div';
//child.style.backgroundColor = colors[ind];
maindiv.appendChild(child);
}
.inline {
display: inline-block;
}
<div id="parent"></div>

JavaScript increase and decrease font size

I am new to JavaScript. I would like to add to add two buttons for my visitors to control font size. I would like to include two tags - 'p' and 'blockquote". Can you please help me edit this code in order to include both?
var min = 8;
var max = 18;
function increaseFontSize() {
var p = document.getElementsByTagName('p');
for (i = 0; i < p.length; i++) {
if (p[i].style.fontSize) {
var s = parseInt(p[i].style.fontSize.replace("px", ""));
} else {
var s = 12;
} if (s != max) {
s += 1;
}
p[i].style.fontSize = s + "px"
}
}
function decreaseFontSize() {
var p = document.getElementsByTagName('p');
for (i = 0; i < p.length; i++) {
if (p[i].style.fontSize) {
var s = parseInt(p[i].style.fontSize.replace("px", ""));
} else {
var s = 12;
} if (s != min) {
s -= 1;
}
p[i].style.fontSize = s + "px"
}
}
Thank you.
Here's a working version:
http://jsfiddle.net/ny4p7pg9/
I took the liberty of refactoring a bit the functions to make the code more parameterized.
function changeFontSize(delta) {
var tags = document.querySelectorAll('p,blockquote');
for (i = 0; i < tags.length; i++) {
if (tags[i].style.fontSize) {
var s = parseInt(tags[i].style.fontSize.replace("px", ""));
} else {
var s = 12;
} if (s != max) {
s += delta;
}
tags[i].style.fontSize = s + "px"
}
}
function increaseFontSize() {
changeFontSize(1);
}
function decreaseFontSize() {
changeFontSize(-1);
}
Instead of using:
p = document.getElementsByTagName('p');
you could, instead use:
elems = document.querySelectorAll('p, blockquote');
(the variable name is irrelevant, and was changed only because the elements are no longer exclusively <p> elements):
function increaseFontSize() {
var elems = document.querySelectorAll('p, blockquote');
for (i = 0; i < elems.length; i++) {
if (elems[i].style.fontSize) {
var s = parseInt(elems[i].style.fontSize.replace("px", ""));
} else {
var s = 12;
} if (s != max) {
s += 1;
}
elems[i].style.fontSize = s + "px"
}
}
var min = 8;
var max = 18;
function increaseFontSize() {
var elems = document.querySelectorAll('p, blockquote');
for (i = 0; i < elems.length; i++) {
if (elems[i].style.fontSize) {
var s = parseInt(elems[i].style.fontSize.replace("px", ""));
} else {
var s = 12;
} if (s != max) {
s += 1;
}
elems[i].style.fontSize = s + "px"
}
}
function decreaseFontSize() {
var elems = document.querySelectorAll('p, blockquote');
for (i = 0; i < elems.length; i++) {
if (elems[i].style.fontSize) {
var s = parseInt(elems[i].style.fontSize.replace("px", ""));
} else {
var s = 12;
} if (s != min) {
s -= 1;
}
elems[i].style.fontSize = s + "px"
}
}
document.querySelector('#increase').addEventListener('click', increaseFontSize);
document.querySelector('#decrease').addEventListener('click', decreaseFontSize);
<button id="increase">↑A</button>
<button id="decrease">A↓</button>
<p>Some text to have its text adjusted by the buttons just up there.</p>
<blockquote>Some text in a blockquote</blockquote>
The querySelectorAll() method accepts CSS-style selectors, and returns a (non-live) NodeList, and is supported in all modern browsers, including IE from version 8 onwards.
That said, it's probably better to increase the font-size of the <body> element, otherwise font-adjustment is redundant (since other elements will still be unclear), so, instead, I'd suggest:
function increaseFontSize() {
// retrieving, and caching, the <body> element:
var body = document.body,
// finding the current computed fontSize of the <body> element, parsing it
// as a float (though parseInt() would be just as safe, really):
currentFontSize = parseFloat(window.getComputedStyle(body, null).fontSize);
// if the currentFontSize is less than the specified max:
if (currentFontSize < max) {
// we set the fontSize of the <body> to the incremented fontSize,
// increasing the current value by 1, and concatenating with the 'px' unit:
body.style.fontSize = ++currentFontSize + 'px';
}
}
function decreaseFontSize() {
var body = document.body,
currentFontSize = parseFloat(window.getComputedStyle(body, null).fontSize);
if (currentFontSize > min) {
body.style.fontSize = --currentFontSize + 'px';
}
}
var min = 8;
var max = 18;
function increaseFontSize() {
var body = document.body,
currentFontSize = parseFloat(window.getComputedStyle(body, null).fontSize);
if (currentFontSize < max) {
body.style.fontSize = ++currentFontSize + 'px';
}
}
function decreaseFontSize() {
var body = document.body,
currentFontSize = parseFloat(window.getComputedStyle(body, null).fontSize);
if (currentFontSize > min) {
body.style.fontSize = --currentFontSize + 'px';
}
}
document.querySelector('#increase').addEventListener('click', increaseFontSize);
document.querySelector('#decrease').addEventListener('click', decreaseFontSize);
<button id="increase">↑A</button>
<button id="decrease">A↓</button>
<p>Some text to have its text adjusted by the buttons just up there.</p>
<blockquote>Some text in a blockquote</blockquote>
References:
document.body.
document.querySelectorAll().
Window.getComputedStyle().

JS OOP - multiple timer created by object but only one works

This js is to create "lyricLine" and showing strings on random position of the page.
While creating an object of oLyricLine and calling drawText, it supposed to display each string of array lyricLines one by one until last line is shown. When last line is time-out, the timer should stop and the created div.lyricline should be deleted.
While different objects are created, (in this case LyricGen1 and LyricGen2) their timer should be ticking simultaneously.
But currently only timer of LyricGen2 is working.
Code is attached below.
<script src="jquery-min.js"></script>
<div id="container">
<div class="lyricline" id="0">
demo
</div>
</div>
<style>
body{
background: #000;
color: #fff;
font-family: sans-serif;
}
#container{
position: relative;
width: 100%;
height: 100%;
}
.lyricline{
position: absolute;
text-align: center;
}
</style>
<script>
var idarray = [];
//Object oLyricLine
function oLyricLine(obj){
this.lyricLines = [];
this.textSize = 30;
this.toppx = -1;
this.leftpx = -1;
this.unixtime = -1;
this.widthpx = -1;
this.colorhex = "#fff";
this.obj = obj;
}
oLyricLine.prototype.drawText = function(){
if (this.toppx != -1 && this.leftpx != -1 && this.unixtime != -1 && this.widthpx != -1){
var transitionInTime = 10;
var transitionOutTime = 10;
var tickfactor = 5;
$("#"+this.unixtime).css({
"color": this.colorhex,
"left": this.leftpx,
"top": this.toppx,
"width": this.widthpx,
"font-size":this.textSize
}).attr({"class":"lyricline","id":this.unixtime}).text(this.lyricLines[0]);
var tickCount = 0;
lyricLinesCount = 0;
var lyricLinesTick = [];
for (var i =0; i <= this.lyricLines.length - 1; i++) {
lyricLinesTick[i] = this.lyricLines[i].length * tickfactor;
if(i>0){lyricLinesTick[i]+=lyricLinesTick[i-1];}
};
var nLyricLines = this.lyricLines;
var nUnixtime = this.unixtime;
idarray[nUnixtime] = setInterval(function () {
tickCount += 1;
if (tickCount == lyricLinesTick[lyricLinesCount]){
lyricLinesCount +=1;
if(lyricLinesCount != lyricLinesTick.length){
$("#"+nUnixtime).text(nLyricLines[lyricLinesCount]);
}else{
$("#"+nUnixtime).remove();
clearInterval(idarray[nUnixtime]);
}
}
},100);
}
};
oLyricLine.prototype.widthGen = function() {
this.widthpx = maxWidth(this.lyricLines, this.textSize);
};
var unixtime1=Date.now();
$("#container").append($("<div></div>").attr("id",unixtime1));
var obj1=$("#"+unixtime1);
var LyricGen1 = new oLyricLine(obj1);
LyricGen1.lyricLines = ["gen1 line1","1.line2","1-------LINE#3"];
LyricGen1.textSize = 50;
LyricGen1.toppx = Math.floor(Math.random()*($(window).height()-LyricGen1.textSize));
LyricGen1.widthGen();
LyricGen1.leftpx = Math.floor(Math.random()*($(window).width()-parseInt(LyricGen1.widthpx)));
LyricGen1.unixtime = unixtime1;
LyricGen1.drawText();
$("#container").append($("<div></div>").attr("id","Datenow"));
var obj2=$("#Datenow");
var LyricGen2 = new oLyricLine(obj2);
LyricGen2.lyricLines = ["2.1","TWO=two","2........3","gen2 line number 4","2>>line5"];
LyricGen2.textSize = 80;
LyricGen2.toppx = Math.floor(Math.random()*($(window).height()-LyricGen1.textSize));
LyricGen2.widthGen();
LyricGen2.leftpx = Math.floor(Math.random()*($(window).width()-parseInt(LyricGen1.widthpx)));
LyricGen2.unixtime = "Datenow";
LyricGen2.drawText();
function strlen(str){ var len = 0; for (var i=0; i<str.length; i++) { var c = str.charCodeAt(i); if ((c >= 0x0001 && c <= 0x007e) || (0xff60<=c && c<=0xff9f)) { len++; } else { len+=2; } } return len; }
function maxWidth (lyricLines, textSize) {
var maxStringLength=0, maxStringId=-1;
for (var i = lyricLines.length - 1; i >= 0; i--) {
if (maxStringLength < strlen(lyricLines[i])){
maxStringLength = strlen(lyricLines[i]);
maxStringId = i;
};
};
$("#container").append($("<div></div>").css({
"background":"#fff",
"color":"#000",
"visibility":"hidden",
"font-size":textSize
}).attr({"class":"lyricline","id":"widgen"}).text(lyricLines[maxStringId]));
var maxPxLength = $("#widgen").css("width");
$("#widgen").remove();
return maxPxLength;
}
</script>
lyricLinesCount = 0;
You're missing a var here, making lyricLinesCount an implicit global variable. You want to have it local to each timer, though.

Categories