Change style dynamically through JS

3

In a progressbar, for example, with this style:

#progress {
background: #000000;
border-radius: 13px;
height: 20px;
width: 400px;
padding: 3px;
}

#progress:after {
content: '';
display: block;
background: white;
width: 300;
height: 100%;
border-radius: 9px;
}

I need to change the fill of the bar as a function of time. In case, I need to change the progress: after width. How can I do this?

    
asked by anonymous 13.10.2015 / 07:04

2 answers

5
  

I need to change the fill of the bar as a function of time. In case, I need to change the progress: after width. How can I do this?

You can not directly change the style of a pseudo-elemento , such as :after .

However, you can add specific rules directly in browser-interpreted styles.

For this we can use the .addRule method of the CSSStyleSheet .

However, it is worth noting that this method is not supported in all browsers.

To ensure that the code works, let's create an auxiliary function responsible for verifying that the browser supports the .addRule method. If not, let's work with the direct rewriting of the CSS property we want to change.

The helper function created for the example was:

function changeRule(selector, property, value) {

    var stylesheet = document.styleSheets[0];

    if (stylesheet.addRule) {
        stylesheet.addRule(selector, property + ': ' + value);
    } else {

        var rules = stylesheet.cssRules;

        for (var i = 0; i < rules.length; i++) {
            var rule = rules[i];
            if (rule.selectorText == selector) {
                rule.style[property] = value;
            }
        }

    }

}

Here is an example of usage:

var INCREMENT_FACTOR = 25;

function changeRule(selector, property, value) {

  var stylesheet = document.styleSheets[0];

  if (stylesheet.addRule) {
    stylesheet.addRule(selector, property + ': ' + value);
  } else {

    var rules = stylesheet.cssRules;

    for (var i = 0; i < rules.length; i++) {

      var rule = rules[i];

      if (rule.selectorText == selector) {
        rule.style[property] = value;
      }

    }

  }

}

var progressInterval = setInterval(function() {

  var progress = document.getElementById('progress');

  var maximumWidth = parseInt(window.getComputedStyle(progress).getPropertyValue('width'));

  var currentWidth = parseInt(window.getComputedStyle(progress, '::after').getPropertyValue('width'));

  var newWidth = currentWidth + INCREMENT_FACTOR;

  changeRule('#progress::after', 'width', newWidth + 'px');

  if (newWidth == maximumWidth) {
    clearInterval(progressInterval);
    alert('success!');
  }

}, 500);
#progress {
  background: #000000;
  border-radius: 13px;
  height: 20px;
  width: 400px;
  padding: 3px;
}
#progress:after {
  content: '';
  display: block;
  background: white;
  width: 0;
  height: 100%;
  border-radius: 9px;
}
<div id="progress"></div>

Read more about this in Modify pseudo element styles with JavaScript .

    
13.10.2015 / 07:25
5

In HTML5 there is the tag <progress> that serves precisely for this. The difference is that, instead of modifying the width of an element, you will only have to change its value (attribute value ).

var $progress = document.querySelector('progress'), // Pegando o elemento
    MAXIMUM   = $progress.max;                      // Pegando o valor máximo: 100

/* Aumentando o valor a cada 1 segundo para exemplificar... */
var interval = setInterval(function(){
  $progress.value++;
  if($progress.value >= MAXIMUM)
    clearInterval(interval);
}, 100);
<progress max='100' value='0'></progress>

You can also customize it just like any other HTML element. The difference is that because the properties are not standardized, you will have to look for properties and prefixes to change the appearance:

.custom {
  background-color: #ecf0f1;
  border: 1px solid #ecf0f1;
  height: 10px
}

/* cor de background da barra */
.custom::-webkit-progress-bar {
  background-color: #fff
}

/* cor de background do valor de progresso */
.custom::-webkit-progress-value {
  background-color: #9b59b6
}

.custom::-moz-progress-bar {
  background-color: #9b59b6
}
<h4>Default:</h4>
<progress max='100' value='50'></progress>

<h4>Customizada:</h4>
<progress class='custom' max='100' value='75' data-value=''></progress>
    
13.10.2015 / 07:43