【问题标题】:Why does attaching an eventhandler in Javascript stop my server side event firing?为什么在 Javascript 中附加事件处理程序会阻止我的服务器端事件触发?
【发布时间】:2009-03-01 00:16:27
【问题描述】:

我从事 C# 多年,但 ASP.NET 的时间不长,这让我很困惑。

在我的故障排除示例中,我在 ASP.NET 页面中有一个下拉列表,其中有四个项目,我有一个在 selectedindexchanged 上触发的服务器端事件,在这种情况下一切正常。

但是,如果(就像我在进化代码中所做的那样)我为“onchange”事件设置了一个 Javascript 处理程序,(它会启动一个警报)警报工作正常,但服务器端事件不再触发......我'确定我遗漏了一些明显的东西。

重要说明:Autopostback 在下拉列表控件上设置为 true,viewstate 启用,Javascript 事件处理程序返回 true

有人吗?

不是我必须手动连接__doPostBack 是吗?

非常感谢任何帮助。

编辑

好的,这里的代码首先是代码隐藏

using System;
using System.Data;
using System.Configuration;
using System.Collections;
using System.Web;
using System.Web.Security;
using System.Web.UI;
using System.Web.UI.WebControls;
using System.Web.UI.WebControls.WebParts;
using System.Web.UI.HtmlControls;
using System.Text;

namespace TestEvents
{
public partial class _Default : System.Web.UI.Page
{
    protected void Page_Load(object sender, EventArgs e)
    {

    }

    protected override void OnPreRender(EventArgs e)
    {

        ClientScriptManager csm = Page.ClientScript;
        if (!csm.IsClientScriptBlockRegistered("NotesChangeScript"))
        {
            StringBuilder sb = new StringBuilder();
            sb.Append("\r\n <script type=\"text/javascript\"> \r\n");
            sb.Append(" //<![CDATA[ \r\n");
            sb.Append(" var changesCount = 0; \r\n");

            sb.Append(" function selection_handler()\r\n");
            sb.Append("{ \r\n");
            sb.Append(" changesCount += 1;\r\n");
            sb.Append(" alert('i changed on the client!'); \r\n");
            sb.Append(" return true; \r\n");
            sb.Append(" } \r\n");

            sb.Append(" function SetUpNotesHandler() \r\n");
            sb.Append("{ \r\n");
            sb.Append("          var ctrls = document.getElementsByTagName(\"SELECT\");\r\n");
            sb.Append("          for(i=0;i<ctrls.length;i++)\r\n");
            sb.Append("                  {\r\n");
            sb.Append("                     ctrls[i].onchange = selection_handler; \r\n");
            sb.Append("                 }\r\n");
            sb.Append("}\r\n");


            sb.Append(" //]]> \r\n");
            sb.Append("</script>");

            csm.RegisterClientScriptBlock(this.GetType(), "NotesChangeScript", sb.ToString(), false);

            StringBuilder initScript = new StringBuilder();
            initScript.Append("<script type=\"text/javascript\" >\r\n");
            initScript.Append(" //<![CDATA[\r\n");
            initScript.Append("  SetUpNotesHandler(); \r\n");
            initScript.Append(" //]]> \r\n");
            initScript.Append("</script> \r\n");
            csm.RegisterStartupScript(this.GetType(), "StartUpKey", initScript.ToString(),false);
            base.OnPreRender(e);
        }

    }
    protected void DropDownList1_SelectedIndexChanged(object sender, EventArgs e)
    {
        Response.Write("i hit the server event");
    }
}

}

这是页面的标记

<%@ Page Language="C#" AutoEventWireup="true"     CodeBehind="Default.aspx.cs"    Inherits="TestEvents._Default" %>

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">

<html xmlns="http://www.w3.org/1999/xhtml" >
<head runat="server">
<title>problem</title>
</head>
<body>
<form id="form1" runat="server">
<div>
    <asp:DropDownList ID="DropDownList1" runat="server" AutoPostBack="True" OnSelectedIndexChanged="DropDownList1_SelectedIndexChanged">
        <asp:ListItem>Numero Uno</asp:ListItem>
        <asp:ListItem>Numer Deux</asp:ListItem>
        <asp:ListItem>Number Three</asp:ListItem>
        <asp:ListItem>Nomina Quatros</asp:ListItem>
    </asp:DropDownList>
    <asp:HiddenField ID="hdnFieldChange" runat="server" />
</div>
</form>
</body>
</html>

【问题讨论】:

    标签: c# asp.net javascript


    【解决方案1】:

    如果您的 Javascript 事件处理程序取消事件冒泡,asp.net 插入的调用服务器端代码的事件处理程序将不会运行。

    我不熟悉asp.net auto-inserted-things,而且你还没有发布你的事件处理程序的代码,所以我不能准确地告诉你如何解决这个问题。我的建议是使用 jQuery 来附加您的事件处理程序,而不是返回 false 或以更冗长的方式取消事件冒泡。

    【讨论】:

      【解决方案2】:

      在我看来,您有两个同时发生的异步回发,默认情况下,最近的回发优先,您必须更改。您可以强制回发到每个完成,然后再允许下一个继续使用找到的脚本here

      或者您可以在 onselectedindex 更改事件中处理警报服务器端,例如:

          ScriptManager.RegisterClientScriptBlock(Page, Page.GetType(), 
      Guid.NewGuid().ToString(),"alert('Person was added 
      successfully.');location.replace('people.aspx');",true);
      

      【讨论】:

        【解决方案3】:

        将您的脚本分配给这样的 onchange 事件:

        DropDownList1.Attributes["onchange"] += "alert('alert');";
        

        警告后不要使用return true;

        编辑:

        问题就在这里,您通过在其上分配脚本来禁用回发脚本,因此回发脚本无法正常工作,因为它不再存在:

        sb.Append("                     ctrls[i].onchange += selection_handler; \r\n");
        

        希望这会有所帮助!

        【讨论】:

        • 有没有办法在客户端添加事件而不覆盖回发脚本?
        • 您正在为 onchange 事件分配一个函数,并且回发引用被您的代码替换,只需在相关行进行字符串连接即可。
        • 我明白了,在 javascript 中我不知道该怎么做。但是您可以通过这种方式在服务器端执行此操作: DropDownList1.Attributes["onchange"] += "selection_handler();";
        • 欢迎您,如果您发现我们如何添加活动参考,请在此处发布 :)
        【解决方案4】:

        好的,首先,感谢 ScarletGarden 明确了问题所在,我已经假设了这么多,但是当有人证实你的怀疑时,这很好。

        其次,向那些认为这是某种 n00b 问题并认为这个问题的整个前提愚蠢的人道歉,我真的找不到任何文章来澄清这个特定问题......

        第三,我现在已经弄清楚了如何在 Javascript 中执行此操作(尽管猩红花园解决方案在几乎所有情况下都简单得多),尽管如果您有多个处理程序和需要他们按某种顺序开火。

        对反射器进行了一些研究,Attributes.Add 通过分号分隔它们添加事件引用,因此这显然有效,因为它保留了已声明的任何处理程序,并且分号分隔您添加的处理程序。

        在 javascript 中,这种链接(一种多播)需要使用 DOM 级别 2 功能(javascript 圣经对于识别这一点很有用),Mozilla 和 IE 有不同的实现方式也就不足为奇了同样的事情,为了添加一个 js 处理程序并在代码隐藏中保留事件处理,我上面的示例中的行是

        ctrls[i].onchange = selection_handler; \r\n
        

        需要替换为以下内容(在人们对这个示例感到珍贵之前,我确实对此有一个很大的警告,进一步向下)

        sb.Append("                 if (ctrls[i].addEventListener) ctrls[i].addEventListener(\"change\",selection_handler,false);");
        sb.Append("                 else if (ctrls[i].attachEvent) ctrls[i].attachEvent(\"on\" + \"change\", selection_handler, false);");
        sb.Append("                 else return false;");
        

        attachEvent 在 IE 中工作,在 Firefox 中使用 addEventListener(注意事件的不同名称,Mozilla 更喜欢删除“on”

        添加像这样的事件以 LIFO(后进先出)方式工作,有许多替代方法可以使用更复杂的 javascript 以这种方式对事件进行排序,覆盖在一个优秀的,如果有点混乱的线程中(因为它开始的方式) 这里http://codingforums.com/showthread.php?t=154673

        我希望这些东西能像我一样启发别人,这是我第一次遇到问题时正在寻找的线程,现在我觉得有点愚蠢,但是嘿嘿

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2012-09-04
          • 1970-01-01
          • 2012-04-11
          相关资源
          最近更新 更多