返回CSS宽度作为公式而不是计算值

时间:2018-06-25 17:21:49

标签: javascript jquery css css3

我的css的编码方式是 point 类始终是div的50%。每当我使用css。('width')时,它都会向我返回计算值。有什么办法将宽度返回为“ calc(100%/ 2)”?

css

.point{width:calc(100%/2)}

JavaScript

var myPoint = document.getElementsByClassName('point');
console.log($(myPoint).css('width'));

1 个答案:

答案 0 :(得分:1)

正如其他人在评论中提到的那样,它需要一些复杂的CSS解析才能弄清楚哪些规则应用了所讨论的元素。这个解决方案不是完美的,但是它解析元素的CSS样式并确定最具体的规则,然后返回其值。请注意,它不一定保留样式的原始格式...颜色从十六进制转换为rgb。但是它确实保留了单位和计算值的定义。

此外,性能极有可能是残酷的,我没有以任何方式对此进行优化。

HTMLElement.prototype.getCSSPropertyAsAuthored = (function(){
  var extractRule = function(cssText){
    return cssText.split('{').shift();
  }
  var extractStyle = function(cssText){
    var match = cssText.match(/[^{]+\{([^}]*)\}/)
    if(match){
      return match[1];
    }
    return '';
  }
  var shouldKeepRule = function(selector, styles, property){
    if(selector.substr(0,1) == '@')
      return false;
    if(styles.indexOf(property+':') == -1)
      return false;
    return true;
  }
  var getAllPotentialRules = function(property){
    var css = [];
    for (var i=0; i<document.styleSheets.length; i++){
        var sheet = document.styleSheets[i];
        var rules = ('cssRules' in sheet)? sheet.cssRules : sheet.rules;
        if (rules){
            for (var j=0; j<rules.length; j++){
                var rule = rules[j];
                var cssText = !!('cssText' in rule)
                var selectors = (cssText ? extractRule(rule.cssText) : rule.selectorText).split(',');
                var styles = cssText ? extractStyle(rule.cssText) : rule.style.cssText;
                for(var selector of selectors){
                  if(shouldKeepRule(selector, styles, property)){
                    var nodes = document.querySelectorAll(selector);
                    if(Array.prototype.indexOf.apply(nodes, [this]) > -1){
                      css.push({selector: selector, style: styles})
                    }
                  }
                }
            }
        }
     }
     return css;
  }
  
  var extractMostSpecificStyle = function(styles, property){
    if(!styles.length) return null;
    var match, re = new RegExp('(^|;)\\s*'+property+':([^;]+);?'), count = 0;
    for(var style of styles){
      style.value = '';
      style.count = count++;
      style.ownStyle = style.selector===''?1:0;
      style.tagCount = (match=style.selector.match(/(^|[\s>]|:not\()[a-zA-z-]+/gi))?match.length:0;
      style.classCount = (match=style.selector.match(/\./gi))?match.length:0;
      style.idCount = (match=style.selector.match(/#/gi))?match.length:0;
      if(match=style.style.match(re)){
        style.value = match[2].trim();
      }
      style.important = style.value.indexOf('!important') > -1 ? 1 : 0;
    }
    styles.sort(function(a,b){
      if(a.important != b.important) return b.important - a.important;
      if(a.ownStyle != b.ownStyle) return b.ownStyle - a.ownStyle;
      if(a.idCount != b.idCount) return b.idCount - a.idCount;
      if(a.classCount != b.classCount) return b.classCount - a.classCount;
      if(a.tagCount != b.tagCount) return b.tagCount - a.tagCount;
      return b.count - a.count;
    });
    return styles[0].value;
  }  
  
  return function(property){
    if(!property) return null;
    property = property.toLowerCase();
    
    var styles = getAllPotentialRules.apply(this, [property]);
    var styleValue = this.getAttribute('style');
    if(shouldKeepRule('', styleValue||'', property)){
      styles.push({selector: '', style: styleValue})
    }
    return extractMostSpecificStyle(styles, property);
  }
})();

var test = document.getElementById('test');
console.log(test.getCSSPropertyAsAuthored('width'));
console.log(test.getCSSPropertyAsAuthored('background-color'));
console.log(test.getCSSPropertyAsAuthored('border'));
<style>
.point {
  border: 1px solid red;
  width: 100%;
  background-color: #ccc;
}
#test {
  background-color: #eee;
}
div > div {
  border: 1px solid blue !important;
}
</style>

<div>
  <div id="test" class="point" style="width:calc(100%/2);">Point</div>
</div>