【问题标题】:How to detect whether a plugin or script has already been loaded without using eval() or requireJS?如何在不使用 eval() 或 requireJS 的情况下检测是否已加载插件或脚本?
【发布时间】:2013-05-29 16:01:01
【问题描述】:

我正在开发一个插件,该插件允许将第 3 方代码注入页面(作为 iframe 或直接注入 DOM)。

我的问题是“直接注入”,因为我需要确保,如果在我的主页和我正在加载和注入的页面中需要它们,我不会再添加任何

例如(我不能使用 requireJS),我的page.html 看起来像这样:

<html>
  <head>
   <script type="text/js" src="jquery.js"></script> // exports window.$
   <script type="text/js" src="foo.js"></script>    // exports window.foo 
  </head>
  <body>
    <!-- things that make foo load anotherPage.html and append its content here -->
  </body>
 </html>

anotherPage.html

 <html>
  <head>
   <script type="text/js" src="foo.js"></script>    // exports window.foo 
  </head>
  <body>
    <!-- stuff that also runs on FOO -->
  </body>
 </html>

页面加载是通过 Ajax 完成的,当我处理我对 anotherPage.html 的请求返回的 data 时,我最终会得到一个所有元素的列表:

    cleanedString = ajaxResponseData
        .replace(priv.removeJSComments, "")
        .replace(priv.removeHTMLComments,"")
        .replace(priv.removeLineBreaks, "")
        .replace(priv.removeWhiteSpace, " ")
        .replace(priv.removeWhiteSpaceBetweenElements, "><");
    // this will return a list with head and body elements
    // e.g. [meta, title, link, p, div, script.foo]
    content = $.parseHTML(cleanedString, true);
    // insert into DOM
    someTarget.append(content);

这是我试图检测我要附加到文档的脚本是否已经存在的地方。

我不能使用src,因为文件名可能不同,并且脚本可能托管在不同的域上(Access-Control-Allow-Origin 设置正确)。我也不知道,如果我要附加的脚本返回一个我已经定义的全局变量,我不能/不想使用eval() 来找出答案。

问题
当我只有“未附加”的

谢谢!

【问题讨论】:

  • if(self.$ && self.foo){ 做事; }
  • 嗯。听起来太容易了。让我试试。
  • 你甚至可以让它等待:(function wait(){ if(!self.$){return setTimeout(wait, 100);}; do Stuff() }());跨度>
  • 但是如果我不知道foo 的名字怎么办?在requireJs中,我会知道我的模块foo.js导出foo,所以当模块被重新请求时,它不会被再次加载。
  • 我的模式不会双重加载那里的东西。本质上,它是 requireJS 等人所做的分解和简化版本,您可以对其进行修改以使其 DRYer 满足您的需求;如果可以的话,我很乐意伸出援手。

标签: javascript jquery ajax eval instance


【解决方案1】:

这是我的自封闭模块模式的一个例子,我称之为“哨兵”:

 (function wait(){ 

   if(!self.$){
       if(!wait.waitingJQ){
             wait.waitingJQ=true;
             addScriptTag(JQUERY_URL); 
       }
       return setTimeout(wait, 44);
   } 

   doStuffThatNeedsJquery();

 }());

哨兵模式可以在任何地方(内部或外部)工作,不关心脚本加载顺序,并且适用于任何脚本加载库。您可以以相同的方式在 jQuery fork 下方列出其他依赖项,只需将您的贪婪代码放在哨兵包装函数的底部即可。

【讨论】:

  • 回复:cmt.是的,您需要每个脚本文件中的确凿证据才能使用它。由于您暗示每个脚本都提供依赖项,因此您应该能够从您的页面访问/嗅探该依赖项。最坏的情况是,您可以将确凿证据附加到自定义脚本文件中,以用于 polyfill 等半不可见脚本。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-01-04
  • 2017-05-24
  • 1970-01-01
  • 2011-08-18
  • 2013-04-12
相关资源
最近更新 更多