createTextNode and IE7

Collapse
This topic is closed.
X
X
 
  • Time
  • Show
Clear All
new posts
  • Randy Webb

    createTextNode and IE7

    When running this code in IE7:

    function insertScript() {
    var newScript = document.create Element('script ');
    newScript.type = "text/javascript";
    var s = document.create TextNode("alert ('hi');");
    newScript.appen dChild(s); // problem line
    document.getEle mentById("myDiv ").appendChild( newScript);
    }

    window.onload=i nsertScript;

    I get this error:

    Unexpected call to method or property access

    And a pointer that points to the newScript.appen dChild(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.javas cript FAQ - http://jibbering.com/faq
    Javascript Best Practices - http://www.JavascriptToolbox.com/bestpractices/
  • Martijn Saly

    #2
    Re: createTextNode and IE7

    Randy Webb wrote:
    When running this code in IE7:
    >
    function insertScript() {
    var newScript = document.create Element('script ');
    newScript.type = "text/javascript";
    var s = document.create TextNode("alert ('hi');");
    newScript.appen dChild(s); // problem line
    document.getEle mentById("myDiv ").appendChild( newScript);
    }
    >
    window.onload=i nsertScript;
    >
    I get this error:
    >
    Unexpected call to method or property access
    >
    And a pointer that points to the newScript.appen dChild(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

    Comment

    • Martin Honnen

      #3
      Re: createTextNode and IE7

      Randy Webb wrote:
      When running this code in IE7:
      >
      function insertScript() {
      var newScript = document.create Element('script ');
      newScript.type = "text/javascript";
      var s = document.create TextNode("alert ('hi');");
      newScript.appen dChild(s); // problem line
      document.getEle mentById("myDiv ").appendChild( newScript);
      }
      >
      window.onload=i nsertScript;
      >
      I get this error:
      >
      Unexpected call to method or property access
      >
      And a pointer that points to the newScript.appen dChild(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

      Comment

      • Randy Webb

        #4
        Re: createTextNode and IE7

        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.create Element('script ');
        > newScript.type = "text/javascript";
        > var s = document.create TextNode("alert ('hi');");
        > newScript.appen dChild(s); // problem line
        > document.getEle mentById("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.appen dChild(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.javas cript FAQ - http://jibbering.com/faq
        Javascript Best Practices - http://www.JavascriptToolbox.com/bestpractices/

        Comment

        • Randy Webb

          #5
          Re: createTextNode and IE7

          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.create Element('script ');
          > newScript.type = "text/javascript";
          > var s = document.create TextNode("alert ('hi');");
          > newScript.appen dChild(s); // problem line
          > document.getEle mentById("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.appen dChild(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.javas cript FAQ - http://jibbering.com/faq
          Javascript Best Practices - http://www.JavascriptToolbox.com/bestpractices/

          Comment

          • ASM

            #6
            Re: createTextNode and IE7

            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.responsetex t 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

            Comment

            • Randy Webb

              #7
              Re: createTextNode and IE7

              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.responsetex t 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.javas cript FAQ - http://jibbering.com/faq
              Javascript Best Practices - http://www.JavascriptToolbox.com/bestpractices/

              Comment

              • RobG

                #8
                Re: createTextNode and IE7

                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.getEle mentById(\'test Div\');'
                + 'd.innerHTML = \'New content\';'
                + '<\/script><br>';

                function addHTML(id, htmlString)
                {
                var target = document.getEle mentById(id);
                target.innerHTM L = htmlString;

                var el, els = target.getEleme ntsByTagName('s cript');
                var oScript;
                for (var i=0, len=els.length; i<len; i++){
                el = els[i];
                oScript = document.create Element('script ');
                oScript.type = 'text/javascript';
                oScript.text = el.text;
                el.parentNode.r eplaceChild(oSc ript, el);
                }
                }

                </script>

                <div>
                <input type="button" value="addHTML"
                onclick="addHTM L('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

                Comment

                • Julian Turner

                  #9
                  Re: createTextNode and IE7


                  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

                  Comment

                  • Peter Michaux

                    #10
                    Re: createTextNode and IE7

                    Hi Randy,

                    Randy Webb wrote:
                    When running this code in IE7:
                    >
                    function insertScript() {
                    var newScript = document.create Element('script ');
                    newScript.type = "text/javascript";
                    var s = document.create TextNode("alert ('hi');");
                    newScript.appen dChild(s); // problem line
                    document.getEle mentById("myDiv ").appendChild( newScript);
                    }
                    >
                    window.onload=i nsertScript;
                    >
                    I get this error:
                    >
                    Unexpected call to method or property access
                    >
                    And a pointer that points to the newScript.appen dChild(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.create TextNode(code);
                    script.appendCh ild(code);
                    }
                    ];

                    var hook = null;
                    function insertExampleCo de(code) {
                    var script = document.create Element('script ');
                    script.type = 'text/javascript';
                    hook(script, code);
                    document.body.a ppendChild(scri pt);
                    }

                    var testCode = "var testInsertion={ b:3};"
                    for (var i=0; i<hooks.length ; i++) {
                    hook = hooks[i];
                    try {
                    insertExampleCo de(testCode);
                    if (testInsertion && testInsertion.b === 3) {
                    return insertExampleCo de;
                    }
                    } 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

                    Comment

                    • Peter Michaux

                      #11
                      Re: createTextNode and IE7


                      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

                      Comment

                      • RobG

                        #12
                        Re: createTextNode and IE7


                        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

                        Comment

                        • Peter Michaux

                          #13
                          Re: createTextNode and IE7

                          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

                          Comment

                          • Randy Webb

                            #14
                            Re: createTextNode and IE7

                            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.javas cript FAQ - http://jibbering.com/faq
                            Javascript Best Practices - http://www.JavascriptToolbox.com/bestpractices/

                            Comment

                            • Randy Webb

                              #15
                              Re: createTextNode and IE7

                              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.javas cript FAQ - http://jibbering.com/faq
                              Javascript Best Practices - http://www.JavascriptToolbox.com/bestpractices/

                              Comment

                              Working...