2

我需要转换"100% - 1"300 - 1哪里 300 - 画布宽度?如何评估(批处理)此操作?

//for example:
var value = batch("100% - 1", canvas.width); //Must 299, because canvas.width is 300
var secondary = batch("50% + 10", canvas.width); //Must 160
//where first argument - arithmetic operation, second - relativity value.

这个问题不属于科幻小说的范畴,而是一个非常严肃和现实的问题。

更新!但如果只需要转换百分比?

var value = hack("75%", 300); //Must 255
var operation = hack("30%", 100) + 10; //Must 40
var end = hack("1em", somearg); //EM?

更新2!什么意志,如果我使用new Function("a", "b", "return (%%Expression%%)")而不是eval

例如:

var operation = "90% - 10";

至:

new Function("a", "return ((a * 90 / 100) - 10)");

怎么做到的?

4

4 回答 4

2

如果批次中有两个部分,第一个总是一个百分比,第二个是一个值,那么你可以这样做

function batch(operation, value){
    var values = operation.match(/\d+|[+-/*]/g),
        percent = parseFloat(values[0])/100,
        relative = parseFloat(values[2]),
        math = values[1],
        applied = percent*value;

     switch(math){
         case '+': return applied + relative; 
         case '-': return applied - relative;
         case '/': return applied / relative;
         case '*': return applied * relative;
     }
}
于 2012-12-24T12:35:39.200 回答
1

您可以使用替换和简单的垫子规则,

100% 的宽度实际上是 (100 / 100 * width) 所以你可以做以下事情。

function batch(calcStr, objWidth)
{
calcStr = calcStr.replace("%", "/100*" + objWidth);
var newWidth = eval(calcStr); 
// The + 10 or -1 are already there...
}
于 2012-12-24T12:32:37.267 回答
0

如果你真的想计算它,你可以使用正则表达式来搜索所有出现的数字,后跟百分号:

expression = "30% + 10";
m = /(\d+)%/.exec( expression );

这将为您提供整个匹配(30%)为 m[0] 和数字(30)为 m 1

您可以使用它来计算新值

v = width_100_percent * parseInt(m[1]) / 100;

然后将其替换为真实的,并评估生成的数学表达式。

有关工作示例,请参阅此 jsfiddle 。

但!

在某些时候可能是用户输入的评估和表达打开了整个安全主题......所以你应该认真考虑如何避免这种情况。

我猜

您将遇到所有这些麻烦,因为您想对 CSS 布局进行一些计算。所以这是我对如何避免计算的建议:

1) box-sizing: 边框框

经典的盒子模型几乎不可能做到“将这个 div 分成三个相等的列,每个列的边框为 1px”。

看看新的“边框框”,它使这变得非常简单:使用边框框,填充+边框计为宽度的一部分,所以

  width: 30%
  border: 1px;

实际上加起来是100%。

有关更详细的解释,请参阅Paul Irish 的文章。

2) CSS 预处理器,如 SASS 或 LESS

如果你想在你的 CSS 中进行计算,你可以使用预处理器来为你做这件事。SASSLESS都 支持变量和数学表达式,语法略有不同:

  padding: $x / 2;

  padding: (@x / 2);

所以你有:一种实现你想要的方法,以及两种避免它的方法。

于 2012-12-24T13:05:44.973 回答
0

例如,

expr = expr.replace(/(\d+)%/g, function($0, $1) { return width * parseInt($1) / 100 })
result = eval(expr)

如果你的表达总是 if formxxx% + yyy你也可以在没有eval:

expr = expr.replace(/(\d+)%/g, function($0, $1) { return width * parseInt($1) / 100 })
result = expr.replace(/(\d+)\s*([+-*/])\s*(\d+)/g, function($0, $1, $2, $3) { 
    $1 = parseInt($1);
    $3 = parseInt($3);
    switch($2) {
        case '+': return $1 + $2;
        etc.....
于 2012-12-24T12:31:20.200 回答