【问题标题】:ASP.Net jQuery dialog only shows up the first time it's hovered overASP.Net jQuery 对话框仅在第一次悬停时显示
【发布时间】:2016-05-25 20:27:40
【问题描述】:

我有一个用户控件,它有一个 UpdatePanel,里面是一个中继器,里面是链接按钮:

<%@ Control Language="C#" AutoEventWireup="true" CodeBehind="RelatedEntityControl.ascx.cs" Inherits="MyApp.Controls.Layout.RelatedURLControl" %>
<asp:UpdatePanel ID="RelatedObjectsPanel" runat="server">
<ContentTemplate>
 <script type="text/javascript">
        function openPopup(url, h, w, t, link) {
            {
                if (url != null && h != null && w != null && t != null && link != null) {
                    var btn = document.getElementById(link);
                    var top_distance = btn.getBoundingClientRect().top;
                    var left_distance = btn.getBoundingClientRect().left;
                    var myDialogX = left_distance - w/2;
                    var myDialogY = top_distance;
                    $('#PreviewWindow').html('<iframe style="border: 0px; " width="100%" height ="100%" src="' + url + '"> </iframe>');
                    $("#PreviewWindow").dialog({
                        title: t,
                        modal: false,
                        autoOpen: true,
                        height: h,
                        width: w,
                        closeOnEscape: true,
                        position: [myDialogX, myDialogY],
                        dialogClass: 'dialog_fixed,ui-widget-header',
                        open: function (event, ui) {
                            $(this).css('overflow', 'hidden'); //this line does the actual hiding of the vertical scrollbar
                        }
                    });
                }
            };
        }
    </script>
    <script type="text/javascript">
        $(function () {
            var btn = $('.previewLink');
            btn.hoverIntent(function (e) {
                e.target.click();
            }, function () { });
        });
    </script>

        <asp:Panel ID="URLPanel" runat="server" Visible="false">
        <asp:CollapsiblePanelExtender ID="URLsCollapsiblePanel" runat="server" CollapseControlID="URLsLabel" ExpandControlID="URLsLabel" TargetControlID="URLsPanel" TextLabelID="URLsLabel"
            CollapsedText="[ + ]  Related URLs" ExpandedText="[ - ]  Related URLs" />
        <asp:Label ID="URLsLabel" runat="server" CssClass="collapsiblePanelHeader" Text="" Width="90%"></asp:Label>
        <asp:Panel ID="URLsPanel" runat="server" CssClass="collapsiblePanelContent" style="height: auto;">

            <asp:Repeater ID="URLsLocalRepeater" runat="server" OnItemDataBound="LocalRepeater_ItemDataBound" ItemType="SSPS.Models.Relationships.RelatedURL">
                <HeaderTemplate>
                    <ul>
                </HeaderTemplate>
                <ItemTemplate>
                    <li>
                        <asp:HyperLink ID="HyperLink1" Text='<%# Item.Title %>' NavigateUrl='<%# Item.ActualLink %>' runat="server" Target="_blank" ToolTip='<%# Item.ToolTip %>'></asp:HyperLink>&nbsp;&nbsp;<asp:LinkButton ID="PreviewButton" runat="server" CausesValidation="false" Text="preview" OnClick="PreviewButton_Click" Font-Size="X-Small"  CssClass="previewLink"></asp:LinkButton>
                        <div id="PreviewWindow"></div>
                    </li>
                </ItemTemplate>
                <FooterTemplate>
                    </ul>
                </FooterTemplate>
            </asp:Repeater>
        </asp:Panel>
    </asp:Panel> 
</ContentTemplate>

Javascript sn-p 为 LinkBut​​tons 附加了一个 hoverIntent 函数,这样当用户将鼠标悬停在它们上方时,我会捕捉到该悬停,然后导致 LinkBut​​ton 点击​​()。从那里我们进入服务器端,在那里我对 Linkbutton 进行一些处理,并最终对 LinkBut​​ton 执行此操作:

protected void PreviewButton_Click(object sender, EventArgs e)
{
    //figure out the loc, url and so forth
    string loc = ResolveUrl("~/PreviewWindow.aspx");
    loc += "?url=" + url.ActualLink;
    ScriptManager.RegisterStartupScript(this, this.GetType(), "dlg", "openPopup('" + loc + "', " + url.HintHeight + ", " + url.HintWidth + ", '" + url.Title + "', '" + previewButton.ClientID + "')", true);
    return;
}

现在,我加载我的页面及其关联的 UserControl,我的 LinkBut​​tons 只是坐在那里盯着我看,直到我将鼠标悬停在它们上面。一旦我这样做了,就会弹出 jQuery 对话框并向我显示我要求的 url。

到目前为止一切都很好。但是一旦我关闭对话框,一切都会崩溃。我再次将鼠标悬停在 LinkBut​​ton 上(相同或不同的,没关系),没有任何反应。服务器端的 PreviewButton_Click() 函数永远不会被调用,一切都只是傻傻地呆在那里盯着我看。

为了缩小问题范围,我删除了设置 hoverintent 功能的 Javascript。没有它,我必须实际点击 LinkBut​​ton,但无论我点击多少次,它都不会弹出对话框,所以似乎 javascript 部分存在问题。

我对 javascript 的了解并不十分深入,我认为某些操作会弄乱 javascript。但我不确定在哪里看。我在 Chrome 的检查窗口中查看了它,但 javascript 中似乎没有任何错误。

有什么建议吗?

更新:在尝试了 @mjw 和 @WevDev 的建议后,我看到了更多奇怪行为的证据。我发现我在那个 UserControl 中所做的任何导致回发的事情都会杀死 jquery 对话框。所以看起来回发确实导致调用hoverIntent的javascript丢失。但是我尝试的任何方法都无法解决 javascript 的丢失问题。

【问题讨论】:

  • 将脚本块向下移动到面板下方。如果您在该脚本块 (hoverIntent) 中添加警报,它会在显示并关闭第一个对话框后触发吗?您有任何控制台消息、错误或警告吗?
  • 我尝试移动脚本,但没有任何乐趣。添加到 hoverintent 脚本块的警报在第一次后不会触发。我没有看到任何相关的控制台消息或错误或任何东西。

标签: javascript c# asp.net


【解决方案1】:

这是有问题的,因为

  1. ASP.Net 页面生命周期。

第一次悬停有效,因为您使用此 js 代码注册悬停事件处理程序

$(function () {
   var btn = $('.previewLink');
   btn.hoverIntent(function (e) {
      e.target.click();
   }, function () { });
});

在回发后 ASP.NET 重新呈现更新面板中的所有内容,因此之前注册的处理程序不再有效。这意味着var btn = $('.previewLink')(先前选择的元素)与新渲染的元素无关。

这就像你有一个&lt;a&gt;,它有一个点击处理程序,然后你删除&lt;a&gt;并创建新的&lt;a&gt;。 HTML 看起来和以前一样,但单击处理程序将不再工作,因为它与新创建的元素无关。

  1. $(function(){ .... }); 这是文档就绪的简写。所以它只在文档准备好时触发一次。回发后,不会触发此功能。因此,您新创建了&lt;a&gt;,但没有用于注册处理程序的 js 代码。

因此,将脚本块向下移动到面板下方(但保留在更新面板内),并删除文档就绪速记。例如

<script>
............
var btn = $('.previewLink');
btn.hoverIntent(function (e) {
   e.target.click();
}, function () { });
</script>

希望对你有帮助

[更新]

试试这个:

protected void Page_PreRender(object sender, EventArgs e)
    {
        var script = @"
        var btn = $('.previewLink');
                btn.hoverIntent(function (e) {
                    e.target.click();
                }, function () { });
        ";

        ScriptManager.RegisterClientScriptBlock(this, typeof(Page), "someKey",
            script, true);
    }

希望对你有帮助

【讨论】:

  • 不幸的是,这似乎没有任何区别。在第一个对话框出现并被关闭后,不再生成 click 事件。或者至少我在 Click 处理程序中的断点没有被命中。并且没有更多的对话框出现。我有另一个按钮,当将鼠标悬停在上面时,它只会生成一条 Alert() 消息。这工作得很好,直到我触发 jQuery 对话框,然后它开始无法发出警报。
  • 有趣,并且可能会有所帮助,如果我像这样向 jQuery 对话框添加一个 close: 事件:close: function () { __doPostBack();} 那么当用户关闭对话框时,页面会重新加载一切都恢复正常了。
  • 因为整个页面被再次加载并注册了事件处理程序。我做了更新,请尝试一下。
  • 甜饼干三明治!上次更新做到了。现在一切都按预期工作了——hoverintent 每次都会为每个链接弹出我的对话框,之后我不必重新加载页面。感谢您的帮助!
猜你喜欢
  • 1970-01-01
  • 2012-07-09
  • 1970-01-01
  • 1970-01-01
  • 2013-02-20
  • 2021-03-22
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多