Home Ask Login Register

Developers Planet

Your answer is one click away!

user1955162 February 2016

Javascript eval() not always working on text appended to contents of a div

I use AJAX to load dynamic content to #main_content element:

var con = document.getElementById('main-content');
con.innerHTML = xhr.responseText;

However, innerHTML does not run JS in script elements. To evaluate them, I use

$("#main-content").find("script").each(function(i) {
  eval($(this).text());
  console.log($(this).text);
});

One of my loaded pages has the following <script> element which gets executed, and works as expected:

<!-- AJAX response -->
<script>alert(123);</script>

However, if I define functions in the AJAX request, they come up as undefined when I attempt to call them:

<!-- AJAX response -->
<script>
function func() {
  alert(123);
}
</script>

I am not sure why the first <script> element gets evaluated and executed, and the second one does not. They are both being called by the same function to load and evaluate the contents of the div.

Answers


Oriol February 2016

The problem is that, in non-strict mode, global variables evaluated by a direct eval call become local variables of the scope which called eval:

var code = "var foo = 123";
(function() {
  eval(code); // direct call
  foo; // 123
})();
foo; // ReferenceError: foo is not defined

In strict mode there are some restricctions, so the variable in not created in the local scope neither.

Instead, if you want the variables to become global, you can use an indirect eval call:

var code = "var foo = 123";
(function() {
  window.eval(code); // indirect call
  foo; // 123
})();
foo; // 123

This is explained in 10.4.2 - Entering Eval Code.

Post Status

Asked in February 2016
Viewed 1,431 times
Voted 4
Answered 1 times

Search




Leave an answer


Quote of the day: live life