当 jGrowl 被调用时,thickbox 停止正常工作(使用 UpdatePanel)

发布于 2024-12-03 17:42:09 字数 3181 浏览 4 评论 0原文

单击链接时,我调用厚盒:

<a href="createContact.aspx?placeValuesBeforeTB_=savedValues&TB_iframe=true&height=400&width=550&modal=true"
                            title="Add a new Contact" class="thickbox">Add a new Contact</a>

并且,单击服务器按钮时,我调用此 javascript 函数来显示 jGrowl 通知:

ScriptManager.RegisterClientScriptBlock(this, typeof(Page), Guid.NewGuid().ToString(), "$(function(){$.jGrowl('No Contact found: " + searchContactText.Text + "');});", true);

两者均按预期工作,除非 jGrowl 先于厚盒显示。这将导致厚盒无法工作,页面将显示为普通网页(就好像厚盒已经消失一样)。

有谁知道发生了什么事?

更新:这是没有母版页的测试页:

<%@ Page Language="C#" AutoEventWireup="true" CodeBehind="WebForm2.aspx.cs" Inherits="RoutingPortal.Presentation.WebForm2" %>

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">

<html xmlns="http://www.w3.org/1999/xhtml">
<head runat="server">
<title></title>
<script src="../Scripts/jquery-1.6.2.js" type="text/javascript"></script>
<script src="../Scripts/jquery-ui-1.8.16.custom.min.js" type="text/javascript"></script>
<script src="../Scripts/thickbox.js" type="text/javascript"></script>
<script src="../Scripts/jquery.jgrowl.js" type="text/javascript"></script>
<link href="../Scripts/css/jquery.jgrowl.css" rel="stylesheet" type="text/css" />
<link rel="stylesheet" href="~/CSS/thickbox.css" type="text/css" media="screen" />
</head>
<body>
<form id="form1" runat="server">
<asp:ScriptManager ID="ScriptManager1" runat="server">
</asp:ScriptManager>
<asp:UpdatePanel ID="UpdatePanel1" runat="server">
<ContentTemplate>
<div>
    <a href="createContact.aspx?placeValuesBeforeTB_=savedValues&TB_iframe=true&height=400&width=550&modal=true"
            title="Add a new Contact" class="thickbox">Add a new Contact</a>
        <asp:Button ID="Button1" runat="server" Text="Button" OnClick="Button1_Click" />
</div>
</ContentTemplate>
</asp:UpdatePanel>
</form>
</body>
</html>

这是隐藏的代码:

namespace RoutingPortal.Presentation
{
public partial class WebForm2 : System.Web.UI.Page
{
    protected void Page_Load(object sender, EventArgs e)
    {

    }

    protected void Button1_Click(object sender, EventArgs e)
    {
        ScriptManager.RegisterClientScriptBlock(this.Page, typeof(Page), Guid.NewGuid().ToString(),
                "$(function(){$.jGrowl('My Message');});", true);
    }
}
}

我刚刚在没有 UpdatePanel 的情况下测试了它,它工作得很好。因此,这绝对是 UpdatePanel 的问题,或者是它与从代码隐藏调用的 jGrowl 交互的方式的问题。

我非常感谢你们的帮助。

更新:我什至创建了一个演示项目,可以轻松识别这个问题。不介意将其发送给任何愿意帮助我解决此问题的人。预先感谢各位!

更新:我还尝试了@Rick 给出的解决方案,更改了从代码隐藏执行 jGrowl 脚本的方式:

ScriptManager.RegisterStartupScript(this.Page, typeof(Page), Guid.NewGuid().ToString(),
        "$.jGrowl('My Message');", true);

但是,问题仍然存在,因为结果完全相同。还有其他想法吗?我非常感谢你的帮助。

更新:我也在 IE8 和 Chrome 中尝试过,面临同样的问题。所以,这与浏览器无关。万一。

I am calling a thickbox when a link is clicked:

<a href="createContact.aspx?placeValuesBeforeTB_=savedValues&TB_iframe=true&height=400&width=550&modal=true"
                            title="Add a new Contact" class="thickbox">Add a new Contact</a>

And, when a server button is clicked I call this javascript function to show a jGrowl notification:

ScriptManager.RegisterClientScriptBlock(this, typeof(Page), Guid.NewGuid().ToString(), "$(function(){$.jGrowl('No Contact found: " + searchContactText.Text + "');});", true);

Both works as expected except when the jGrowl is shown first than the thickbox. This will cause the thickbox not to work and the page will be shown as a normal web (as if the thickbox had been gone).

Does anyone know what is happening?

UPDATE: This is the a test page without Master Page:

<%@ Page Language="C#" AutoEventWireup="true" CodeBehind="WebForm2.aspx.cs" Inherits="RoutingPortal.Presentation.WebForm2" %>

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">

<html xmlns="http://www.w3.org/1999/xhtml">
<head runat="server">
<title></title>
<script src="../Scripts/jquery-1.6.2.js" type="text/javascript"></script>
<script src="../Scripts/jquery-ui-1.8.16.custom.min.js" type="text/javascript"></script>
<script src="../Scripts/thickbox.js" type="text/javascript"></script>
<script src="../Scripts/jquery.jgrowl.js" type="text/javascript"></script>
<link href="../Scripts/css/jquery.jgrowl.css" rel="stylesheet" type="text/css" />
<link rel="stylesheet" href="~/CSS/thickbox.css" type="text/css" media="screen" />
</head>
<body>
<form id="form1" runat="server">
<asp:ScriptManager ID="ScriptManager1" runat="server">
</asp:ScriptManager>
<asp:UpdatePanel ID="UpdatePanel1" runat="server">
<ContentTemplate>
<div>
    <a href="createContact.aspx?placeValuesBeforeTB_=savedValues&TB_iframe=true&height=400&width=550&modal=true"
            title="Add a new Contact" class="thickbox">Add a new Contact</a>
        <asp:Button ID="Button1" runat="server" Text="Button" OnClick="Button1_Click" />
</div>
</ContentTemplate>
</asp:UpdatePanel>
</form>
</body>
</html>

This is the codebehind:

namespace RoutingPortal.Presentation
{
public partial class WebForm2 : System.Web.UI.Page
{
    protected void Page_Load(object sender, EventArgs e)
    {

    }

    protected void Button1_Click(object sender, EventArgs e)
    {
        ScriptManager.RegisterClientScriptBlock(this.Page, typeof(Page), Guid.NewGuid().ToString(),
                "$(function(){$.jGrowl('My Message');});", true);
    }
}
}

I have just tested it without the UpdatePanel and it worked perfectly. So, it is definitely a problem with the UpdatePanel or the way that it is interacting with the jGrowl called from the codebehind.

I would massively appreciate your help guys.

UPDATE: I have even created a demo project where this problem can be easily identified. Wouldn't mind to send it to anyone willing to help me out with this. Thanks in advance guys!

UPDATE: I have also tried the solution given by @Rick, changing the way the jGrowl script is executed from codebehind:

ScriptManager.RegisterStartupScript(this.Page, typeof(Page), Guid.NewGuid().ToString(),
        "$.jGrowl('My Message');", true);

However, the problem persist since the outcome is exactly the same. Any other ideas? I'd massively appreciate your help.

UPDATE: I have also tried this in IE8 and Chrome, facing the same problem. So, this is nothing to do with the browser. Just in case.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

花之痕靓丽 2024-12-10 17:42:09

我相信您的问题与 jGrowl 无关,而与您使用 UpdatePanel 有关。

当您使用 UpdatePanel 时,它会刷新其中包含的 DOM 中的所有元素。这意味着在页面中创建且其点击事件设置为使用厚盒的原始 标记不再存在。 UpdatePanel 刷新后,您现在有一个新的 标记,该标记具有 Thickbox 类,但尚未“初始化”(因为 Thickbox 在页面加载期间设置点击处理程序,这不会在部分回发期间像平常一样发生)。因此,当您单击该链接时,它的作用就像普通链接一样。

有多种方法可以解决此问题,具体取决于您的情况。

选项 1:根据上面粘贴的代码,在回发处理期间,看起来并没有与链接相关的任何实际更改。所以也许你可以移动你的

位于 UpdatePanel 外部,仅将按钮保留在内部。这将使您的链接保留为页面的一部分,并且仍然会附加其厚盒处理程序。

选项 2:如果由于某种原因无法使用选项 1,那么您可以设置一些 javascript 在加载 UpdatePanel 期间运行,以重新附加链接的点击处理程序。在调用 jGrowl 的函数中,尝试将 tb_init('a.thickbox'); 添加到您的代码中。

选项3:您可以修改thickbox.js 文件以使用jQuery 的实时处理程序而不是普通的点击处理程序。在 tb_init 函数中,您可以将其更改为 $(domChunk).live('click', function(){..})。我认为这会起作用,尽管更新面板过程可能仍然会阻止它。

希望这有帮助。

I believe your problem has nothing to do with jGrowl, and all to do with your use of an UpdatePanel.

When you use an UpdatePanel, it refreshes all the elements in the DOM that are contained in it. What this means is that the original <a> tag that was created in the page and that had its click event set to use thickbox no longer exists. After the UpdatePanel refreshes, you now have a NEW <a> tag that has the thickbox class, but has not been "initialized" (since thickbox sets the click handler during page load, which doesn't happen like normal during a partial postback). Hence, when you click on the link, it acts like a normal link.

There are several ways to fix this, depending on your situation.

Option 1: Based on your code pasted above, it does not look like anything actually changes related to the link during your postback handling. So maybe you could move your <div><a ...></a> </div> outside of the UpdatePanel, and leave only the button inside. This will keep your link as part of the page and it will still have its thickbox handler attached.

Option 2: If there's some reason you can't go with Option 1, then you can set some javascript to run during the load of your UpdatePanel to re-attach the click handler for your link. In the function that calls jGrowl, try adding tb_init('a.thickbox'); to your code.

Option 3: You could modify the thickbox.js file to use jQuery's live handler instead of the normal click handler. In the tb_init function, you would change it to be $(domChunk).live('click', function(){..}). I think this would work, though it's possible the update panel process might still foil it.

Hope this helps.

肥爪爪 2024-12-10 17:42:09

我不完全理解您的页面架构,但正如 @patmortech 所指出的,UpdatePanel 会导致 DOM 元素在每次异步回发时被完全替换。您需要重新绑定任何受影响的元素。

当您处理 updatepanels 时, $(document).ready 还不够好。它只会在第一个页面加载时调用(而不是在 UpdatePanel 刷新之后)。解决方案是为您的配置代码挂钩 ASP.NET 的 ajax 架构。

无论您使用什么代码来配置 ThickBox 和 jGrowl 链接,请在此处添加:

Sys.WebForms.PageRequestManager.getInstance().add_endRequest(function() {
    // page config code
});

这将在 ASP.NET 客户端生命周期结束时调用,因此请将您的配置代码放在 UpdatePanel 中。如果您有多个UpdatePanel,您可以测试哪个已更新(google add_endRequest)。然而,使用客户端标记状态来确定是否需要配置某些内容通常更容易,或者只使用配置代码,如果针对相同的标记运行两次,则不会破坏内容。

使用 jquery live 也是一种选择,但它并不适用于所有情况。

I don't understand the architecture of your page completely, but as @patmortech notes the UpdatePanel causes the DOM elements to be replaced completely on each async postback. You need to rebind any affected elements.

$(document).ready is not good enough when you're dealing with updatepanels. It will only be called on the first page load (not after an UpdatePanel refresh). The solution is to hook into ASP.NET's ajax architecture for your config code.

Whatever code you are using to configure the ThickBox and jGrowl links, add here:

Sys.WebForms.PageRequestManager.getInstance().add_endRequest(function() {
    // page config code
});

This gets called at the end of the ASP.NET client lifecycle, so put your config code for anything within anUpdatePanel there. If you have multiple UpdatePanels, you can test which has been updated (google add_endRequest). However it's often easier just to use the client markup state to determine if you need to configure something or not, or just use config code that will not break things if run twice against the same markup.

Using jquery live is also an option, but it doesn't work for all situations.

西瓜 2024-12-10 17:42:09
protected void Button1_Click(object sender, EventArgs e)
{
    ScriptManager.RegisterStartupScript(this.Page, typeof(Page), Guid.NewGuid().ToString(),
            "$.jGrowl('My Message');", true);
}
protected void Button1_Click(object sender, EventArgs e)
{
    ScriptManager.RegisterStartupScript(this.Page, typeof(Page), Guid.NewGuid().ToString(),
            "$.jGrowl('My Message');", true);
}
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文