2012-12-24 127 views
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? 

Update2!如果我使用new Function("a", "b", "return (%%Expression%%)")而不是eval,會發生什麼?

例如:

var operation = "90% - 10"; 

要:

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

如何做呢?

+2

爲什麼你不使用'var anything =(canvas.width *(percent/100))+ somenumber;'? – 2012-12-24 12:27:56

回答

0

例如,

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

如果你的表情始終如表格xxx% + 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..... 
1

可以使用替代和簡單的墊子規則,

寬度實際上是100%(100/100 *寬度),所以你可以做下面的事情。

function batch(calcStr, objWidth) 
{ 
calcStr = calcStr.replace("%", "/100*" + objWidth); 
var newWidth = eval(calcStr); 
// The + 10 or -1 are already there... 
} 
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; 
    } 
} 
+0

+1不使用eval。 – 2012-12-24 12:36:33

0

如果你真的要來計算,你可以使用正則表達式搜索隨後百分號若干所有出現:

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

這會給你整個匹配(30%),爲米[0]和 只是數字(30)m 1

你可以用這個方法來計算新值

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

,然後更換爲真實的,EVAL產生的 mathemtatical表達。

查看this jsfiddle的工作示例。

但是!

評估和表達,可能是用戶輸入 在某個時候打開安全的整個主題...所以你認爲真的,真的,真的很難如何避免 這種情況。

我的猜測

你要這麼麻煩,因爲你想要做一些 計算CSS佈局。因此,這裏是我給的建議,你會如何避免計算 :

1)盒大小:邊界盒

經典盒模型使得它幾乎不可能做的東西一樣 「分裂這個div分成三個相等的列,每個邊界爲1px「。

考慮新的「邊界框」,它使這個非常簡單:用邊界框 填充+邊框算作寬度的一部分,所以

width: 30% 
    border: 1px; 

實際上增加高達100%。

請參閱Paul Irish's article瞭解更多詳細說明。

2)CSS預處理程序像SASS以下

,如果你想要做你的CSS的計算,你可以使用一個 預處理來爲你做的。無論SASSLESS 支持變量和數學表達式,在語法上的些許差異 :

padding: $x/2; 

    padding: (@x/2); 

你就在那兒:一個方式來實現你想要的東西,而兩種方式,以避免它。