Когда вызывается jGrowl, Thickbox перестает работать должным образом (с помощью UpdatePanel)
Я звоню в толстую коробку, когда ссылка нажата:
<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 показывается первым, чем Thickbox. Это приведет к тому, что Thickbox не будет работать, и страница будет отображаться как обычный веб-сайт (как если бы Thickbox ушел).
Кто-нибудь знает, что происходит?
ОБНОВЛЕНИЕ: это тестовая страница без главной страницы:
<%@ 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, вызываемым из codebehind.
Я был бы очень признателен за вашу помощь, ребята.
ОБНОВЛЕНИЕ: я даже создал демонстрационный проект, где эта проблема может быть легко идентифицирована. Не против отправить его любому, кто захочет мне помочь с этим. Заранее спасибо, ребята!
ОБНОВЛЕНИЕ: я также попробовал решение, данное @Rick, изменив способ выполнения скрипта jGrowl из codebehind:
ScriptManager.RegisterStartupScript(this.Page, typeof(Page), Guid.NewGuid().ToString(),
"$.jGrowl('My Message');", true);
Тем не менее, проблема сохраняется, так как результат точно такой же. Есть другие идеи? Я был бы очень признателен за вашу помощь.
ОБНОВЛЕНИЕ: я также попробовал это в IE8 и Chrome, столкнувшись с той же проблемой. Таким образом, это не имеет ничего общего с браузером. Так, на всякий случай.
3 ответа
Я считаю, что ваша проблема не имеет ничего общего с jGrowl, и все, что связано с использованием вами UpdatePanel.
Когда вы используете UpdatePanel, он обновляет все содержащиеся в нем элементы DOM. Это означает, что оригинал <a>
тег, созданный на странице и для которого было установлено событие click для использования Thickbox, больше не существует. После обновления UpdatePanel у вас теперь есть НОВЫЙ <a>
тег, который имеет класс Thickbox, но не был "инициализирован" (так как Thickbox устанавливает обработчик кликов во время загрузки страницы, что не происходит, как обычно, при частичной обратной передаче). Следовательно, когда вы нажимаете на ссылку, она действует как обычная ссылка.
Есть несколько способов исправить это, в зависимости от вашей ситуации.
Вариант 1. Исходя из вашего кода, вставленного выше, не похоже, что на самом деле что-то меняется, связанное со ссылкой, во время обработки обратной передачи. Так что, возможно, вы могли бы переместить <div><a ...></a> </div>
за пределами UpdatePanel и оставьте только кнопку внутри. Это сохранит вашу ссылку как часть страницы, и к ней по-прежнему будет прикреплен обработчик Thickbox.
Вариант 2. Если есть какая-то причина, по которой вы не можете использовать Вариант 1, тогда вы можете настроить запуск JavaScript во время загрузки UpdatePanel, чтобы повторно прикрепить обработчик кликов для вашей ссылки. В функции, которая вызывает jGrowl, попробуйте добавить tb_init('a.thickbox');
к вашему коду.
Вариант 3: Вы можете изменить файл Thickbox.js, чтобы использовать живой обработчик jQuery вместо обычного обработчика щелчков. в tb_init
функция, вы бы изменили его на $(domChunk).live('click', function(){..})
, Я думаю, что это будет работать, хотя возможно, что процесс обновления панели все еще может помешать этому.
Надеюсь это поможет.
Я не совсем понимаю архитектуру вашей страницы, но, как отмечает @patmortech, UpdatePanel
вызывает полную замену элементов DOM при каждой асинхронной обратной передаче. Вам необходимо перепривязать любые затронутые элементы.
$(document).ready
недостаточно хорош, когда вы имеете дело с панелями обновления. Он будет вызываться только при первой загрузке страницы (не после UpdatePanel
обновить). Решение состоит в том, чтобы подключиться к архитектуре ajax ASP.NET для вашего кода конфигурации.
Какой бы код вы ни использовали для настройки ссылок ThickBox и jGrowl, добавьте сюда:
Sys.WebForms.PageRequestManager.getInstance().add_endRequest(function() {
// page config code
});
Это вызывается в конце жизненного цикла клиента ASP.NET, поэтому поместите свой конфигурационный код для всего в пределахUpdatePanel
там. Если у вас есть несколько UpdatePanels, вы можете проверить, какие из них были обновлены (google add_endRequest). Однако зачастую проще просто использовать состояние разметки клиента, чтобы определить, нужно ли вам что-то настраивать или нет, или просто использовать конфигурационный код, который не сломает вещи, если дважды выполнить одну и ту же разметку.
Использование jquery live
также вариант, но он не работает для всех ситуаций.
protected void Button1_Click(object sender, EventArgs e)
{
ScriptManager.RegisterStartupScript(this.Page, typeof(Page), Guid.NewGuid().ToString(),
"$.jGrowl('My Message');", true);
}