0

IE7 gives the following error: 'myapp' is undefined

//home.html
<script type="application/x-javascript" src="//www.mysite.com/myjs.js"></script>
<script type="text/javascript" charset="utf-8">
    new myapp.myfunc();
</script>

javascript file:

//myjs.js
myapp = {
    myfunc : function(){
        alert('hello world');
    }
};

*I understand there are many ways to rewrite the code that is used on home.html, but I want to make this work without changing that. I found a working example with similar structure and no JS errors (IE7, IE6). https://google-developers.appspot.com/custom-search-ads/docs/sample

EDIT: The < script > code will be given to external clients, so I want to keep it as simple as possible. See example link.

  • Where is the code going to be used? Different environments? Can I paste it into my Wordpress blog? If the answer is 'I don't know' or 'Yes' to the last question, you will probably need something more robust - because loading javascript cross-browser in a reliable fashion is not simple. – Jon Jaques Feb 05 '13 at 02:09
  • @JonJaques yes, the code will be used into different environments, including copying-pasting into any blog. I've been running into all kinds of issues with cross-origin resource sharing and now some more with older IE browsers. I think what is currently the most backwards-compatible is injecting Javascript into an iFrame. I know its hacky but as long as it works it's worth a try. – Henry Colchado Feb 05 '13 at 16:02
  • So is your application trying to request additional resources once the main script comes back? Like JSON etc? – Jon Jaques Feb 05 '13 at 16:22
  • yes, I was initially looking at requesting xml data, but due to cross-origin compatibility issues I'm now looking at JSONP – Henry Colchado Feb 06 '13 at 00:08

3 Answers3

0

Occam's razor suggests that either IE/MSHTML does not support script elements with type="application/x-javascript". That might have to do with the fact that application/x-javascript is not a registered MIME media type, nor was it ever necessary.

Or it has to do with the fact that //www.mysite.example.com/myjs.js is not a supported URI-reference in that environment. Use fully-qualified URIs like http://www.mysite.example.com/myjs.js instead. (And please use the registered example domains for examples.)

You should also declare identifiers that you intend to use as variables:

var myapp = {
  …
};

If you do not do this, problems can occur if there is an element named myapp in the document. In JScript/MSHTML, identifier resolution will find a host object in the scope chain that has myapp as its property. The value of that property will be a reference to the corresponding element object, and attempting to overwrite that property value will cause a runtime error.

Community
  • 1
  • 1
PointedEars
  • 14,752
  • 4
  • 34
  • 33
  • IE6 seems to dislike the application/x-javascript type. I've made some changes and that seems to work without undefined errors. I hope IE7 behaves the same way. Thanks for the suggestion. – Henry Colchado Feb 05 '13 at 02:38
-1

Add an event handler to the body's Load event. In that event handler, make your myapp.myfunc() call.

Jaxidian
  • 13,081
  • 8
  • 83
  • 125
  • Thanks, I will probably have to do that, however I wanted to see if I could keep the client's copy/paste code to a minimum, like the example link. – Henry Colchado Feb 05 '13 at 01:48
  • What if the end user doesn't have control over the html? What if it's within a content management system? – Jon Jaques Feb 05 '13 at 02:10
  • @JonJaques First of all, take W3Schools (!= W3C) with a handful of salt. As to your question, I would say then that CMS is deeply flawed. You can rely on the fact, for historical and HTML Specification reasons, that the `onload` attribute of the `body` element works. You cannot rely on that `window.onload` & friends work the same. – PointedEars Feb 05 '13 at 02:37
  • @PointedEars, That's why I'm not referencing any W3Schools material. The point is, if you put an html script tag in a document, then immediately try to reference the content from said tag is not going to work because scripts load asynchronously. Furthermore, I don't understand how the OP's code works anyways, because you can't use the new keyword in conjunction with an object literal. – Jon Jaques Feb 05 '13 at 02:46
  • 1
    @JonJaques You are mistaken. 1. Client-side scripts are never loaded asynchronously when included in that fashion; that is why [stylesheets should come first in a document](https://developers.google.com/speed/docs/best-practices/rtt#PutStylesBeforeScripts) (I would not sign the other tips there, but this one is good). 2. The OP is not instantiating the `Object` instance, but the method of the object; every `Function` instance can be called as a constructor. – PointedEars Feb 05 '13 at 02:49
-1

Whenever you're making your code available for consumption, you always want to make sure you're being a good citizen on the page. That means you don't want to create unnecessary global variables, and make sure ones you do create are unique enough. Thats why it's a good idea to wrap your code in an immediately-invoked function expression.

Also, it's generally just easier to do the whole thing with javascript. This is how Google analytics and Facebook plugins load their code.

<script type="text/javascript">
(function() {
  var loadScript = function(src, callback) {
    var head = document.getElementsByTagName('head')[0];
    var script = document.createElement('script');
    script.type = 'text/javascript';
    script.src = src;
    // modern browsers
    script.onload = callback;
    // IE 6 & 7
    script.onreadystatechange = function() {
      if (this.readyState == 'complete') {
        callback();
      }
    }
    head.appendChild(script);
  };
  loadScript('path/to/myscript.js', function() {
     //script loaded
  });
})();
</script>
Jon Jaques
  • 4,262
  • 2
  • 23
  • 25
  • Thanks for this snippet. I will likely need to modify the client code to assure the JS loads first then executes the function. – Henry Colchado Feb 05 '13 at 02:41
  • While you give some good suggestions (and some bad ones), you are not actually answering the question. – PointedEars Feb 05 '13 at 02:44
  • @PointedEars Care to elaborate on the bad ones? I will admit, I interpreted the OP's question wrong initially. – Jon Jaques Feb 05 '13 at 02:54
  • Sure. Due to lack of original research (AFAIK), I am not yet convinced that loading scripts in that fashion is a reliable approach. I know that many people do that (and JSX:dom.js contains a `loadScript()`), but, to paraphrase Bertrand Russell, “everyone can still be wrong.” Also, you are relying on proprietary features, `onload`, and `onreadystatechange`. For what? – PointedEars Feb 05 '13 at 03:00