【问题标题】:Why does asp page load event fire again on javascript window.close?为什么在javascript window.close上再次触发asp页面加载事件?
【发布时间】:2017-05-05 14:03:14
【问题描述】:

我有一个计划,我们正在使用外部方提供的培训视频和考试来升级有关新法规的培训。它包括最后的考试。

我被要求将它分叉到我们的 ASP 员工网站中,我在很大程度上已经成功地做到了。我确实想记录考试结果,因此,尽管我的 Javascript 技能很初级,但我确实在 Javascript 编码中找到了计算考试结果的位置,所以我让 Javascript 打开了一个 asp.net 页面作为弹出窗口,将考试成绩信息传递到该页面,该页面将结果记录在数据库中。页面上唯一的项目是确认信息已记录,显示捕获的信息,以及关闭弹出窗口的按钮,该按钮触发 Javascript window.close 事件。当按下按钮时,分数会再次记录,这应该只发生在页面加载事件中。

我们在数据库中获得了重复的条目,但条目上的时间戳不一样,所以我知道部分代码正在再次运行。

这是该弹出窗口的 asp 标记:

<body>
<form id="form1" runat="server">
<div>
    <h4><asp:Label runat="server" ID="lblWelMess" /></h4>
    <br />
    <br />
    <asp:Button runat="server" Text="OK" ID="btnOK" />
</div>
</form>

这是背后的 Visual Basic 代码 -

Protected Sub Page_Load(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.Load
    Dim quizName As String = Request.QueryString("qn")
    Dim corrAns As Integer = CInt(Request.QueryString("ca"))
    Dim totQues As Integer = CInt(Request.QueryString("nq"))
    Dim examStatus As String = Request.QueryString("xst")

    logScores(quizName, examStatus, corrAns, totQues)

End Sub

Protected Sub logScores(ByVal qName As String, xStat As String, correct As Integer, qNum As Integer)
    Dim uID As String = Session.Item("USERNAME")
    Dim uName As String = Session.Item("FULLNAME")
    Dim testPerc As String = Format(100 * correct / qNum, "0.00")

    Dim connSQL As New SqlConnection(ConfigurationManager.ConnectionStrings("MyConnectionString1").ToString)
    Dim procName As String = "AddExamScore"
    Dim cmdAdd As New SqlCommand(procName, connSQL)
    cmdAdd.CommandType = CommandType.StoredProcedure
    cmdAdd.Parameters.AddWithValue("UserID", uID)
    cmdAdd.Parameters.AddWithValue("corrAns", correct)
    cmdAdd.Parameters.AddWithValue("numQues", qNum)
    cmdAdd.Parameters.AddWithValue("corrPerc", CDec(testPerc))
    cmdAdd.Parameters.AddWithValue("status", xStat)
    cmdAdd.Connection.Open()

    cmdAdd.ExecuteNonQuery()
    cmdAdd.Connection.Close()

    lblWelMess.Text = uName & ", your score has been logged" & "<br />Quiz: " & qName & "<br />Status: " & xStat & "<br />Correct: " & correct.ToString & "<br />Questions: " & qNum.ToString & "<br />Percentage: " & testPerc
End Sub

Protected Sub btn_OK_Click(sender As Object, e As EventArgs) Handles btnOK.Click
    Response.Write("<Script language=javascript>window.close()</Script>")
End Sub

我应该关闭该窗口还是以其他方式构建按钮单击事件?

我是否应该在“logScores”子例程中包含某种代码来检查以确保它不会被窗口关闭触发?

我应该移动那个“logScores”子以触发不同的事件吗?

【问题讨论】:

  • 您能否在页面加载时检查 IsPostback 并忽略日志记录?
  • 大多数 ASP.NET Web 窗体控件会导致触发回发,例如当您单击按钮时。这会强制页面重新加载。您可以检查它是否是 PostBack,但这很愚蠢。为什么需要回发来关闭页面?为什么你需要一个服务器控制?您知道如何编写一个基本的 HTML 按钮并连接一些 JavaScript 以在您单击它时运行,对吧?
  • @RossBush - 我现在感觉有点傻......
  • @mason - 整个站点都是基于 ASP.NET 的,我们(和我)没有太多 Javascipt 专业知识。除非我必须这样做,否则我不会将其添加到站点中,而我没有,在这里。 “IsPostBack”检查非常简单并且工作正常。
  • 不,它非常复杂。你没有看到发生的一切。这在客户端和服务器上都浪费资源,并导致糟糕的体验。通过使用纯 HTML 而不是服务器控制,您不会向站点“添加”任何内容。您只是在使用正确的工具来完成这项工作。 &lt;button onclick="window.close()"&gt;OK&lt;/button&gt; 就是您所需要的。没有服务器方法,没有回发,没有额外的标记或视图状态,没有浪费的带宽或额外的 HTTP 请求。一切都包含在一个位置。

标签: javascript asp.net vb.net webforms


【解决方案1】:

大多数 ASP.NET Web 窗体控件会触发回发,例如当您单击按钮时。这会强制页面重新加载。您可以检查它是否是 PostBack,但这很愚蠢。为什么需要回发来关闭页面?为什么需要服务器控件?

相反,让我们替换所有这些:

<asp:Button runat="server" Text="OK" ID="btnOK" />

Protected Sub btn_OK_Click(sender As Object, e As EventArgs) Handles btnOK.Click
    Response.Write("<Script language=javascript>window.close()</Script>")
End Sub

用这个:

<button onclick="window.close()">OK</button>

不同之处在于您的原始方式会触发一些 JavaScript,这会导致向服务器发送 HTTP Post,运行整个页面生命周期,构建页面的新实例,运行您的按钮单击处理程序,编写一些 JavaScript 到一旦遇到该 JavaScript,将导致它关闭窗口的页面。

我的方式可以描述为:点击按钮时会触发一些 JavaScript 并关闭窗口。


注意,像我这样的人如此不喜欢 Web 表单的原因就是这样的。它可能看起来简单,但发生的一切都比看起来要复杂得多。相反,学习 HTML 和 JavaScript 的基础知识会更好地为您服务。最好使用 ASP.NET MVC,它可以减少这种泄漏抽象的东西。或者切换到仅在客户端上编写 HTML 和 JavaScript(可能使用 Angular 或 React 或 Knockout 等),通过 AJAX(可能使用 ASP.NET Web API)或 Web 套接字(可能使用 SignalR)与 Web 服务器通信。这意味着更少的抽象泄漏、更简洁的 HTML、更容易调试、更快的客户端、更少的客户端和服务器资源密集型。

我并不是说您不能使用 Web 表单并取得成功。就像罗斯的回答一样,通常有办法做事。但是还有更好的方法。

【讨论】:

  • @RossBush - 抱歉,您的答案“不是最好的”,但这个更简单,更优雅。你们俩都诊断出双重射击的原因。谢谢@
【解决方案2】:

我敢打赌,使用 IsPostBack 来确定它是否是初始请求会解决您的问题。

Protected Sub Page_Load(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.Load
    if !IsPostBack Then Begin
        Dim quizName As String = Request.QueryString("qn")
        Dim corrAns As Integer = CInt(Request.QueryString("ca"))
        Dim totQues As Integer = CInt(Request.QueryString("nq"))
        Dim examStatus As String = Request.QueryString("xst")
        logScores(quizName, examStatus, corrAns, totQues)
    EndIf
End Sub

【讨论】:

  • 呃!!!回发将在按下按钮时触发,即使它只是触发关闭窗口/页面。正如预期的那样,这是非常简单/愚蠢的事情。感谢您看到我无法理解的显而易见的事情!
  • 很高兴我能帮上忙。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2012-05-05
  • 1970-01-01
  • 2022-01-10
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-06-17
相关资源
最近更新 更多