问题
I am trying to create a simple calculator for chrome. I need to use eval() to evaluate the expression,but it is banned by chrome. Any workarounds? Here is the js. Can anyone give a solution to this? I have looked everywhere.
var text = document.getElementById("tBox");
var x = 0;
var y = 0;
var op = "";
var resetFlag = 0;
document.getElementById("buttonbackspace").addEventListener("click",function(){backspace()});
document.getElementById("buttonone").addEventListener("click",function(){addDigit(1)});
document.getElementById("buttontwo").addEventListener("click",function(){addDigit(2)});
document.getElementById("buttonthree").addEventListener("click",function(){addDigit(3)});
document.getElementById("buttonfour").addEventListener("click",function(){addDigit(4)});
document.getElementById("buttonfive").addEventListener("click",function(){addDigit(5)});
document.getElementById("buttonsix").addEventListener("click",function(){addDigit(6)});
document.getElementById("buttonseven").addEventListener("click",function(){addDigit(7)});
document.getElementById("buttoneight").addEventListener("click",function(){addDigit(8)});
document.getElementById("buttonnine").addEventListener("click",function(){addDigit(9)});
document.getElementById("buttonzero").addEventListener("click",function(){addDigit(0)});
document.getElementById("buttondecimal").addEventListener("click",function(){addDigit(".")});
document.getElementById("buttonaddition").addEventListener("click",function(){add()});
document.getElementById("buttonsubtraction").addEventListener("click",function(){subtract()});
document.getElementById("buttonmultiplication").addEventListener("click",function(){multiply()});
document.getElementById("buttondivision").addEventListener("click",function(){divide()});
var backspace = function() {
tBox.value = tBox.value.slice(0, -1);
};
var addDigit = function(x) {
tBox.value = tBox.value + x;
}
var add = function() {
if (x === 0) {
x = tBox.value;
tBox.value = "";
op = "+";
} else if (y === 0) {
y = tBox.value;
equals();
}
};
var subtract = function() {
if (x === 0) {
x = tBox.value;
tBox.value = "";
op = "-";
} else if (y === 0) {
y = tBox.value;
equals();
}
};
var multiply = function() {
if (x === 0) {
x = tBox.value;
tBox.value = "";
op = "*";
} else if (y === 0) {
y = tBox.value;
equals();
}
};
var divide = function() {
if (x === 0) {
x = tBox.value;
tBox.value = "";
op = "/";
} else if (y === 0) {
y = tBox.value;
equals();
}
};
var equals = function() {
y = tBox.value;
tBox.value = eval(x + op + y); //Eval over here
x = 0;
y = 0;
resetFlag = 1;
};
回答1:
I had nothing to do so ... well i made you a function to eval your maths :
var eval = function( maths ){
// Lets start
var math_object = [];
var number = 0;
var pattern;
while( maths.length>0 ){
// get front number
number = parseFloat( maths );
// create regexp pattern
pattern = new RegExp('^'+((number>=0)?'\\+*':'')+number.toString(), 'i');
// check for error
if( isNaN(number) || !maths.match(pattern) ) return "Expression Error";
// cut number from string
maths = maths.replace(pattern,'');
// push number into array
math_object.push(number);
// Check if next has action
if( maths.length==0 ) break;
// get math action
if( !maths[0].match(/[\/\*+-]/i) ) return "Expression Error";
// save acton
if( maths[0].match(/[+-]/i) ){
math_object.push('+');
}else{
math_object.push(maths[0]);
maths = maths.substr(1);
}
}
if( math_object.length%2==0 ) return "Expression Error";
if( math_object.length==1 ) return math_object[0];
//console.log(math_object);
var math_object_structed = [];
var i = 0;
while( i<math_object.length ){
if( i+1==math_object.length ){
math_object_structed.push(math_object[i]);
break;
}
if( math_object[i+1]=='+' ){
math_object_structed.push(math_object[i]);
math_object_structed.push('+');
i+=2;
}else{
var array = [
math_object[i],
math_object[i+1],
math_object[i+2]
];
math_object.splice(i, 2);
math_object[i] = array;
}
}
//console.log(math_object_structed);
var doMath = function( math_array ){
while( math_array.length>1 ){
var first = math_array.shift();
if( typeof first != "number" )
first = doMath( first );
var action = math_array.shift();
var second = math_array.shift();
if( typeof second != "number" )
second = doMath( second );
var result;
if( action=='+' )
result = first + second;
else if( action=='*' )
result = first * second;
else if( action=='/' )
result = first / second;
else
return "Expression Error";
math_array.unshift( result );
}
if( typeof math_array[0] != "number" )
return doMath( math_array[0] );
else
return math_array[0];
}
return doMath( math_object_structed );
}
So now the result of 1+2+3/5+14*3*4*5+16
is 859.6
and the result of my function eval("1+2+3/5+14*3*4*5+16")
is 859.6
Happy coding.
回答2:
You can use the HTML5 Filesystem API to first write the code that you want to eval to the local filesystem and then eval execute the script.
First step is to request the filesystem:
navigator.webkitPersistentStorage.requestQuota(FILESYSTEM_RESOURCES_QUOTA_MB * 1024 * 1024, function (grantedBytes) {
console.log('Granted ' + grantedBytes + ' bytes for filesystem.');
window.webkitRequestFileSystem(window.PERSISTENT, grantedBytes, onInitFs, errorHandler);
}, errorHandler);
function onInitFs(fs) {
// File system initialized
}
After initializing the file system, create a temporary file on the filesystem and the load the script:
fs.root.getFile('my-script.js', {create: true}, function(fileEntry) {
// Create a FileWriter object for our FileEntry (log.txt).
fileEntry.createWriter(function(fileWriter) {
fileWriter.onwriteend = function(e) {
console.log('Write completed.');
// Execute the script
$.getScript(fileEntry.toURL());
};
fileWriter.onerror = function(e) {
console.log('Write failed: ' + e.toString());
};
// Create a new Blob and write it to my-script.js.
var blob = new Blob([scriptText], {type: 'text/plain'});
fileWriter.write(blob);
}, errorHandler);
}, errorHandler);
回答3:
Read the Chrome documentation "Using eval in Chrome Extensions. Safely.". It answers this common question.
来源:https://stackoverflow.com/questions/25196121/chrome-app-eval