0

不幸的是,我无法在我的应用程序之外重现此问题。我有一个 VS2012 项目,我可以发给任何愿意看的人。它单独适用于我,但不适用于更大的应用程序。

我的目标是在母版页中有一个通用的覆盖控件,页面可以在部分回发期间冒泡显示事件。

这是我所拥有的:

  • 在叠加层中显示消息框的用户控件
  • 获取 PageRequestManager 对象并添加 pageLoaded 事件的 javascript 文件
    • 事件处理程序检查隐藏控件的值并使用 jquery 显示/隐藏消息
  • 带有脚本管理器的母版页和包装在更新面板中的用户控件
  • 包含一个共享事件的类,用于提醒母版页需要显示一条消息
  • 一个带有更新面板的页面,其中包含一个 div、一个按钮和一个文本框
  • 一个css文件

测试应用程序中会发生什么:

  • 在框中输入文本并单击按钮
  • 按钮点击事件
    • 将文本复制到更新面板中的 div
    • 调用自定义类中的DisplayMessage方法提醒母版页
  • DisplayMessage 实例化并填充自定义事件参数并引发事件
  • 母版页中的处理程序设置用户控件的属性并在其 UpdatePanel 上调用 Update
  • 页面显示覆盖并触发 pageLoaded [1]
  • javascript 函数评估隐藏控件的 Value 属性并显示消息。
  • 用户单击确定按钮
  • 点击处理程序(服务器端)设置隐藏值并在用户控件的更新面板上触发更新
  • 消息消失

“在现实生活中”会发生什么:

  • 在点 [1],javascript 失败,$ 未定义

chrome 控制台允许我输入 jQuery 并显示元素。

不涉及 jq 插件,脚本管理器位于主窗体的顶部。jquery 参考在没有“http/https”的指向 google 的 master 中。

我尝试在 ScriptManagerProxy 中添加外部脚本,但无济于事。事实上,测试应用程序与

<script src="blahblah.js"></script> 

在用户控件标记的底部。

您能提供的任何帮助将不胜感激。

干杯,.pd。

编辑:

根据要求提供脚本参考:

这是主页:

<head runat="server">
<title>Untitled Page</title>
<script type="text/javascript" src="//ajax.googleapis.com/ajax/libs/jquery/1.10.2/jquery.min.js"></script>
<script type="text/javascript" src="//ajax.googleapis.com/ajax/libs/jqueryui/1.10.3/jquery-ui.min.js"></script>
<script type="text/javascript" src="/scripts/tabindex.js"></script>

<asp:ContentPlaceHolder ID="head" runat="server">
</asp:ContentPlaceHolder>
</head>
<body style="background-color: #cccccc;">
<form id="form1" runat="server">
    <asp:ToolkitScriptManager runat="Server" EnablePartialRendering="true" ID="ScriptMan1" EnablePageMethods="true">
    </asp:ToolkitScriptManager>

     <asp:UpdatePanel ID="updPopupMsg" runat="server" UpdateMode="Conditional">
        <ContentTemplate>
            <amis:PopupMsg ID="popMaster" runat="server" Hidden="true" />
        </ContentTemplate>
    </asp:UpdatePanel>   
</form>

这是 UserControl 标记:

<div id="divOverlay" runat="server" class="helpbox-overlay"></div>
<div id="divMessage" runat="server" class="helpbox">
<asp:HiddenField ID="hdnHidden" runat="server" Value="True" />
<asp:Panel ID="pnlHelpBox" CssClass="helpbox-popup" runat="server">
    <h1>
        <asp:Label ID="lblTitle" runat="server"></asp:Label></h1>
    <p>
        <asp:Label ID="lblMsg" runat="server"></asp:Label>
    </p>
    <p>&nbsp;</p>
    <p align="center">
        <asp:Button ID="btnClose" CausesValidation="false" Text="Close" runat="server"/>
    </p>
</asp:Panel>
</div>

<script type="text/javascript" src="/scripts/popup-msg.js"></script>

该 javascript 文件中的代码如下所示:

var prm = Sys.WebForms.PageRequestManager.getInstance();
prm.add_pageLoaded(popup_msg_init);

function popup_msg_init() {
    if ($('input[id*="hdnHidden"]').attr('value') == 'True')
        popup_msg_hide();
    else
        popup_msg_show();
}

function popup_msg_show() {
    $('div[id*="divOverlay"]').show();
    $('div[id*="divMessage"]').show();
}

function popup_msg_hide() {
    $('div[id*="divOverlay"]').hide();
    $('div[id*="divMessage"]').hide();
}

编辑:

嘿 - 是否有可能异步加载脚本?有什么工具可以用来验证什么时候发生的事情吗?我问是因为我将 javascript 更改为以下内容:

var prm = Sys.WebForms.PageRequestManager.getInstance();
prm.add_pageLoaded(popup_msg_init);

function popup_msg_init() {
    var inputs = document.getElementsByTagName('input');
    for (var i = 0; i < inputs.length; i++) {
        var input = inputs[i];
        if (input.id.indexOf('hdnHidden') > 0) {
            if (input.value == 'True')
                popup_msg_hide();
            else
                popup_msg_show();
        }
    }
}

function popup_msg_show() {
    $('div[id*="divOverlay"]').show();
    $('div[id*="divMessage"]').show();
}       

function popup_msg_hide() {
    $('div[id*="divOverlay"]').hide();
    $('div[id*="divMessage"]').hide();
} 

现在一切正常。所以我的理论是 pageLoaded 正在另一个看不到 jquery 的线程上调用我的 popup_msg_init 函数,并且手动搜索 dom 导致的延迟给了它足够的时间来加载 cuz 在调用显示/隐藏函数时,一切都很正常.

所以我想我会通过在那里设置超时来检查:

setTimeout(function () {
    if ($('input[id*="hdnHidden"]').attr('value') == 'True')
        popup_msg_hide();
    else
        popup_msg_show();
}, 5000);

但它又回到“$ 未定义”。

对此有何评论?

4

2 回答 2

0

chrome 控制台允许我输入 jQuery 并显示元素。

因为当您输入该代码时,jQuery 已加载。但是这个错误:

$ 未定义

表示在其他一些代码运行时,没有加载 jQuery。

请注意,JavaScript 代码按照加载到页面中的顺序进行处理。因此,需要在任何使用它的代码之前加载 jQuery 库。(也就是说,引擎不够聪明,无法加载所有代码,然后像编译语言一样将引用相互链接。)

虽然您在问题中提供了大量信息,但您没有提供的一件事是 HTML 中的脚本引用。但是,作为示例,请考虑以下不正确的情况:

<script type="text/javascript" src="someScriptThatUsesjQuery.js"></script>
<script type="text/javascript" src="jQuery.js"></script>

与以下正确的相反:

<script type="text/javascript" src="jQuery.js"></script>
<script type="text/javascript" src="someScriptThatUsesjQuery.js"></script>
于 2013-11-15T15:10:37.057 回答
0

包含的其他 javascript 中存在错误。不是语法错误,而是由于 ASP.NET 将它们插入页面的方式,它们领先于 Sys 定义。所以我用相关的 javascript 改变了我所有的用户控件来遵循这个模式:

-1- 使用 Javascript 帮助类将脚本引用添加到页面。(我会在这里使用项目符号,但代码格式化程序在项目符号列表中不起作用 - 提示 stackoverflow 开发人员)

Imports System.Web.UI
Imports System.Web.UI.WebControls
Imports System.Web.UI.HtmlControls

Public Class JSHelper
    Public Shared Sub Add(path As String, page As Page)
        Dim jsFile As New HtmlGenericControl("script")
        jsFile.Attributes.Add("type", "text/javascript")
        jsFile.Attributes.Add("language", "javascript")
        jsFile.Attributes.Add("src", page.ResolveUrl(path))
        page.Header.Controls.Add(jsFile)
    End Sub
End Class

-2- 添加脚本

JSHelper.Add("/scripts/myscript.js", Me.Page)

-3- 根据控件标记运行设置功能

<script type="text/javascript" lang="javascript">
    if (typeof (Sys) === 'undefined')
        $(function () { 
            init(); });
    else {
        if (typeof (Sys.WebForms) === 'undefined')
            alert('Sys.WebForms not defined!');
        else {
            Sys.WebForms.PageRequestManager.getInstance().add_pageLoaded(init);
        }
    }
</script>
于 2013-11-20T10:29:33.053 回答