Un1
Un1

Reputation: 4132

How to change value of each html element with a specified class?

I have a list of elements, each of them has a span element with class size, I want to convert each one of them to readable value (bytes => kb, mb, etc.) I'm not sure how to update those values on the page.

Codepen: https://codepen.io/x84733/pen/GGGEzx?editors=1010

function formatBytes(bytes,decimals) {
    if(bytes == 0) return '0 Bytes';
    var k = 1024,
        dm = decimals || 2,
        sizes = ['Bytes', 'KB', 'MB', 'GB', 'TB', 'PB', 'EB', 'ZB', 'YB'],
        i = Math.floor(Math.log(bytes) / Math.log(k));
    return parseFloat((bytes / Math.pow(k, i)).toFixed(dm)) + ' ' + sizes[i];
}


var size = document.getElementsByClassName("size");


function updateValue(v){
    size.innerHTML = formatBytes(v);
}


for (var i = 0; i < size.length; i++) {
    updateValue(size.item(i));
}
<ul>
  <li><span class="size">875</span></li>
  <li><span class="size">25984</span></li>
  <li><span class="size">12525125</span></li>
  <li><span class="size">23234</span></li>
  <li><span class="size">325235</span></li>
  <li><span class="size">0</span></li>
  <li><span class="size"></span></li>
</ul>

Upvotes: 0

Views: 46

Answers (2)

mooga
mooga

Reputation: 3307

You just need First: pass the position of the item in the list Second: you apply the method on the item itself but you need to do on the innerHTML

function updateValue(v, i){
     size.item(i).innerHTML = formatBytes(parseFloat(v.innerHTML));
}

        function formatBytes(bytes,decimals) {
            if(bytes == 0) return '0 Bytes';
            var k = 1024,
                dm = decimals || 2,
                sizes = ['Bytes', 'KB', 'MB', 'GB', 'TB', 'PB', 'EB', 'ZB', 'YB'],
                i = Math.floor(Math.log(bytes) / Math.log(k));
            return parseFloat((bytes / Math.pow(k, i)).toFixed(dm)) + ' ' + sizes[i];
        }

        
        var size = document.getElementsByClassName("size");


        function updateValue(v, i){
            if(v.innerHTML.length > 0){
            size.item(i).innerHTML = formatBytes(parseFloat(v.innerHTML));
}
        }


        for (var i = 0; i < size.length; i++) 
        {
            updateValue(size.item(i), i);
        }
        <ul>
          <li><span class="size">875</span></li>
          <li><span class="size">25984</span></li>
          <li><span class="size">12525125</span></li>
          <li><span class="size">23234</span></li>
          <li><span class="size">325235</span></li>
          <li><span class="size">0</span></li>
          <li><span class="size"></span></li>
        </ul>

Upvotes: 1

T.J. Crowder
T.J. Crowder

Reputation: 1074198

What you're passing to formatBytes is the span element, not its content. You're also trying to set innerHTML on size (which is an HTMLCollection), not on the element you passed (v). Instead:

function updateValue(span) {
    span.innerHTML = formatBytes(parseFloat(span.innerHTML));
}

Or you might use textContent rather than innerHTML.

A couple of side notes:

  • You can use size[i] rather than size.item(i). The old item function is a bit archaic.

  • You never need to call parseFloat on the result of /, the result of / is already always a number.

  • Strongly recommend naming variables containing lists, arrays, collections, etc. in the plural. E.g., sizeSpans or similar, not size.

  • If you need to support IE8 (hopefully you don't), it doesn't have getElementsByClassName but it does have querySelectorAll which is more general-purpose (accepts any valid CSS selector): var size = document.querySelectorAll(".size").

  • Similarly, if you need to support IE8, be aware it doesn't have textContent.

Upvotes: 2

Related Questions