【问题标题】:ASP.Net - Javascript inside AJAX UpdatePanelASP.Net - AJAX UpdatePanel 中的 Javascript
【发布时间】:2010-12-29 11:56:15
【问题描述】:

我遇到了从 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>

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

有什么想法吗?

【问题讨论】:

    标签: javascript asp.net ajax jscolor


    【解决方案1】:

    在异步往返之后,任何启动脚本都不会运行,这可能是它在 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(...)。为此,只需创建一个基本页面类并将其包含在其中(确保将受保护标记为非私有,否则您的继承页面类将无法访问它)。

    使用上面的代码,我可以放心地注册客户端脚本,而不管页面是在执行回发还是回调。意识到您正在使用外部脚本文件,您可能可以修改上述方法以注册外部脚本而不是内联。更多详情请咨询ScriptManager类,有多种脚本注册方法...

    【讨论】:

    • 谢谢。我用了这个方法,把jscolor.init()方法称为scriptText,现在可以了。
    • 没问题 :) 很高兴它解决了这个问题。
    • 我更喜欢 Page 类的扩展方法,而不是创建一个基页面类。非常感谢。 +1
    • 当它是标准回发时,你能帮我理解为什么你把它放在“Sys.Application.add_load(function(){}”中。我可以在我有的页面上使用它吗?没有放置 ScripManager 控件?
    • @Ismail:说实话,我不记得为什么需要 add_load 函数(我已经很久没有写上面的方法了),但我记得它与在回发期间注册的脚本要么不触发,要么在某些情况下提前触发。我在网上找到了 add_load 解决方案,它立即修复了它,所以我坚持使用它。
    【解决方案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();
    }
    

    【讨论】:

    • "if (window.Sys ...",而不是"if (Sys..."
    【解决方案3】:

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

    【讨论】:

      【解决方案4】:

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

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2010-09-29
        • 2011-09-15
        • 2010-12-18
        • 2010-09-14
        • 2011-03-25
        • 2011-02-02
        • 1970-01-01
        • 2012-12-05
        相关资源
        最近更新 更多