Reputation: 105
So I m trying to understand JS, been doing a little JS project to learn it. Trying to make a simple calculator with javascript/html but got stuck already.
I want to get the innerHTML from all the spans in an array, but I can't figure out how to do it. (I want to use pure JavaScript). What I tried is this:
var allSpans = document.getElementsByTagName('span');
var arrayNumbers = [];
for (var i = 0; i <= allSpans.length; i++) {
arrayNumbers.push(allSpans[i].innerHTML);
}
And my html:
<!DOCTYPE html>
<html>
<head>
<meta charset=utf-8 />
</head>
<body>
<div id="calculator">
<span class="numb">1</span>
<span class="numb">2</span>
<span class="numb">3</span>
<span class="calc">x</span><br />
<span class="numb">4</span>
<span class="numb">5</span>
<span class="numb">6</span>
<span class="calc">/</span><br />
<span class="numb">7</span>
<span class="numb">8</span>
<span class="numb">9</span>
<span class="calc">√</span><br />
<span class="numb">0</span>
<span class="calc">+</span>
<span class="calc">-</span>
<span class="calc">=</span><br />
<input type="text" >
</div>
</body>
</html>
What is the best methode to use and why? Trying to learn it the proper way :) Many thanks!
Upvotes: 0
Views: 12279
Reputation: 28999
You can use Array.prototype.map()
to store the innerHTML
of your span
elements in an array:
var span = document.getElementsByTagName('span');
var span_array = [].map.call(span, function (element) {
return element.innerHTML;
});
You can optimize this procedure with ECMAScript 6 (ES6):
const span = document.getElementsByTagName('span');
let span_array = Array.from(span, element => element.innerHTML);
Note: I would personally recommend using
textContent
in conjunction with thetrim()
function rather thaninnerHTML
if you are trying to access non-HTML content inside of your tags.
Upvotes: 0
Reputation: 16706
some weeks ago i wrote a very simple calculator using a similar approach as you...
it works on mobile devices and modern browsers.
here is the css
body,html{
height:100%;
margin:0;
padding:0;
background-color:#666;
}
*{
box-sizing:border-box;
}
.clc{
width:256px;
height:320px;
clear:both;
}
.clc>*{
border:4px solid #666;
border-radius:4px;
font:normal normal bold 20px/56px Arial,Helvetica,sans-serif;
border-radius:10px;
}
.clc>input{
width:100%;
height:20%;
text-align:right;
padding:0 20px;
}
.clc>div{
width:25%;
height:20%;
background-color:#5a5a5a;
color:#fff;
text-align:center;
float:left;
}
.clc>div:nth-child(4n+1){
background-color:#f36573;
}
.clc>div:nth-last-child(1){
width:100%;
background-color:#ffb343;
}
here is the very short javascript code that does the work for you
function calc(e){
var a=e.target.innerText,b=this.firstChild;
b.value=a=='='?eval(b.value):a=='C'?'':b.value+a;
}
var gui=document.createElement('div');
gui.className='clc';
gui.innerHTML='<input><div>'+('789+456-123*C0./='.split('').join('</div><div>'))+'</div>';
gui.addEventListener('click',calc,false);
window.onload=function(){
document.body.appendChild(gui);
}
and here is a live example
if you don't understand something just ask!
UPDATE
calc explained
function calc(event){
var clickedText=event.target.innerText,// this is the clicked element inner Text
inputBox=this.firstChild; // this is the input box
if(clickedText=='='){// if the clicked text is equal symbol
inputBox.value=eval(inputBox.value); // calculate the input string by evulating it
}else{
if(clickedText=='C'){ // if clicked text is C
inputBox.value='';// clear the input box
}else{
inputBox.value=inputBox.value+clickedText; // add the clicked text
}
}
}
Upvotes: 1
Reputation: 10564
Your code is fine. Just replace i <= allSpans.length
with i < allSpans.length
.
See jsfiddle.
Array.length
returns the number of elements in an array. But remember, an array indexing starts from 0
(not just in JS but in most languages). Thus, as in your example, an array of length 16 will only have indexes up to 15. Accessing array[16]
would crash the code.
To prevent an error like this, you could use jQuery .each (but I suggest you learn standard JS first).
var array = [];
$('span').each(function () {
array.push(this.innerHTML);
});
See jsfiddle.
Upvotes: 2
Reputation: 10896
try something like this
var allSpans = document.getElementsByTagName('span');
var arrayNumbers = [];
for (var i = 0; i < allSpans.length; i++) {
arrayNumbers.push(allSpans.item(i).innerHTML);
}
The getElementsByTagName() method returns a collection of an elements's child elements with the specified tagname, as a NodeList object.
REFERENCE
https://studio.tellme.com/dom/ref/methods/getelementsbytagname.html
Upvotes: 1
Reputation: 198314
Your loop has <=
in it. allSpans
has 16 elements (0-15). When you try to access the 16th element, it is undefined
; undefined.innerHTML
throws an error; and your code stops.
Solution: Replace <=
with <
.
Also: In this particular case it doesn't matter, but if you had a button >
or &
, you would get bad results. I suggest using .textContent
instead of .innerHTML
here.
Upvotes: 1
Reputation: 74036
You almost got it, just one minor mistake: use <
instead of <=
in the for loop:
for (var i = 0; i < allSpans.length; i++) {
arrayNumbers.push(allSpans[i].innerHTML);
}
When using array indexes, they go from 0
to length - 1
(which equals an amount length
elements), so in your loop you have to make sure you do not exceed this range.
Upvotes: 1