ASP.Net - AJAX UpdatePanel中的Javascript

时间:2009-12-23 13:28:03

标签: javascript asp.net ajax jscolor

我遇到了从UpdatePanel内部的外部javascript文件运行javascript的问题。我试图让一个颜色选择器在ListView内部工作。 ListView位于UpdatePanel内。

我正在使用this color picker

以下是我将其缩小为:

  • 如果我在UpdatePanel之外的文本框中使用颜色选择器,它在所有回发中都可以正常工作。

  • 如果我在UpdatePanel内的文本框中使用颜色选择器,它会起作用,直到我执行异步回发(单击ListView中的“编辑”按钮)。 UpdatePanel完成回发后,单击时文本框将不再显示颜色选择器。当文本框位于ListView的InsertItemTemplateEditItemTemplate时,也会出现同样的情况。

如果您想复制它,只需下载颜色选择器(它是免费的),然后将其添加到网页...

<asp:ScriptManager ID="ScriptManager1" runat="server">
</asp:ScriptManager>

<div>
    <asp:UpdatePanel ID="panel1" runat="server">
        <ContentTemplate>
            <asp:TextBox runat="server" ID="textbox" CssClass="color" />
            <asp:Button ID="Button1" runat="server" Text="Button" />
        </ContentTemplate>
    </asp:UpdatePanel>
</div>

页面加载时,颜色选择器工作正常。当您单击按钮(执行回发)时,颜色选择器将不再起作用。

有什么想法吗?

4 个答案:

答案 0 :(得分:15)

在异步往返之后,将不会运行任何启动脚本,这可能是为什么它在AJAX回调之后不起作用的原因。颜色选择器可能具有需要在页面加载时执行的功能。

我遇到过这么多次,我写了一个小方法来在代码隐藏中注册我的脚本,它处理异步和非异步往返。这是基本概要:

private void RegisterClientStartupScript(string scriptKey, string scriptText)
{
    ScriptManager sManager = ScriptManager.GetCurrent(this.Page);

    if (sManager != null && sManager.IsInAsyncPostBack)
    {
        //if a MS AJAX request, use the Scriptmanager class
        ScriptManager.RegisterStartupScript(this.Page, this.Page.GetType(), scriptKey, scriptText, true);
    }
    else
    {
        //if a standard postback, use the standard ClientScript method
        scriptText = string.Concat("Sys.Application.add_load(function(){", scriptText, "});");
        this.Page.ClientScript.RegisterStartupScript(this.Page.GetType(), scriptKey, scriptText, true);
    }
}

我实际上已将上述内容编入基页类,以便我正在使用的任何页面都可以调用this.RegisterClientStartupScript(...)。要做到这一点,只需创建一个基页类并将其包含在那里(确保标记为protected not private或您的继承页面类将无法访问它)。

使用上面的代码,无论页面是在进行回发还是回调,我都可以自信地注册客户端脚本。意识到您正在使用外部脚本文件,您可以修改上述方法来注册外部脚本而不是内联脚本。有关详细信息,请参阅ScriptManager类,因为有几种脚本注册方法......

答案 1 :(得分:2)

在查看jscolor源代码后,我注意到它在窗口加载时初始化了所有内容。因此,您可能需要使用类似的东西重新初始化(在UpdatePanel内部):

function yourInit(){
   /* keep in mind that the jscolor.js file has no way to determine
      that the script has already been initialized, and you may end
      up initializing it twice, unless you remove jscolor.install();
   */

   if (typeof(jscolor) !== 'undefined'){
      jscolor.init();
   }
}
if (typeof(Sys) !== 'undefined'){
   Sys.UI.DomEvent.addHandler(window, "load", yourInit);
}
else{
   // no ASP.NET AJAX, use your favorite event
   // attachment method here
}

如果您决定将jscolor脚本放在UpdatePanel中,您还需要在jscolor.js的末尾添加这样的内容:

if(Sys && Sys.Application){
   Sys.Application.notifyScriptLoaded();
}

答案 2 :(得分:1)

您是否尝试过ScriptManager.RegisterStartupScript,它允许您“在执行异步回发时将JavaScript从服务器添加到页面中”?

答案 3 :(得分:0)

我猜想运行设置颜色选择器的jscolor.js代码仅在您的页面首次加载时被调用,因此当在服务器上重新生成控件时,您将丢失jscolor所做的更改。你可以注册一些在你的代码后面调用的javascript,以便在你的异步调用完成时调用jscolor上的init方法吗?