【问题标题】:ASP.Net ScriptManager and UpdatePanel ignoring javascript once posted backASP.Net ScriptManager 和 UpdatePanel 在回发后忽略 javascript
【发布时间】:2010-02-09 16:05:54
【问题描述】:

我在网站上使用 UpdatePanel 时遇到了重大问题。问题是,当我使用 ScriptManager 时,一旦更新面板回发,所有在页面最初加载时处于活动状态的客户端 JavaScript 都会丢失。

这就是我想要做的......

我在同一页面上有许多 .net 日历控件,每个控件都在其自己的更新面板中。日历最初是隐藏的,直到您在关联的文本框内(也在更新面板内)单击,此时日历会弹出,以便您选择日期。在您实际更改日期(回发)之前,它们的日历工作得很好,之后,当您在文本框中单击时,日历不再弹出,“onfocus”JavaScript 丢失。

在谷歌上看了几个小时后,我可以通过向 TextBox 动态添加“onfocus”属性并在日历回发时使用 ScriptManager 注册启动脚本来让事情半正常工作。

例子:

TextBox1.Attributes.Add("onfocus", "document.getElementById('searchArrivalDateCalendarDiv').style.display = 'block';")
ScriptManager.RegisterStartupScript(Page, GetType(Page), "StopTxtClick", "$(document).ready(function(){$('.txtArrivalDate').click(function(event){event.stopPropagation(); $('div.searchArrivalDateCalendarDiv').show(); });});", True)

这似乎真的不切实际,尤其是当我介绍一个母版页时。我最终将不得不重新注册大量的启动脚本。

一定有更简单的方法吗?

【问题讨论】:

    标签: javascript updatepanel scriptmanager


    【解决方案1】:

    您似乎想使用事件委托。主要思想是事件冒泡,因此您可以将事件处理程序附加到更新面板之外(可能附加到更新面板所在的 div 或表中)。此处理程序负责它接收的所有事件,因此即使您的更新面板回发并呈现新的文本框,您也不需要重新附加事件处理程序。当新文本框引发其事件时,您现有的事件处理程序可以尝试处理它。

    以下只是在 javascript 中进行事件委托的一种方式(使用 jquery,取自 http://www.danwebb.net/2008/2/8/event-delegation-made-easy-in-jquery

    jQuery.delegate = function() {
                return function(e) {
                    var target = $(e.target);
                    if (target.attr("showCalendar")) {
                        var calendar = $("#" + target.attr("showCalendar"));
                        calendar.css("display", "block");
                    }
                }
            }
    
            $(document).ready(function() 
            {
                $('#test').click($.delegate());
            });
    
    <form id="form1" runat="server">
            <asp:ScriptManager runat="server" EnablePartialRendering="true"/>
            <div id="test" style="width:100%;">
                <asp:UpdatePanel runat="server">
                    <ContentTemplate>
                        <input type="text" id="testText" showCalendar="testCalendarDiv" />
                        <div id="testCalendarDiv" style="display:none;">
                            <asp:Calendar runat="server" ID="testCalendar1"/>
                        </div>
                   </ContentTemplate>
               </asp:UpdatePanel>
            </div>
        </form>
    

    在这个简单的示例中,我在单击此 div 时注册了委托方法(文本框和日历在此 div 内)。当您单击文本框时,单击事件会冒泡到 div。委托方法被调用,我从引发事件的元素中检查 showCalendar 属性。如果此属性存在,我会找到此属性指向的元素并更新其显示样式。这是一个非常简单的示例,但是您可以轻松地扩展委托方法以接收它将根据您注册的某种规则调用的函数。

    【讨论】:

      【解决方案2】:

      问题在于 UpdatePanel 刷新完全清除了其 div 元素中的 DOM。解决这个问题的最简单方法是尽可能使用 live() 功能,例如:

      $(document).ready(function () {
        $('.txtArrivalDate').live('click', function (event) {
          event.stopPropagation();
      
          $('div.searchArrivalDateCalendarDiv').show();
        });
      });
      

      【讨论】:

        【解决方案3】:

        感谢您的回答。

        我还是没能解决这个问题。但是,我找到了日历弹出的替代解决方案。

        我现在使用CalendarExtender 控件,它是 ASP.Net AJAX 控件工具包的一部分。这是我需要的更好的解决方案。整个日历更加流畅和整洁,我不再需要使用更新面板。它还支持多种文化而无需任何额外的编码,这很棒。

        干杯。

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 2010-12-18
          • 2010-09-29
          • 1970-01-01
          • 2014-08-03
          • 1970-01-01
          • 2011-09-15
          • 2013-08-30
          相关资源
          最近更新 更多