createTextNode and IE7

Discussion in 'Javascript' started by Randy Webb, Nov 30, 2006.

  1. Randy Webb

    Randy Webb Guest

    When running this code in IE7:

    function insertScript() {
    var newScript = document.createElement('script');
    newScript.type = "text/javascript";
    var s = document.createTextNode("alert('hi');");
    newScript.appendChild(s); // problem line
    document.getElementById("myDiv").appendChild(newScript);
    }

    window.onload=insertScript;

    I get this error:

    Unexpected call to method or property access

    And a pointer that points to the newScript.appendChild(s) line.

    Am I using createTextNode incorrectly or is IE7 getting it wrong?

    The function, as written, works correctly in FF2.0, Opera9 and AIUI,
    Safari1.3.2 Its an attempt to get around Safari not supporting the
    setting of the .text property of a script element. If IE7 simply won't
    create the text and append it then feature testing for createTextNode
    won't work. So, I came up with the idea of attempting to set the .text
    property with a variable definition then reading that variable. If it is
    set, then use the .text property. If it isn't set, then use
    createTextNode. Not sure how reliable it is so I thought about using an
    IE conditional to isolate IE and go based on that but it reeks of
    browser detection.

    --
    Randy
    Chance Favors The Prepared Mind
    comp.lang.javascript FAQ - http://jibbering.com/faq
    Javascript Best Practices - http://www.JavascriptToolbox.com/bestpractices/
     
    Randy Webb, Nov 30, 2006
    #1
    1. Advertising

  2. Randy Webb

    Martijn Saly Guest

    Randy Webb wrote:
    > When running this code in IE7:
    >
    > function insertScript() {
    > var newScript = document.createElement('script');
    > newScript.type = "text/javascript";
    > var s = document.createTextNode("alert('hi');");
    > newScript.appendChild(s); // problem line
    > document.getElementById("myDiv").appendChild(newScript);
    > }
    >
    > window.onload=insertScript;
    >
    > I get this error:
    >
    > Unexpected call to method or property access
    >
    > And a pointer that points to the newScript.appendChild(s) line.
    >
    > Am I using createTextNode incorrectly or is IE7 getting it wrong?
    >
    > The function, as written, works correctly in FF2.0, Opera9 and AIUI,
    > Safari1.3.2 Its an attempt to get around Safari not supporting the
    > setting of the .text property of a script element. If IE7 simply won't
    > create the text and append it then feature testing for createTextNode
    > won't work. So, I came up with the idea of attempting to set the .text
    > property with a variable definition then reading that variable. If it is
    > set, then use the .text property. If it isn't set, then use
    > createTextNode. Not sure how reliable it is so I thought about using an
    > IE conditional to isolate IE and go based on that but it reeks of
    > browser detection.
    >


    So basically you're inserting javascript with javascript? :D

    Why not put the inserted script directly into your page? Then you won't
    have a problem.

    --
    Martijn Saly
     
    Martijn Saly, Nov 30, 2006
    #2
    1. Advertising

  3. Randy Webb wrote:
    > When running this code in IE7:
    >
    > function insertScript() {
    > var newScript = document.createElement('script');
    > newScript.type = "text/javascript";
    > var s = document.createTextNode("alert('hi');");
    > newScript.appendChild(s); // problem line
    > document.getElementById("myDiv").appendChild(newScript);
    > }
    >
    > window.onload=insertScript;
    >
    > I get this error:
    >
    > Unexpected call to method or property access
    >
    > And a pointer that points to the newScript.appendChild(s) line.
    >
    > Am I using createTextNode incorrectly or is IE7 getting it wrong?


    This is not related specifically to IE 7, earlier versions of IE don't
    do it (the append child on a script element object) either. It is one of
    the many problems with IE where the Core DOM stuff applied to a certain
    element fails in IE and you need to use the more specialized HTML DOM.



    --

    Martin Honnen
    http://JavaScript.FAQTs.com/
     
    Martin Honnen, Nov 30, 2006
    #3
  4. Randy Webb

    Randy Webb Guest

    Martijn Saly said the following on 11/30/2006 3:45 AM:
    > Randy Webb wrote:
    >> When running this code in IE7:
    >>
    >> function insertScript() {
    >> var newScript = document.createElement('script');
    >> newScript.type = "text/javascript";
    >> var s = document.createTextNode("alert('hi');");
    >> newScript.appendChild(s); // problem line
    >> document.getElementById("myDiv").appendChild(newScript);
    >> }
    >>
    >> window.onload=insertScript;
    >>
    >> I get this error:
    >>
    >> Unexpected call to method or property access
    >>
    >> And a pointer that points to the newScript.appendChild(s) line.
    >>
    >> Am I using createTextNode incorrectly or is IE7 getting it wrong?
    >>
    >> The function, as written, works correctly in FF2.0, Opera9 and AIUI,
    >> Safari1.3.2 Its an attempt to get around Safari not supporting the
    >> setting of the .text property of a script element. If IE7 simply won't
    >> create the text and append it then feature testing for createTextNode
    >> won't work. So, I came up with the idea of attempting to set the .text
    >> property with a variable definition then reading that variable. If it
    >> is set, then use the .text property. If it isn't set, then use
    >> createTextNode. Not sure how reliable it is so I thought about using
    >> an IE conditional to isolate IE and go based on that but it reeks of
    >> browser detection.
    >>

    >
    > So basically you're inserting javascript with javascript? :D


    That is precisely what it is doing.

    > Why not put the inserted script directly into your page? Then you won't
    > have a problem.


    It's purpose is Ajax related. If you retrieve a snippet of HTML using
    Ajax and then insert it in a container using innerHTML then any script
    blocks in the HTML won't get executed. So you need some way of causing
    it to be executed.

    --
    Randy
    Chance Favors The Prepared Mind
    comp.lang.javascript FAQ - http://jibbering.com/faq
    Javascript Best Practices - http://www.JavascriptToolbox.com/bestpractices/
     
    Randy Webb, Nov 30, 2006
    #4
  5. Randy Webb

    Randy Webb Guest

    Martin Honnen said the following on 11/30/2006 8:25 AM:
    > Randy Webb wrote:
    >> When running this code in IE7:
    >>
    >> function insertScript() {
    >> var newScript = document.createElement('script');
    >> newScript.type = "text/javascript";
    >> var s = document.createTextNode("alert('hi');");
    >> newScript.appendChild(s); // problem line
    >> document.getElementById("myDiv").appendChild(newScript);
    >> }
    >>
    >> window.onload=insertScript;
    >>
    >> I get this error:
    >>
    >> Unexpected call to method or property access
    >>
    >> And a pointer that points to the newScript.appendChild(s) line.
    >>
    >> Am I using createTextNode incorrectly or is IE7 getting it wrong?

    >
    > This is not related specifically to IE 7, earlier versions of IE don't
    > do it (the append child on a script element object) either. It is one of
    > the many problems with IE where the Core DOM stuff applied to a certain
    > element fails in IE and you need to use the more specialized HTML DOM.


    Thank you Martin, it had me scratching my head in wonderment for a
    little while. Is there a way to feature detect for that failure without
    using try/catch or throwing an error?

    How widely feasible is using try/catch now anyway? Is the web and
    browsers to the point where try/catch is safe enough to use without
    backwards compatibility issues?

    --
    Randy
    Chance Favors The Prepared Mind
    comp.lang.javascript FAQ - http://jibbering.com/faq
    Javascript Best Practices - http://www.JavascriptToolbox.com/bestpractices/
     
    Randy Webb, Nov 30, 2006
    #5
  6. Randy Webb

    ASM Guest

    Randy Webb a écrit :
    >
    > It's purpose is Ajax related. If you retrieve a snippet of HTML using
    > Ajax and then insert it in a container using innerHTML then any script
    > blocks in the HTML won't get executed. So you need some way of causing
    > it to be executed.


    I think if you createElement('object') and XHR.responsetext in it
    all what is in object fire (even css)


    --
    Stephane Moriaux et son (moins) vieux Mac déjà dépassé
    Stephane Moriaux and his (less) old Mac already out of date
     
    ASM, Nov 30, 2006
    #6
  7. Randy Webb

    Randy Webb Guest

    ASM said the following on 11/30/2006 6:09 PM:
    > Randy Webb a écrit :
    >>
    >> It's purpose is Ajax related. If you retrieve a snippet of HTML using
    >> Ajax and then insert it in a container using innerHTML then any script
    >> blocks in the HTML won't get executed. So you need some way of causing
    >> it to be executed.

    >
    > I think if you createElement('object') and XHR.responsetext in it
    > all what is in object fire (even css)


    How would you get the responsetext into the container object? Via
    innerHTML or how? If you set it via innerHTML then it won't execute
    script elements. That's how this whole thing got started was by people
    asking "I put my contents in a container but my scripts don't get
    executed". There are still flaws with the approach I have so far with
    potential scope issues, document.write issues, and code that will go up
    the chain using parentNode to get to a container (which goes into the
    scope issue).

    --
    Randy
    Chance Favors The Prepared Mind
    comp.lang.javascript FAQ - http://jibbering.com/faq
    Javascript Best Practices - http://www.JavascriptToolbox.com/bestpractices/
     
    Randy Webb, Dec 1, 2006
    #7
  8. Randy Webb

    RobG Guest

    Randy Webb wrote:
    > Martin Honnen said the following on 11/30/2006 8:25 AM:

    [...]
    > > This is not related specifically to IE 7, earlier versions of IE don't
    > > do it (the append child on a script element object) either. It is one of
    > > the many problems with IE where the Core DOM stuff applied to a certain
    > > element fails in IE and you need to use the more specialized HTML DOM.

    >
    > Thank you Martin, it had me scratching my head in wonderment for a
    > little while. Is there a way to feature detect for that failure without
    > using try/catch or throwing an error?
    >
    > How widely feasible is using try/catch now anyway? Is the web and
    > browsers to the point where try/catch is safe enough to use without
    > backwards compatibility issues?


    I think your compatibility issues are worse than that - if the loaded
    script element assigns something to the innerHTML property of an
    element in the page, and you assign to the text property of the script
    element before adding it to the page, it will crash IE 6. You can't
    even protect users with try..catch:

    <script type="text/javascript">
    var htmlString = '<hr><script type="text/javascript">'
    + 'var d = document.getElementById(\'testDiv\');'
    + 'd.innerHTML = \'New content\';'
    + '<\/script><br>';

    function addHTML(id, htmlString)
    {
    var target = document.getElementById(id);
    target.innerHTML = htmlString;

    var el, els = target.getElementsByTagName('script');
    var oScript;
    for (var i=0, len=els.length; i<len; i++){
    el = els;
    oScript = document.createElement('script');
    oScript.type = 'text/javascript';
    oScript.text = el.text;
    el.parentNode.replaceChild(oScript, el);
    }
    }

    </script>

    <div>
    <input type="button" value="addHTML"
    onclick="addHTML('testDiv', htmlString);">
    </div>

    Using DOM methods (createTextNode et al) is OK.

    How did I discover that? Because I was playing with adding scripts
    using both this method and eval'ing the script content (the method used
    by Prototype.js) and wanted to resolve a multitude of issues. I think
    eval'ing script element content is really awful, so I wanted to see if
    this method offers a genuine alternative.

    The fix is to add the script element to the page *before* assigning a
    value to the text property (a strategy that doesn't help with the
    createTextNode problem). The danger is is the severe consequences of
    getting the order wrong, and that some future browser may decide to
    execute scripts added using innerHTML so the above method will execute
    it twice.

    I think you have to strip the script element content from the response
    text (a RegExp with match does the trick) first, then assign to
    innerHTML, then insert replacement script elements and assign to their
    text property or use createTextNode as appropriate. Gets tougher, eh?

    Incidentally, you also need to deal with external scripts (src="...")
    and (if this is to be a widely used library) with people putting HTML
    comments in the script elements. That last one hurt, I'd love to say
    screw 'em but I'm not sure that is the right attitude.

    I'm glad you solved the Safari issue - I'd actually given up on it once
    I discovered the above, you've given me new hope. I'd decided that any
    script added to a page should come as JSON and be eval'd. There are a
    number of other issues associated with that related to scope that your
    script/replace method neatly solves.

    Regardless of which way you add the script, if it is non-trivial, it
    must be specifically designed to be added that way.

    Keep at it, maybe you'll finally get there. :)

    --
    Rob
     
    RobG, Dec 1, 2006
    #8
  9. Randy Webb wrote:

    [snip]
    >It's purpose is Ajax related. If you retrieve a snippet of HTML using
    > Ajax and then insert it in a container using innerHTML then any script
    > blocks in the HTML won't get executed. So you need some way of causing
    > it to be executed.

    [/snip]

    Hi

    I don't know if this is relevant to your problem, but have you explored
    adapating any of the ideas discussed on http://dean.edwards.name,
    involving the use of hidden IFrames to execute script?

    Regards

    Julian
     
    Julian Turner, Dec 1, 2006
    #9
  10. Hi Randy,

    Randy Webb wrote:
    > When running this code in IE7:
    >
    > function insertScript() {
    > var newScript = document.createElement('script');
    > newScript.type = "text/javascript";
    > var s = document.createTextNode("alert('hi');");
    > newScript.appendChild(s); // problem line
    > document.getElementById("myDiv").appendChild(newScript);
    > }
    >
    > window.onload=insertScript;
    >
    > I get this error:
    >
    > Unexpected call to method or property access
    >
    > And a pointer that points to the newScript.appendChild(s) line.
    >
    > Am I using createTextNode incorrectly or is IE7 getting it wrong?
    >
    > The function, as written, works correctly in FF2.0, Opera9 and AIUI,


    What is "AIUI"?

    > Safari1.3.2 Its an attempt to get around Safari not supporting the
    > setting of the .text property of a script element. If IE7 simply won't
    > create the text and append it then feature testing for createTextNode
    > won't work. So, I came up with the idea of attempting to set the .text
    > property with a variable definition then reading that variable.


    I was doing this weeks ago :) You even saw a page of mine that did
    exactly this. Remember that "insert code" thing I had for code
    examples. Below is the code I used to determine if the page is capable
    of inserting scripts with your technique plus the necessary option for
    Safari. I try the IE method first because as far as i remember it
    doesn't error in Safari but trying them in the other order does error
    in IE. However I did put the tests in try-catch blocks for good (or
    bad) measure.

    function newInserter() {

    var hooks = [
    function(script, code) { // IE
    script.text = code;
    },
    function(script, code) { // Safari
    code = document.createTextNode(code);
    script.appendChild(code);
    }
    ];

    var hook = null;
    function insertExampleCode(code) {
    var script = document.createElement('script');
    script.type = 'text/javascript';
    hook(script, code);
    document.body.appendChild(script);
    }

    var testCode = "var testInsertion={b:3};"
    for (var i=0; i<hooks.length; i++) {
    hook = hooks;
    try {
    insertExampleCode(testCode);
    if (testInsertion && testInsertion.b === 3) {
    return insertExampleCode;
    }
    } catch (e) {}
    }
    return null;
    }

    > If it is
    > set, then use the .text property. If it isn't set, then use
    > createTextNode.


    Just because text property doesn't work, it doesn't mean that
    createTextNode will work. It is just as easy to test both as test one.

    > Not sure how reliable it is so I thought about using an
    > IE conditional to isolate IE and go based on that but it reeks of
    > browser detection.


    I just retested the above coded with success in Mac/Safari 2, Mac/Opera
    9, Mac/Firefox 1.5, Win/IE 5.5, Win/IE 6, Win/Netscape 6.

    Win/IE 5.01 gives and "unexpected quantifier" error.

    Win/IE 4 gives a "syntax error" and then "object expected"

    ----------------

    Clearly there is appeal to your technique which is why I played with it
    until I found the Safari problem. Then I started to get nervous that
    some other browser might be able to do XHR but the script blocks
    wouldn't run.

    The advantage of using eval() is that as long as the programmer knows
    how the code has to be written then it is extremely likely that the
    browser will be able to run the scripts. Success is the most important
    part. If the script blocks are written with care then they could also
    run if your technique is proven to work and the use of eval is changed
    to your technique.

    Peter
     
    Peter Michaux, Dec 1, 2006
    #10
  11. Peter Michaux wrote:
    >
    > Randy Webb wrote:
    >
    > > Not sure how reliable it is so I thought about using an
    > > IE conditional to isolate IE and go based on that but it reeks of
    > > browser detection.

    >
    > I just retested the above coded with success in Mac/Safari 2, Mac/Opera
    > 9, Mac/Firefox 1.5, Win/IE 5.5, Win/IE 6, Win/Netscape 6.
    >
    > Win/IE 5.01 gives and "unexpected quantifier" error.
    >
    > Win/IE 4 gives a "syntax error" and then "object expected"


    I just realized there was other code being run as well. I don't know
    which code was giving the errors.

    Peter
     
    Peter Michaux, Dec 1, 2006
    #11
  12. Randy Webb

    RobG Guest

    Peter Michaux wrote:
    > Randy Webb wrote:

    [...]
    > > The function, as written, works correctly in FF2.0, Opera9 and AIUI,

    >
    > What is "AIUI"?


    "As I understand it". :)

    [...]
    > Clearly there is appeal to your technique which is why I played with it
    > until I found the Safari problem. Then I started to get nervous that
    > some other browser might be able to do XHR but the script blocks
    > wouldn't run.
    >
    > The advantage of using eval() is that as long as the programmer knows
    > how the code has to be written then it is extremely likely that the
    > browser will be able to run the scripts.


    The simplicity of the eval method is alluring, however the whole
    exercise is based on using innerHTML which isn't part of a standard
    anyway. JSON already freely uses eval so there is some acceptance of
    its use there.

    Perhaps there is something in the DOM 3 (XML) Load and Save spec?


    --
    Rob
     
    RobG, Dec 1, 2006
    #12
  13. RobG wrote:
    > Peter Michaux wrote:
    > > Randy Webb wrote:

    > [...]
    > > > The function, as written, works correctly in FF2.0, Opera9 and AIUI,

    > >
    > > What is "AIUI"?

    >
    > "As I understand it". :)


    For a minute there I was worried it was some new browser I had not
    heard about from Microsoft and they were going to cram it down 90% of
    the market's throat and that it's userAgent string was "ice weasel", it
    had window.opera, used only netscape's layers and didn't have
    innerHTML.

    Peter
     
    Peter Michaux, Dec 1, 2006
    #13
  14. Randy Webb

    Randy Webb Guest

    RobG said the following on 12/1/2006 4:48 PM:
    > Peter Michaux wrote:
    >> Randy Webb wrote:

    > [...]
    >>> The function, as written, works correctly in FF2.0, Opera9 and AIUI,

    >> What is "AIUI"?

    >
    > "As I understand it". :)
    >
    > [...]
    >> Clearly there is appeal to your technique which is why I played with it
    >> until I found the Safari problem. Then I started to get nervous that
    >> some other browser might be able to do XHR but the script blocks
    >> wouldn't run.
    >>
    >> The advantage of using eval() is that as long as the programmer knows
    >> how the code has to be written then it is extremely likely that the
    >> browser will be able to run the scripts.

    >
    > The simplicity of the eval method is alluring, however the whole
    > exercise is based on using innerHTML which isn't part of a standard
    > anyway. JSON already freely uses eval so there is some acceptance of
    > its use there.
    >
    > Perhaps there is something in the DOM 3 (XML) Load and Save spec?


    And maybe IE will support it in IE27?

    --
    Randy
    Chance Favors The Prepared Mind
    comp.lang.javascript FAQ - http://jibbering.com/faq
    Javascript Best Practices - http://www.JavascriptToolbox.com/bestpractices/
     
    Randy Webb, Dec 1, 2006
    #14
  15. Randy Webb

    Randy Webb Guest

    Julian Turner said the following on 12/1/2006 4:11 AM:
    > Randy Webb wrote:
    >
    > [snip]
    >> It's purpose is Ajax related. If you retrieve a snippet of HTML using
    >> Ajax and then insert it in a container using innerHTML then any script
    >> blocks in the HTML won't get executed. So you need some way of causing
    >> it to be executed.

    > [/snip]
    >
    > Hi
    >
    > I don't know if this is relevant to your problem, but have you explored
    > adapating any of the ideas discussed on http://dean.edwards.name,
    > involving the use of hidden IFrames to execute script?


    If you use an IFrame to execute your scripts that defeats the purpose of
    using the XMLHttpRequest object as you could just load the page in the
    IFrame, the script gets executed, grab the results and dump it in the
    main page. (That is how 'ajax' was done before XMLHttpRequest came about).

    And, the IFrame tricks discussed are about getting eval'ed code out of
    the current scope into a scope of it's own and I am trying to get code
    back into it's proper scope.

    --
    Randy
    Chance Favors The Prepared Mind
    comp.lang.javascript FAQ - http://jibbering.com/faq
    Javascript Best Practices - http://www.JavascriptToolbox.com/bestpractices/
     
    Randy Webb, Dec 1, 2006
    #15
  16. Randy Webb

    Randy Webb Guest

    Peter Michaux said the following on 12/1/2006 11:27 AM:
    > Hi Randy,
    >
    > Randy Webb wrote:
    >> When running this code in IE7:
    >>
    >> function insertScript() {
    >> var newScript = document.createElement('script');
    >> newScript.type = "text/javascript";
    >> var s = document.createTextNode("alert('hi');");
    >> newScript.appendChild(s); // problem line
    >> document.getElementById("myDiv").appendChild(newScript);
    >> }
    >>
    >> window.onload=insertScript;
    >>
    >> I get this error:
    >>
    >> Unexpected call to method or property access
    >>
    >> And a pointer that points to the newScript.appendChild(s) line.
    >>
    >> Am I using createTextNode incorrectly or is IE7 getting it wrong?
    >>
    >> The function, as written, works correctly in FF2.0, Opera9 and AIUI,

    >
    > What is "AIUI"?


    No, it doesn't support window.opera but it has all the rest of your
    nightmares :)

    >> Safari1.3.2 Its an attempt to get around Safari not supporting the
    >> setting of the .text property of a script element. If IE7 simply won't
    >> create the text and append it then feature testing for createTextNode
    >> won't work. So, I came up with the idea of attempting to set the .text
    >> property with a variable definition then reading that variable.

    >
    > I was doing this weeks ago :) You even saw a page of mine that did
    > exactly this. Remember that "insert code" thing I had for code
    > examples.


    Yes, this thread:

    <URL:
    http://groups-beta.google.com/group/comp.lang.javascript/browse_thread/thread/499fb07a38e71077/3b313bfc2c0090e6?lnk=gst&q=createTextNode+safari&rnum=3#3b313bfc2c0090e6>

    Was the one I remembered seeing that had the code I used in it and where
    I got the idea from that caused this thread to be created.

    Below is the code I used to determine if the page is capable
    > of inserting scripts with your technique plus the necessary option for
    > Safari. I try the IE method first because as far as i remember it
    > doesn't error in Safari but trying them in the other order does error
    > in IE. However I did put the tests in try-catch blocks for good (or
    > bad) measure.
    >
    > function newInserter() {
    >
    > var hooks = [
    > function(script, code) { // IE
    > script.text = code;
    > },
    > function(script, code) { // Safari
    > code = document.createTextNode(code);
    > script.appendChild(code);
    > }
    > ];
    >
    > var hook = null;
    > function insertExampleCode(code) {
    > var script = document.createElement('script');
    > script.type = 'text/javascript';
    > hook(script, code);
    > document.body.appendChild(script);
    > }
    >
    > var testCode = "var testInsertion={b:3};"
    > for (var i=0; i<hooks.length; i++) {
    > hook = hooks;
    > try {
    > insertExampleCode(testCode);
    > if (testInsertion && testInsertion.b === 3) {
    > return insertExampleCode;
    > }
    > } catch (e) {}
    > }
    > return null;
    > }



    Looks like a convoluted way of doing this:

    function insertScript(scriptContents) {
    var useIt = false;
    var testScript = document.createElement('script');
    testScript.type = "text/javascript";
    testScript.text = "var useText=true";
    document.getElementById("myDiv").appendChild(testScript);

    var newScript = document.createElement('script');
    newScript.type = "text/javascript";
    if(useText)
    {
    newScript.text = scriptContents;
    }
    else
    {
    //Opera 9 falls through to this branch.
    var s = document.createTextNode(scriptContents);
    newScript.appendChild(s);
    }
    document.getElementById("myDiv").appendChild(newScript);
    }

    Although the only browser I know of that won't use createTextNode is IE.

    What does that code do in Safari (in fact, any mac browser) when called
    with a insertScript('alert("It worked")') ?

    >> If it is
    >> set, then use the .text property. If it isn't set, then use
    >> createTextNode.

    >
    > Just because text property doesn't work, it doesn't mean that
    > createTextNode will work. It is just as easy to test both as test one.


    It's possible, but unless I see one, or hear of one, I will leave it as
    simple as possible which is the goal.

    >> Not sure how reliable it is so I thought about using an
    >> IE conditional to isolate IE and go based on that but it reeks of
    >> browser detection.

    >
    > I just retested the above coded with success in Mac/Safari 2, Mac/Opera
    > 9, Mac/Firefox 1.5, Win/IE 5.5, Win/IE 6, Win/Netscape 6.


    What do the Mac browsers (and even NS6 Win) do with the code above I posted?

    > Clearly there is appeal to your technique which is why I played with it
    > until I found the Safari problem. Then I started to get nervous that
    > some other browser might be able to do XHR but the script blocks
    > wouldn't run.


    I don't use XHR so this is mostly an academic exercise for me as I use
    ..js files and dynamically load them on the fly.

    > The advantage of using eval() is that as long as the programmer knows
    > how the code has to be written then it is extremely likely that the
    > browser will be able to run the scripts.


    Most JS programmers don't understand how to control eval and when to/not
    to use it though. The major drawback to eval here is the scope chain. I
    haven't decided on an attempted course to try to deal with the scope
    issue yet but I have some ideas.

    > Success is the most important part.


    Without a doubt.

    > If the script blocks are written with care then they could also
    > run if your technique is proven to work and the use of eval is changed
    > to your technique.


    I don't know that I can make mine work but I won't stop trying to :) I
    have been modifying the loadJSFile function for about 5 years now :)

    --
    Randy
    Chance Favors The Prepared Mind
    comp.lang.javascript FAQ - http://jibbering.com/faq
    Javascript Best Practices - http://www.JavascriptToolbox.com/bestpractices/
     
    Randy Webb, Dec 1, 2006
    #16
  17. Hi Randy,

    Randy Webb wrote:
    >
    > Below is the code I used to determine if the page is capable
    > > of inserting scripts with your technique plus the necessary option for
    > > Safari. I try the IE method first because as far as i remember it
    > > doesn't error in Safari but trying them in the other order does error
    > > in IE. However I did put the tests in try-catch blocks for good (or
    > > bad) measure.
    > >
    > > function newInserter() {
    > >
    > > var hooks = [
    > > function(script, code) { // IE
    > > script.text = code;
    > > },
    > > function(script, code) { // Safari
    > > code = document.createTextNode(code);
    > > script.appendChild(code);
    > > }
    > > ];
    > >
    > > var hook = null;
    > > function insertExampleCode(code) {
    > > var script = document.createElement('script');
    > > script.type = 'text/javascript';
    > > hook(script, code);
    > > document.body.appendChild(script);
    > > }
    > >
    > > var testCode = "var testInsertion={b:3};"
    > > for (var i=0; i<hooks.length; i++) {
    > > hook = hooks;
    > > try {
    > > insertExampleCode(testCode);
    > > if (testInsertion && testInsertion.b === 3) {
    > > return insertExampleCode;
    > > }
    > > } catch (e) {}
    > > }
    > > return null;
    > > }

    >
    >
    > Looks like a convoluted way of doing this:
    >
    > function insertScript(scriptContents) {
    > var useIt = false;
    > var testScript = document.createElement('script');
    > testScript.type = "text/javascript";
    > testScript.text = "var useText=true";
    > document.getElementById("myDiv").appendChild(testScript);
    >
    > var newScript = document.createElement('script');
    > newScript.type = "text/javascript";
    > if(useText)
    > {
    > newScript.text = scriptContents;
    > }
    > else
    > {
    > //Opera 9 falls through to this branch.
    > var s = document.createTextNode(scriptContents);
    > newScript.appendChild(s);
    > }
    > document.getElementById("myDiv").appendChild(newScript);
    > }


    Each time you insert a script you are making the same test. If the page
    will only insert once then that is fine. However with multiple uses you
    are making the same test unnecessarily. Of course you already know this
    and it is personal preference. I like Richard's style of testing once
    and then setting a very short efficient function to be used repeatedly.


    > Although the only browser I know of that won't use createTextNode is IE.
    >
    > What does that code do in Safari (in fact, any mac browser) when called
    > with a insertScript('alert("It worked")') ?

    <snip>
    > What do the Mac browsers (and even NS6 Win) do with the code above I posted?


    If you post some examples at a few different URLs then I can click them
    in Safari 2.0.4 and if the issue is still interesting in a few weeks I
    can also click them in Safari 1.3.9.


    > > The advantage of using eval() is that as long as the programmer knows
    > > how the code has to be written then it is extremely likely that the
    > > browser will be able to run the scripts.

    >
    > Most JS programmers don't understand how to control eval and when to/not
    > to use it though.


    Unless the alternative is better and has less drawbacks, I really am ok
    with letting other programmers shoot themselves in the foot as long as
    the capability to do it right is in the compromise solution.


    > I don't know that I can make mine work but I won't stop trying to :) I
    > have been modifying the loadJSFile function for about 5 years now :)


    Using eval with care will work today (and I'm all stressed about
    setting opacity well). Not that your attempts should be discouraged.
    I'd rather do it your way.

    Peter
     
    Peter Michaux, Dec 2, 2006
    #17
  18. Randy Webb wrote:

    [snip]
    > And, the IFrame tricks discussed are about getting eval'ed code out of
    > the current scope into a scope of it's own and I am trying to get code
    > back into it's proper scope.

    [/snip]

    Hi

    I appreciate the point your are making here, and that the IFrame trick
    is not relevant.

    I am not sure I fully understand the issues you have with eval and
    proper scope, and therefore why inserting script with a script tag is
    preferrable to eval'ing it.

    I think I understand that if I eval script, then it will get its own
    scope based on the scope of the function in which it it is eval'd.

    Is the problem this: your script is trying to introduce variables and
    declared functions to be available in the scope chains of
    **previously** imported script? Or am I way off the mark?

    Regards

    Julian Turner
     
    Julian Turner, Dec 4, 2006
    #18
  19. Randy Webb

    Randy Webb Guest

    Julian Turner said the following on 12/4/2006 7:40 AM:
    > Randy Webb wrote:
    >
    > [snip]
    >> And, the IFrame tricks discussed are about getting eval'ed code out of
    >> the current scope into a scope of it's own and I am trying to get code
    >> back into it's proper scope.

    > [/snip]
    >
    > Hi
    >
    > I appreciate the point your are making here, and that the IFrame trick
    > is not relevant.


    It may end up not being irrelevant, I honestly don't know yet. I do
    think it doesn't solve the issue I am pondering on though :) And, to be
    totally honest, I don't have the issue in any site I am working on. It's
    more of a mental exercise than anything else.

    > I am not sure I fully understand the issues you have with eval and
    > proper scope, and therefore why inserting script with a script tag is
    > preferrable to eval'ing it.


    Simple scenario. Let's say a page is loaded via XHR. That document has a
    script block in it with this code snippet:

    <script>
    var myVar = "My name is Randy";
    </script>

    Just any global variable.

    You load the HTML, insert it in a container, then want to execute the
    script block. You run a function that evals the script contents. myVar
    then becomes local to the function.

    The biggest thing? I hate eval :)

    Second scenario is one that I can not come up with a reasonable reason
    to ever do but it involves a script block that traverses the tree going
    upwards using parentNode to get to an element. As I say, that is a
    perverse scenario that if I ever saw actual code that did it I would
    probably wonder what insane asylum the author was a patient at.

    > I think I understand that if I eval script, then it will get its own
    > scope based on the scope of the function in which it it is eval'd.


    Yes it does.

    function function1(theArg){
    eval(theArg)
    }
    function function2(){
    alert(myVar)
    }

    function1('var myVar = "My name is Randy"')

    If the argument to that function1 call is the string being loaded via
    XHR and passed to function1 to be executed, then in it's original form
    it would be a global variable. After being eval'ed it becomes local.
    Using createTextNode or the .text property it retains it's global scope.

    > Is the problem this: your script is trying to introduce variables and
    > declared functions to be available in the scope chains of
    > **previously** imported script? Or am I way off the mark?


    Close. Three years ago you didn't see questions in this group with
    regards to XMLHttpRequest and/or AJAX very often. Now, you see a
    kazillion of them. The next phase of that, to me, is going to be script
    issues and it is already happening where people are asking "How do I
    make my scripts execute when loaded with AJAX" and I am simply trying to
    be ahead of it and come up with an answer before the onslaught happens.

    Personally, I don't use AJAX to load data. What dictates how you load
    data is how your back end is set up. People seem to think that you can
    simply take a huge site and convert it to AJAX and everything keeps
    going when that isn't true. If you have a site that has, say, 100 pages
    to it. OK, lets make it an AJAX site. Create a new first page, use AJAX
    to load the other pages and drop them in a div container. Simple, and
    you now have an "AJAX site". That is what it seems a lot of people are
    doing and it runs into the "My scripts don't execute" scenario. Where if
    the site is setup and maintained to be an AJAX driven site then the
    "pages" aren't complete HTML pages and don't stand on there own.

    The approach I use, and prefer, for loading data is .js files and
    loading them on the fly. The back end still has to be set up to create
    those .js files and the main page is set up to handle it. I just find
    the .js files simpler and more reliable than AJAX is all.

    --
    Randy
    Chance Favors The Prepared Mind
    comp.lang.javascript FAQ - http://jibbering.com/faq
    Javascript Best Practices - http://www.JavascriptToolbox.com/bestpractices/
     
    Randy Webb, Dec 4, 2006
    #19
  20. Randy Webb wrote:

    > Simple scenario. Let's say a page is loaded via XHR.


    Maybe this is just semantics but folks don't usually load a page with
    XHR but rather an HTML snip that may contain script blocks.


    > The biggest thing? I hate eval :)


    but Randy, eval is the only way to write dynamic code like this...

    eval("myObj." + foo + "=" + bar);

    :) Ok. Seriously...

    I haven't run tests, but as far as I know, eval is the quickest way to
    parse trusted json. The alternative is a relatively lengthy json parser
    written in JavaScript.


    > Three years ago you didn't see questions in this group with
    > regards to XMLHttpRequest and/or AJAX very often. Now, you see a
    > kazillion of them. The next phase of that, to me, is going to be script
    > issues and it is already happening where people are asking "How do I
    > make my scripts execute when loaded with AJAX" and I am simply trying to
    > be ahead of it and come up with an answer before the onslaught happens.


    This attitude plus FAQ mantainer: a true humanitarian!

    > Personally, I don't use AJAX to load data. What dictates how you load
    > data is how your back end is set up. People seem to think that you can
    > simply take a huge site and convert it to AJAX and everything keeps
    > going when that isn't true. If you have a site that has, say, 100 pages
    > to it. OK, lets make it an AJAX site. Create a new first page, use AJAX
    > to load the other pages and drop them in a div container. Simple, and
    > you now have an "AJAX site". That is what it seems a lot of people are
    > doing and it runs into the "My scripts don't execute" scenario. Where if
    > the site is setup and maintained to be an AJAX driven site then the
    > "pages" aren't complete HTML pages and don't stand on there own.
    >
    > The approach I use, and prefer, for loading data is .js files and
    > loading them on the fly. The back end still has to be set up to create
    > those .js files and the main page is set up to handle it. I just find
    > the .js files simpler and more reliable than AJAX is all.


    But once a site starts submitting forms with Ajax then the whole site
    may as well switch over to Ajax all together, don't you think?

    Peter
     
    Peter Michaux, Dec 4, 2006
    #20
    1. Advertising

Want to reply to this thread or ask your own question?

It takes just 2 minutes to sign up (and it's free!). Just click the sign up button to choose a username and then you can ask your own questions on the forum.
Similar Threads
  1. Avi U
    Replies:
    2
    Views:
    597
    Martin Honnen
    Jan 13, 2004
  2. Danny
    Replies:
    11
    Views:
    869
  3. Martin Honnen

    Re: DOM CreateTextNode with Unicode

    Martin Honnen, Feb 29, 2008, in forum: XML
    Replies:
    0
    Views:
    397
    Martin Honnen
    Feb 29, 2008
  4. Thomas 'PointedEars' Lahn

    Re: DOM CreateTextNode with Unicode

    Thomas 'PointedEars' Lahn, Mar 1, 2008, in forum: XML
    Replies:
    0
    Views:
    512
    Thomas 'PointedEars' Lahn
    Mar 1, 2008
  5. Dan Andrews
    Replies:
    4
    Views:
    292
Loading...

Share This Page