【问题标题】:Getting content of a script file using Javascript使用 Javascript 获取脚本文件的内容
【发布时间】:2010-11-02 08:40:50
【问题描述】:

我的网页中有以下脚本元素:

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

使用 JavaScript,我希望能够检索脚本文件的内容。我知道我可以使用 ajax 请求来获取数据,但是我从本地已经拥有的服务器中获取了一些东西。

所以我更愿意从 DOM 中检索内容(如果可能的话)或具有相同结果的内容。

干杯 安东尼

更新

我试图简化问题,也许是个坏主意,我认为这样会减少问题。

我的真实情况如下,其实我有

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

现在这工作正常,但这意味着每次加载页面时,我都必须将模板作为主页 HTML 的一部分发送。所以我的计划是做以下事情:

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

这意味着浏览器将缓存 template.html 的内容,而我不必每次都将其发送下来。但要做到这一点,我需要能够从文件中获取内容。

在这种情况下,据我所知,通过 ajax 请求内容并没有太大帮助,因为它必须返回服务器才能获取内容。

【问题讨论】:

  • 请问您为什么要这样做?
  • 如果可以(不能)通过 text/html 类型的脚本包含它,那么浏览器也必须返回服务器。 XMLHttpRequest 没有什么神奇的东西可以阻止缓存。

标签: javascript html dom scripting


【解决方案1】:

如果我理解正确,您不想使用 Ajax 加载 html 模板文本,而是将其与页面的其余部分一起加载。如果您控制服务器端,则始终可以将模板文本包含在一个不可见的 div 标记中,然后从 Javascript 中引用该标记:

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

如果您只是想加载模板以便缓存它,您可以将内容放在一个变量中,如下所示:

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

或者您可以使用 ajax 加载它并将模板存储在一个变量中,以便可以访问它。在 jquery 中这很简单:

var template;
$.get("template.html", function(data){
  template = data;
});

【讨论】:

  • 按照您提出的要点的顺序:1)我可以这样做,但它不会利用浏览器缓存外部引用文件的能力。我的一些模板超过 300 行。因此,能够将其放入外部文件并进行缓存是一大优势。 2) 看看我对 Ryan Oberoi 说的话 3) 是的,这很简单,问题在于客户端页面生命周期何时会发生这种情况。如果我有一个像“”这样的外部文件,它将与任何其他外部引用并行加载(假设我放了
  • 我在页面底部的所有脚本引用)。这意味着如果我将所有模板声明如下“”,浏览器将非常有效地加载这些模板。此外,如果我使用 $(document).ready(...) 在加载模板之前,我的任何 JS 都不会运行。如果我通过 ajax 进行加载,我的 javascript 在它尝试获取模板之前运行到一半,我将不得不等待它获取内容。现在确定我可以先尝试加载所有模板,但这会使事情复杂化,因为在它们之前我什么都做不了,
  • 准备好了。因此,如果我在文档头 中注册模板如下,然后通过同步 ajax 调用获取相同的页面,我的想法如下, 浏览器是否足够聪明,可以知道它已经通过脚本标签获取了文件,并且不需要返回服务器通过 ajax 获取它???
【解决方案2】:

除非您将脚本作为文本加载到页面中,否则它不会作为文本存在。它由浏览器解释并与任何其他脚本融合到运行时中。

如果你想要源你必须再次获取它,如果使用 Ajax 获取 responseText。

它将来自浏览器缓存,无需再次下载。

【讨论】:

  • 如果是这种情况,我可以把这个“”放在我的页面顶部然后调用template.html 通过 ajax 并让它使用之前获得的缓存版本?
【解决方案3】:

我认为您要做的是在 template.js 中分配一个变量。然后,您可以在 jquery 中的任何位置使用该变量。比如:

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

这不是解决您问题的更简单方法吗?我们在 Ext JS 中这样做。我认为这在 jQuery 中对你有用。

【讨论】:

  • 是的,我确实想到了这一点,但问题是我必须做的转义量。如果您的模板只有 5 行长,那么进行转义(如果需要)也不错。但如果它超过 300 行,维护起来就有点困难了。你们是怎么解决这个问题的?
  • 我在 Ext JS 中使用过大小合理的模板。如果要编码 300 行以上,请编写一个简单的工具来转义 HTML 文本。有很多选择。这会将 template.html 转换为 template.js 并转义 html 文本。使用 ruby​​ 的一个简单方法是使用 CGI.escape(str),其中 str 是从 template.html 中读取的。这种方法可能是您最好的选择。
  • 或使用预先存在的工具,例如search.cpan.org/~rkrimen/Jemplate/lib/Jemplate.pm
  • 最后我最终采用了这种方法,并编写了一个简短的脚本来将 html 内容从一个文本区域转义和取消转义到另一个文本区域,以帮助使其更容易一些。谢谢
【解决方案4】:

你可以获取脚本src的属性,然后使用XHR来获取JS文件的内容。这是一种更清洁的方式来做 IMO。例如:-

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);
            }

【讨论】:

    【解决方案5】:

    使用 iFrame 和 HTML5 本地存储

    保存模板以供稍后渲染...

    对 iFrame 不感兴趣,但它似乎工作得很好(还没有进行性能测试)


    将 iFrame 放在您希望模板放在的页面上(index.html)

    <html>
      <head>
        <iframe src="mustache.Users.html" onload="this.remove();" class="hidden" id="users_template"></iframe>
      </head>
    </html>
    
    • 确保设置了 src 属性
    • 隐藏元素,直到加载后您可以将其删除

    将此正文包装器放在您的模板周围(mustache.Users.html)

    (不用担心它不会显示在模板中)

    <body onload="localStorage.setItem('users_template',this.document.body.innerHTML);"> 
      <ul class="list-group" id="users" >
        {{#users}}<li>{{name}}</li>{{/users}}
      </ul>
    </body>
    
    • 'users_template' 替换为您的变量的任何名称
    • onload”属性在加载过程中将模板保存到 localStorage

    现在您可以从任何地方访问您的模板

    localStorage.getItem('users_template')  
    

    window.localStorage.getItem('users_template')
    

    【讨论】:

    • ...需要跨浏览器测试,仅在 chrome 中开发。如果有任何问题,请告诉我。
    【解决方案6】:

    JavaScript 文件中有什么?如果是实际代码,您可以在其中运行函数和引用变量,就像您将它们剪切并粘贴到网页中一样。您需要将包含行放在引用它的任何脚本块之上。

    这是你想要完成的事情吗?

    【讨论】:

      【解决方案7】:

      为什么不使用 Ajax(Ajah 是因为它的 html :-))?

      当服务器设置正确并且没有发送 no-cache 或过去过期的标头时,浏览器将缓存它。

      【讨论】:

      • 如果我把这个 "" 放在我的页面顶部,然后通过 ajax 调用 template.html 和是否使用了之前获取的缓存版本?
      【解决方案8】:

      大多数 JavaScript 导入文件的工作方式是它们包含一个脚本,该脚本立即调用带有特定文本参数的函数或另一个函数。为了更好地说明,假设你有你的主 index.html 文件,像这样设置它:

      <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>
      

      现在创建另一个文件someOtherFile.js,并在加载时立即调用应该已经在作用域中声明的“启动”函数,完成后,然后从文件中传递任何文本, 存储在主 index.html 文件中。您甚至可以将整个函数字符串化并将其放入,例如:

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

      现在您可以访问函数的内部内容,并获取 cmets 之间的所有文本,或者更好的是,然后进行其他解析等,或者在 cmets 的开头和结尾制作一些其他类型的解析标识符,如上所示,并获取它们之间的所有文本

      【讨论】:

        猜你喜欢
        • 2013-07-01
        • 2017-06-05
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2023-03-20
        • 2013-07-30
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多