Coffee_Table
Coffee_Table

Reputation: 284

Using Javascript's eval() on HTML Text

I am toying around with some basic constructs in HTML and Javascript (i.e., I am a HTML/Javascript n00b), and there is a feature I simply cannot seem to implement properly. In a nutshell, I'd like to grab text from the body of an HTML page and evaluate it using Javascript (either eval() or new Function()). To see that my use of eval() is right, I first tried the following code, which works as expected (and displays the value 5):

<script>
window.onload = function () {
    eval("var t = function () { if (5>0) return 5; }();");
    document.body.innerHTML = t;
}
</script>

However, when I then attempt to achieve my goal of grabbing the "code" from the HTML and running it, this seems to fail for me. Here's a piece of code that doesn't work (I've tried many variations of this):

<script>
window.onload = function() {
    var x = document.getElementById("myP").innerHTML;
    eval("var e = " + x + ";");
    document.body.innerHTML = e();
}
</script>

<body>
    <p id="myP">function () { if (5>1) { return 5; } } </p>
</body>

I tested that the variable x does in fact contain the desired "code" from the body. But for some reason, the above will just not work correctly; it will just display the body and ignore the eval and the statement after it updating the innerHTML.

What's stranger is that when I try code that is "more complex", it works fine, such as:

<script>
window.onload = function() {
    var x = document.getElementById("myP").innerHTML;
    eval("var e = " + x + ";");
    document.body.innerHTML = e();
}
</script>

<body>
    <p id="myP">function () { var a = []; var b = [1,2,3]; for (var i in b) { a.push([b[i],'q']); } return a; } </p>
</body>

It seems really weird to me that this example should work but not the previous one; does eval() hate if-statements? Am I missing some subtle aspect of eval()? Am I missing some super-basic Javascript syntax? Any help is appreciated, both in getting the above particular instance to work, as well as advice for how to implement what I am trying to do generally, i.e. to pass any code from HTML to eval().

NOTE: If possible, please avoid any comments/answers about how eval() is "evil" or is a major security issue, or any such remarks. I am aware of these concerns. My issue is within the context of a personal project and has no chance of being publicly deployed or used unsafely etc.

Upvotes: 2

Views: 10419

Answers (1)

James Allardice
James Allardice

Reputation: 166031

The problem here is related to the DOM, rather than JavaScript. You're asking for the innerHTML of a node. If you have a look at what you end up with the problem becomes clear:

var x = document.getElementById("myP").innerHTML;
console.log(x); // "function () { if (5&gt;1) { return 5; } }"

The browser has converted the > character into an HTML entity. What you need is the textContent of the node:

var x = document.getElementById("myP").textContent;
console.log(x); // "function () { if (5>1) { return 5; } }"

Here's a working example.

Upvotes: 6

Related Questions