如何判断JavaScript文件是否已包含在ASP.NET页面中?

时间:2022-03-22 04:16:44

I have an ASP.NET user control (.ascx file). In this user control I want to use a .js file.

我有一个ASP.NET用户控件(.ascx文件)。在这个用户控件中我想使用.js文件。

So I include <script src="file.js" type"text/javascript"></script> on the page.

所以我在页面上包含

However, sometimes I use this user control in a webpage where this same script has already been loaded.

但是,有时我会在已加载此相同脚本的网页中使用此用户控件。

How can I add a <script /> declaration that will render on the page only if the page doesn't already contain another <script /> tag for the same script?

如果页面尚未包含同一脚本的另一个标记,如何添加仅在页面上呈现的声明?

7 个解决方案

#1


12  

As you are using asp.net, it makes sense to do the check server-side as that will be where you choose to add the reference to the javascript file. From your .ascx file you could register with the following:

当您使用asp.net时,检查服务器端是有意义的,因为这将是您选择添加对javascript文件的引用的位置。从.ascx文件中,您可以注册以下内容:

this.Page.ClientScript.RegisterClientScriptInclude("GlobalUnqiueKey", UrlOfJavascriptFile);

... from your page you just call the ClientScript object directly:

...从您的页面直接调用ClientScript对象:

ClientScript.RegisterClientScriptInclude("GlobalUnqiueKey", UrlOfJavascriptFile);

The 'GlobalUniqueKey' can be any string (I use the url of the javascript file for this too)

'GlobalUniqueKey'可以是任何字符串(我也使用javascript文件的url)

If you try to register a script with the same key string, it doesn't do anything. So if you call this in your page, your control or anywhere else, you'll end up with only one reference in your page. The benefit of this is that you can have multiple instances of a control on a page and even though they all try to register the same script, it is only ever done a maximum of one time. And none of them need to worry about the script being already registered.

如果您尝试使用相同的键字符串注册脚本,则它不会执行任何操作。因此,如果您在自己的页面,控件或其他任何地方调用此内容,则最终只会在页面中显示一个引用。这样做的好处是,您可以在页面上拥有多个控件实例,即使它们都尝试注册相同的脚本,也只能执行最多一次。并且他们都不必担心脚本已经注册。

There is a 'IsClientScriptIncludeRegistered(stringkey)' method which you can use to see if a script has already been included under that key but it seems pretty redundant to do that check before registering as multiple attempts to register do not throw exceptions or cause any other errors.

有一个'IsClientScriptIncludeRegistered(stringkey)'方法,您可以使用该方法查看脚本是否已包含在该键下,但在注册多次尝试注册之前执行该检查似乎非常多余,不会抛出异常或导致任何其他错误。

Doing the check client-side means that, assuming the multiple javascript references are cached by the browser (they may not be), you still have multiple tags and the over head of each one causing some javascript to run. If you had 20 instances of your control on a page, you could get serious issues.

执行检查客户端意味着,假设浏览器缓存了多个javascript引用(它们可能不是),您仍然有多个标记,每个标记的顶部都会导致一些javascript运行。如果您在页面上有20个控件实例,则可能会出现严重问题。

#2


6  

You can do one of two things client side...

你可以做客户端的两件事之一......

  1. Check the dom for the script tag corresponding to the javascript file your want to check
  2. 检查dom以查找与您要检查的javascript文件对应的脚本标记
  3. Test a variable or function you know has/will be defined within the javascript file for undefined.
  4. 测试你知道已经/将要在javascript文件中定义的变量或函数是否为undefined。

Here's a quick JS function which uses JQuery to do what you need:

这是一个快速的JS函数,它使用JQuery来完成你需要的东西:

function requireOnce(url) {    
    if (!$("script[src='" + url + "']").length) {
        $('head').append("<script type='text/javascript' src='" + url + "'></script>"); 
    }
}

#3


0  

use something like the following:

使用类似以下内容:

if(typeof myObjectOrFunctionDecalredInThisScript != 'undefined') {
  // code goes here
  var myObjectOrFunctionDecalredInThisScript = { };
}

This tests if your object or function already exists and thus prevents redeclaration.

这将测试您的对象或功能是否已存在,从而阻止重新声明。

#4


0  

var storePath = [];
function include(path){
if(!storePath[path]){
    storePath[path]= true;
    var e = document.createElement("script");
    e.src = path;
    e.type = "text/javascript";
    document.getElementsByTagName("head")[0].appendChild(e);
    return false;
 } }

use this in your main page and call function include with argument javascript file name

在你的主页面中使用它,并使用参数javascript文件名调用函数include

#5


0  

As you want to include javascript on one page of your site only.
If you use Asp.net(4.0) then it is very easy.
Just include following code

因为您只想在您网站的一个页面上添加javascript。如果您使用Asp.net(4.0),那么它非常简单。只需包含以下代码

<script type="text/javascript" scr="filepath and name here"></script>

in ContentPlaceHolder of content page.

在内容页面的ContentPlaceHolder中。

#6


0  

@Shimmy I am coming across this after a long while but maybe it might still be useful or at least help other coming from behind. To check if jquery is already loaded do this

@Shimmy很长一段时间我都会遇到这个问题,但也许它可能仍然有用,或者至少可以帮助其他人从后面来。要检查jquery是否已加载,请执行此操作

<script>window.jQuery || document.write('<script src="js/libs/jquery-1.x.x.min.js"><\/script>')</script>

Don't miss the escape character in the closing script tag in document.write statement.

不要错过document.write语句中关闭脚本标记中的转义字符。

@mysomic, why did I not think of that. thumbs up

@mysomic,为什么我没有想到这一点。竖起大拇指

PS: I would have loved to write this right under the line where @Shimmy wrote that jQuery itself is the script he wants to load. But dont know how to write it there. cant see a reply or anything similar link. This may sound dumb but maybe I'm missing something. Pls point it out, anybody?

PS:我本来喜欢在@Shimmy写道jQuery本身就是他想加载的脚本的行下写这个。但不知道如何在那里写它。无法看到回复或任何类似的链接。这可能听起来很愚蠢,但也许我错过了一些东西。请指出,任何人?

#7


-1  

If you need it from server side, and Page.ClientScript.RegisterClientScriptInclude won't work for you in case script was included by some other way other then Page.ClientScript.RegisterClientScript (for example page.Header.Controls.Add(..), you can use something like this:

如果你需要从服务器端,并且Page.ClientScript.RegisterClientScriptInclude对你不起作用,以防除了Page.ClientScript.RegisterClientScript之外的其他方式包含脚本(例如page.Header.Controls.Add(..) ,你可以使用这样的东西:

static public void AddJsFileToHeadIfNotExists(Page page, string jsRelativePath)
{
    foreach (Control ctrl in page.Header.Controls)
    {
        if (ctrl is HtmlLink htmlLink)
        {
            if (htmlLink.Href.ToLower().Contains(jsRelativePath.ToLower())) return;
        }
        if (ctrl is ITextControl textControl
          && (textControl is LiteralControl || textControl is Literal))
        {
            if (textControl.Text.ToLower().Contains(jsRelativePath.ToLower())) return;
        }
        if (ctrl is HtmlControl htmlControl)
        {
            if (htmlControl.Attributes["src"]?.ToUpper()
              .Contains(jsRelativePath.ToUpper())) return;
        }
    }

    HtmlGenericControl Include = new HtmlGenericControl("script");
    Include.Attributes.Add("type", "text/javascript");
    Include.Attributes.Add("src", page.ResolveUrl(jsRelativePath));
    page.Header.Controls.Add(Include);    
}

#1


12  

As you are using asp.net, it makes sense to do the check server-side as that will be where you choose to add the reference to the javascript file. From your .ascx file you could register with the following:

当您使用asp.net时,检查服务器端是有意义的,因为这将是您选择添加对javascript文件的引用的位置。从.ascx文件中,您可以注册以下内容:

this.Page.ClientScript.RegisterClientScriptInclude("GlobalUnqiueKey", UrlOfJavascriptFile);

... from your page you just call the ClientScript object directly:

...从您的页面直接调用ClientScript对象:

ClientScript.RegisterClientScriptInclude("GlobalUnqiueKey", UrlOfJavascriptFile);

The 'GlobalUniqueKey' can be any string (I use the url of the javascript file for this too)

'GlobalUniqueKey'可以是任何字符串(我也使用javascript文件的url)

If you try to register a script with the same key string, it doesn't do anything. So if you call this in your page, your control or anywhere else, you'll end up with only one reference in your page. The benefit of this is that you can have multiple instances of a control on a page and even though they all try to register the same script, it is only ever done a maximum of one time. And none of them need to worry about the script being already registered.

如果您尝试使用相同的键字符串注册脚本,则它不会执行任何操作。因此,如果您在自己的页面,控件或其他任何地方调用此内容,则最终只会在页面中显示一个引用。这样做的好处是,您可以在页面上拥有多个控件实例,即使它们都尝试注册相同的脚本,也只能执行最多一次。并且他们都不必担心脚本已经注册。

There is a 'IsClientScriptIncludeRegistered(stringkey)' method which you can use to see if a script has already been included under that key but it seems pretty redundant to do that check before registering as multiple attempts to register do not throw exceptions or cause any other errors.

有一个'IsClientScriptIncludeRegistered(stringkey)'方法,您可以使用该方法查看脚本是否已包含在该键下,但在注册多次尝试注册之前执行该检查似乎非常多余,不会抛出异常或导致任何其他错误。

Doing the check client-side means that, assuming the multiple javascript references are cached by the browser (they may not be), you still have multiple tags and the over head of each one causing some javascript to run. If you had 20 instances of your control on a page, you could get serious issues.

执行检查客户端意味着,假设浏览器缓存了多个javascript引用(它们可能不是),您仍然有多个标记,每个标记的顶部都会导致一些javascript运行。如果您在页面上有20个控件实例,则可能会出现严重问题。

#2


6  

You can do one of two things client side...

你可以做客户端的两件事之一......

  1. Check the dom for the script tag corresponding to the javascript file your want to check
  2. 检查dom以查找与您要检查的javascript文件对应的脚本标记
  3. Test a variable or function you know has/will be defined within the javascript file for undefined.
  4. 测试你知道已经/将要在javascript文件中定义的变量或函数是否为undefined。

Here's a quick JS function which uses JQuery to do what you need:

这是一个快速的JS函数,它使用JQuery来完成你需要的东西:

function requireOnce(url) {    
    if (!$("script[src='" + url + "']").length) {
        $('head').append("<script type='text/javascript' src='" + url + "'></script>"); 
    }
}

#3


0  

use something like the following:

使用类似以下内容:

if(typeof myObjectOrFunctionDecalredInThisScript != 'undefined') {
  // code goes here
  var myObjectOrFunctionDecalredInThisScript = { };
}

This tests if your object or function already exists and thus prevents redeclaration.

这将测试您的对象或功能是否已存在,从而阻止重新声明。

#4


0  

var storePath = [];
function include(path){
if(!storePath[path]){
    storePath[path]= true;
    var e = document.createElement("script");
    e.src = path;
    e.type = "text/javascript";
    document.getElementsByTagName("head")[0].appendChild(e);
    return false;
 } }

use this in your main page and call function include with argument javascript file name

在你的主页面中使用它,并使用参数javascript文件名调用函数include

#5


0  

As you want to include javascript on one page of your site only.
If you use Asp.net(4.0) then it is very easy.
Just include following code

因为您只想在您网站的一个页面上添加javascript。如果您使用Asp.net(4.0),那么它非常简单。只需包含以下代码

<script type="text/javascript" scr="filepath and name here"></script>

in ContentPlaceHolder of content page.

在内容页面的ContentPlaceHolder中。

#6


0  

@Shimmy I am coming across this after a long while but maybe it might still be useful or at least help other coming from behind. To check if jquery is already loaded do this

@Shimmy很长一段时间我都会遇到这个问题,但也许它可能仍然有用,或者至少可以帮助其他人从后面来。要检查jquery是否已加载,请执行此操作

<script>window.jQuery || document.write('<script src="js/libs/jquery-1.x.x.min.js"><\/script>')</script>

Don't miss the escape character in the closing script tag in document.write statement.

不要错过document.write语句中关闭脚本标记中的转义字符。

@mysomic, why did I not think of that. thumbs up

@mysomic,为什么我没有想到这一点。竖起大拇指

PS: I would have loved to write this right under the line where @Shimmy wrote that jQuery itself is the script he wants to load. But dont know how to write it there. cant see a reply or anything similar link. This may sound dumb but maybe I'm missing something. Pls point it out, anybody?

PS:我本来喜欢在@Shimmy写道jQuery本身就是他想加载的脚本的行下写这个。但不知道如何在那里写它。无法看到回复或任何类似的链接。这可能听起来很愚蠢,但也许我错过了一些东西。请指出,任何人?

#7


-1  

If you need it from server side, and Page.ClientScript.RegisterClientScriptInclude won't work for you in case script was included by some other way other then Page.ClientScript.RegisterClientScript (for example page.Header.Controls.Add(..), you can use something like this:

如果你需要从服务器端,并且Page.ClientScript.RegisterClientScriptInclude对你不起作用,以防除了Page.ClientScript.RegisterClientScript之外的其他方式包含脚本(例如page.Header.Controls.Add(..) ,你可以使用这样的东西:

static public void AddJsFileToHeadIfNotExists(Page page, string jsRelativePath)
{
    foreach (Control ctrl in page.Header.Controls)
    {
        if (ctrl is HtmlLink htmlLink)
        {
            if (htmlLink.Href.ToLower().Contains(jsRelativePath.ToLower())) return;
        }
        if (ctrl is ITextControl textControl
          && (textControl is LiteralControl || textControl is Literal))
        {
            if (textControl.Text.ToLower().Contains(jsRelativePath.ToLower())) return;
        }
        if (ctrl is HtmlControl htmlControl)
        {
            if (htmlControl.Attributes["src"]?.ToUpper()
              .Contains(jsRelativePath.ToUpper())) return;
        }
    }

    HtmlGenericControl Include = new HtmlGenericControl("script");
    Include.Attributes.Add("type", "text/javascript");
    Include.Attributes.Add("src", page.ResolveUrl(jsRelativePath));
    page.Header.Controls.Add(Include);    
}