ASP.Net диалоговое окно jQuery отображается только при первом наведении курсора

У меня есть пользовательский элемент управления, который имеет UpdatePanel, внутри которого находится повторитель, внутри которого находятся кнопки Linkbuttons:

<%@ 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 присоединяет функцию hoverIntent к кнопкам Linkbutton, так что когда пользователь парит над ними, я ловлю это наведение, а затем заставляю кнопку LinkButton нажать(). Оттуда мы идем на серверную сторону, где я делаю некоторую обработку для Linkbutton и в конечном итоге делаю это для LinkButton:

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, и мои кнопки ссылок просто сидят там, глядя на меня, пока я не наведу на них курсор. Как только я это сделаю, появится диалоговое окно jQuery и покажет мне url, который я просил.

Пока все хорошо. Но как только я закрываю диалог, все ломается. Я снова наведу курсор на кнопку связи (ту же или другую, не имеет значения), и ничего не произойдет. Функция PreviewButton_Click () на стороне сервера никогда не вызывается, и все просто сидит там глупо и смотрит на меня.

Чтобы попытаться сузить проблему, я удалил Javascript, который устанавливает функцию hoverintent. Без этого я должен фактически нажать на кнопку LinkButton, но это никогда не вызывает диалоговое окно, независимо от того, сколько раз я нажимаю его, поэтому кажется, что есть проблема в части javascript.

Я, с моим не очень глубоким знанием javascript, думаю, что есть какое-то действие, которое портит javascript. Но я не знаю, где искать. Я посмотрел на него в окне проверки Chrome, но, похоже, в javascript нет никаких ошибок.

Есть предложения?

Update: после попытки предложить от @mjw и @WevDev, я вижу еще больше доказательств странного поведения. Я обнаружил, что все, что я делаю в этом UserControl, который вызывает обратную передачу, убьет диалоговое окно jquery. Таким образом, похоже, что postback вызывает потерю javascript, который вызывает hoverIntent. Но ничто из того, что я пробую, не исправит эту потерю javascript.

1 ответ

  1. Это имеет проблему, потому что

    1. ASP.Net страница lifecicle.

    Первый hover работает, потому что вы регистрируете обработчик событий hover с этим кодом js

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

    После postback ASP.NET rerenders все внутри updatepanel, поэтому ранее зарегистрированные обработчики больше не действительны. Это означает, что var btn = $('.previewLink')(ранее выбранные элементы) не имеют ничего общего с вновь отображаемыми элементами.

    Это то же самое, как если у вас есть<a>, который имеет обработчик щелчка, а затем удалить <a>и создать новый <a>. HTML будет выглядеть так же, как и раньше, но click handler больше не будет работать, потому что он не имеет ничего общего с вновь созданным элементом.

    1. $(function(){ .... }); это стенография готового документа. Таким образом, он срабатывает только один раз, когда документ готов. После обратной передачи эта функция не активируется. Таким образом, вы только что создали<a>, но нет кода js для регистрации обработчиков.

    Итак, переместите блок сценария вниз под панелями (но держите внутри updatepanel) и удалите готовый стенографический документ. например.

    <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);
        }
    

    Надеюсь, это поможет