views:

84

answers:

2

I have page A that issues an ajax call and brings in snipped B. This snippet is being added into the DOM and all the scripts in that snipper are eval-ed. In that snippet, I have 2 script tags as such:

<script type="text/javascript">
function doOptions(){
   alert('doOptions');
}
</script>
<script type="text/javascript">
   X = { 
      x : function(x) {
           alert('x');
      }


   }
</script>

Then the JS that is declared in the above script tags is being used on within snippet B as such:

  <button type="button" onclick="doOptions();"> options </button>       
  <button type="button" onclick="X.x();"> XX </button>

Clicking on the XX button work, but clicking on the options button, does not. Both firefox and IE tell me that doOptions is not defined. Why?

Also, what category of Javascript knowledge is this? Meaning, if I want to read more about this, what do I search for, where do I look in the table of contents in a JS book?

Thanks.

+1  A: 

This snippet is being added into the DOM and all the scripts in that snipper are eval-ed.

If you are using innerHTML to insert the script, it will not work - the script content will not be parsed. There are methods to get it working with Internet Explorer, but you'll never have a cross browser solution. You should look at returning the data from the AJAX request in a different format (as text, for example) and then creating and appending the script element using DOM functions. For example:

// Create the script element
var script = document.createElement("script");
script.type = "text/javascript";

// Set the source as the location of the ajax service
script.src = "http://path.to/myajaxhandler.php?ajaxopt=2&amp;anotheropt=5";

// Add the script element
document.getElementsByTagName("head")[0].appendChild(script);

Either that or parse out the text content from the script elements returned in the AJAX call, but that gets more complicated because you'll need to use regular expressions (which aren't ideal for parsing HTML, but might be ok if the content returned isn't too complex).

Andy E
I have a custom function that evals the scripts. It does a decent job dealing with diferent browsers. The snippets are definitelly getting evaled since the second one works. I can see that in Firebug that eval is being called on both snippets.I guess my question is what is the difference between the two snippets such that after an eval, the function is not available, but the function inside an object is?
ssm
I meant to say that the script blocks are definitely being evaled.
ssm
A: 

If my guess is right and your problem falls this case, this might be useful. The problem could be due to the reason that the evals are executed in the calling environments context.

I executed the following test:

function test() {
    eval('x={bar:function(){alert("bar");}}');
    eval('function foo(){alert("foo")}')


}
test();
x.bar(); //succeeds
foo(); //fails.

Here the call foo() fails because it is local to the test() function whereas the variable 'x' is a global variable(since 'var' is not specified) hence the call to bar() on x succeeds;

If you want to make 'foo' function available outside,

function test() {
    eval('x={bar:function(){alert("bar");}}');
    eval('foo = function(){alert("foo")}')


}
test();
x.bar();
foo();

Now we are assigning the function to a global variable ('var' not specified). Now you can call foo() function outside.

Hope this helps.

Marimuthu Madasamy
You nailed it on the head. You were testing exactly the scenario I was trying to describe. My only question is this: In your case, I can see how foo() is local to the test() function. In my case, my function is not declared inside of any other function, but in its own script block. Shouldn't this make it global?
ssm
Your functions are in its own script block but only when you call eval(), they are made available and there comes the "calling environment's context". If your call to eval() is not wrapped inside any function, the functions evaluated will be global otherwise the function definitions are local to the function(in your case, this function might be the Ajax success callback) which calls eval.
Marimuthu Madasamy