13

I have the following script element in my web page:

<script src="default.js" type="text/javascript"></script>

Using JavaScript, I want to be able to retrieve the content of the script file. I know I could use an ajax request to get the data but then I am getting something from the server that I already have locally.

So what I would prefer to do is retrieve the content from the DOM (if that's possible) or something that has the same result.

Cheers Anthony

UPDATE

I was trying to simplify the question, maybe a bad a idea, I thought this way would cause less questions.

The real situation I have is as follows, I actually have

<script type="text/html" class="jq-ItemTemplate_Approval">
   ...
   html template that is going to be consumed by jQuery and jTemplate
   ...
</script>

Now this works fine but it means each time the page loads I have to send down the template as part of the HTML of the main page. So my plan was to do the following:

<script src="template.html" type="text/html"></script>

This would mean that the browser would cache the content of template.html and I would not have to send it down each time. But to do this I need to be able to get the content from the file.

Also in this case, as far as I know, requesting the content via ajax isn't going to help all that much because it has to go back to the server to get the content anyway.

thealchemist
  • 421
  • 4
  • 12
vdh_ant
  • 12,720
  • 13
  • 66
  • 86
  • 1
    May I ask why you want to do this? – Schwern Jun 12 '09 at 04:09
  • 1
    If you could (you can't) include it via a script with type text/html then the browser would have to go back to the server too. There is nothing magical about XMLHttpRequest that prevents caching. – Quentin Jun 12 '09 at 08:10

8 Answers8

5

If I understand you correctly, you don't want to use Ajax to load an html template text, but rather have it loaded with the rest of the page. If you control the server side, you can always include the template text in an invisible div tag that you then reference from Javascript:

<div id="template" style="display:none;">
...template text...
</div>
<script>
// pops up the template text.
alert(document.getElementById("template").innerHTML);
</script>

If you are just looking for to load the template so that you can have it cached, you can put the contents in a variable like this:

<script>
var template = "template text..";
</script>

or you can load it using ajax and store the template in a variable so it is accessible. It's pretty trivial in jquery:

var template;
$.get("template.html", function(data){
  template = data;
});
Helgi
  • 1,577
  • 9
  • 9
  • In order of the points you raised: 1) I could do this but it wouldn't take advantage of the browser ability to cache externally referenced files. Some of my templates are over 300 line. Hence being able to put this in an external file and have it cached is a big plus. 2) see what I have said to Ryan Oberoi 3) yes it is very trivial, the problem with this is the time is the client side page lifecycle when this would occur. If I have an external file like "" it will get loaded in parallel with any other external referencess (assuming I put – vdh_ant Jun 12 '09 at 06:51
  • all my script references at the bottom of the page). That means if i have all my templates declared as follows "" the browser will load these very efficiently. Also if i use $(document).ready(...) none of my JS will run until the templates are loaded. If I go to the loading via ajax, my javascript is halfway through running before it tries to get the template, and I would have to hold until it had gotten the content. Now sure I could try loading all templates first but this complicates things, because then I can't do anything till they, – vdh_ant Jun 12 '09 at 06:55
  • are ready. Hence what I was thinking is as follows if I register the templates as follows in the document head , then get the same pages via synchronous ajax call, is the browser smart enough to know that it already got the file via the script tag and it doesn't need to go back to the server to get it via ajax??? – vdh_ant Jun 12 '09 at 06:58
4

unless you load a script as literal text in the page, it does not exist as text. It is interpreted by the browser and melded into the runtime, with any other scripts.

If you want the source you have to fetch it again,if with Ajax get the responseText.

It will come from the browser cache, and doesn't have to be downloaded again.

kennebec
  • 102,654
  • 32
  • 106
  • 127
  • If this is the case, could I put this "" in the top of my page and then call template.html via ajax and have it use the cached version that was gotten previously? – vdh_ant Jun 12 '09 at 04:41
2

You could get the attribute of the src of the script and then use XHR to get the contents of the JS file. It's a much cleaner way of doing it IMO. e.g.:-

if(window.XMLHttpRequest) {
                var xhr = new XMLHttpRequest();         
                xhr.onreadystatechange = function() {
                    if(xhr.status == 200 && xhr.readyState == 4) {
                        var sourceCode = xhr.responseText;
                                            alert('The source code is:-\n'+sourceCode);
                    }
                }
                xhr.open("GET",document.getElementById('scriptID').src,true);
                xhr.send(null);
            }
2

I think what you want to do is to assign a variable inside template.js. Then you have the variable available for use wherever you want in jquery. Something like:

var tpl = "<div> ... </div>"

Wouldn't this be a simpler solution to your problem? We do this in Ext JS. I think this will work for you in jQuery.

Ryan Oberoi
  • 13,817
  • 2
  • 24
  • 23
  • 1
    Ya I did think of this but the problem is the amount of escaping I would have to do. As in if your template is only 5 lines long then doing the escaping, if required isn't too bad. But if it 300 lines plus it becomes a bit harder to maintain. How do you guys get around this? – vdh_ant Jun 12 '09 at 06:47
  • 1
    I have worked with reasonable sized templates in Ext JS. If you want to encode 300 lines plus, write a simple tool that will escape the HTML text. Plenty of options are available. that will convert template.html to template.js with the html text escaped. A simple method using ruby would be to use CGI.escape(str) where str is read from template.html. This approach may be your best bet. – Ryan Oberoi Jun 12 '09 at 07:04
  • Or use a pre-existing tool such as http://search.cpan.org/~rkrimen/Jemplate/lib/Jemplate.pm – Quentin Jun 12 '09 at 08:09
  • In the end I ended up going with this method and I wrote a short script to escape and unescape html content from one text area to another to help make it a little easier. Thanks – vdh_ant Jun 22 '09 at 22:48
1

Using an iFrame & HTML5 Local Storage

Save the templates for rendering later...

not stoked about the iFrame, but it seems to be working pretty good (haven't ran performance tests yet)


Put the iFrame on the page you want the template on (index.html)

<html>
  <head>
    <iframe src="mustache.Users.html" onload="this.remove();" class="hidden" id="users_template"></iframe>
  </head>
</html>
  • Make sure the src attribute is set
  • hide the element until you can get rid of it after it loads

Put this body wrapper around your template (mustache.Users.html)

(don't worry it won't show up in the template)

<body onload="localStorage.setItem('users_template',this.document.body.innerHTML);"> 
  <ul class="list-group" id="users" >
    {{#users}}<li>{{name}}</li>{{/users}}
  </ul>
</body>
  • replace 'users_template' with whatever name for your variable
  • the 'onload' attribute saves the template into localStorage during load

Now You can access your templates from anywhere

localStorage.getItem('users_template')  

OR

window.localStorage.getItem('users_template')

check out this image to see it in Chrome

oLinkWebDevelopment
  • 1,841
  • 15
  • 8
0

The way that most JavaScript import files work is they include a script, that immediately calls a function with a parameter of certain text, or of another function. To better illustrate, say you have your main index.html file, set it up like this:

<html>
<head>
</head>
<body>
<script>
let modules = {};
function started(moduleName, srcTxt) {
    modules[moduleName] = (srcTxt) //or something similar
}
</script>

<!--now you can include other script tags, and any script tags that will be included, their source can be gotten (if set up right, see later)-->

<script src="someOtherFile.js"></script>
</body>
</html>

now make that other file, someOtherFile.js, and right away when its loaded, simply call that "started" function which should already be declared in the scope, and when thats done, then whatever text is passed, from the file, is stored in the main index.html file. You can even stringify an entire function and put it in, for example:

started("superModule", (function() {
    /*
    <?myCustomTemplateLanguage
    <div>
    {something}Entire Javascript / html template file goes here!!{/something}
    </div>
    ?>
    */
}).toString());

now you can access the inner content of the function, and get all the text in between the comments, or better yet, then do other parsing etc, or make some other kind of parsing identifiers at the beginning and end of the comments, as shown above, and get all text in between those

0

What is in the JavaScript file? If it's actual code, you can run functions and reference variables in there just like you had cut and paste them into the webpage. You'll want to put the include line above any script blocks that reference it.

Is this what your looking to accomplish?

ICodeForCoffee
  • 3,187
  • 2
  • 30
  • 40
0

Why not use Ajax (well Ajah because its html :-))?

when the server is set up correctly and no no-cache or past expires headers are sent, the browser will cache it.

Michael Siebert
  • 2,378
  • 1
  • 20
  • 17
  • If I put this "" in the top of my page and then call template.html via ajax and have it use the cached version that was gotten previously? – vdh_ant Jun 13 '09 at 05:27