在服务器端运行JavaScript

4
在ASP.NET中,当我点击按钮时,我需要使用JavaScript来执行其操作。我尝试了OnClientClick函数,但该事件的问题是首先会执行OnClientClick函数,然后才会执行OnServerClick函数,即首先运行 JavaScript 函数,然后才执行 C# 代码,但我需要相反的顺序,即首先执行C#代码,然后再运行JavaScript。我在我的代码中使用了AJAX.NET和ScriptManager。ScriptManager能帮助我吗?否则,如何在服务器端运行JavaScript。
我需要以下方式:
Button1_Click(object sender, EventArgs e)
{
    ListBox1.Items.Add(TextBox1.Text); //for example
    ` here I have to run JavaScript `
}

有没有办法实现这个?

编辑1:

我需要在按钮点击时将div向下滚动(单击按钮使用databinder和repeater添加新数据到div中)。如上所述,clientclick首先运行,但我需要在服务器操作之后运行它。

Javascript是...

<script>
            var objDiv = document.getElementById("div1");
            objDiv.scrollTop = objDiv.scrollHeight;
</script> 

并且。
<div id="div1"> //css properties height 200 and width 200 overflow:auto
    <asp:ScriptManager ID="ScriptManager1" runat="server" EnablePartialRendering="true" />
    <asp:Timer ID="Timer1" runat="server" Interval="200" />
    <asp:UpdatePanel ID="UpdatePanel1" runat="server" UpdateMode="Conditional">
    <ContentTemplate>
        <asp:Repeater id="Repeater1" runat="server" >
        <ItemTemplate>
            <%# DataBinder.Eval(Container.DataItem, "Message") %> <br />
        </ItemTemplate>
        </asp:Repeater>
    </ContentTemplate>
    <Triggers>
        <asp:AsyncPostBackTrigger ControlID="Timer1" EventName="Tick" /> 
    </Triggers>
    </asp:UpdatePanel>
    </div>
    <asp:UpdatePanel ID="UpdatePanel2" runat="server" UpdateMode="Conditional">
    <ContentTemplate>
        <div id="div2">
            <asp:TextBox ID="tb_message" runat="server" Width="250px" EnableViewState="false" />
            <br />
            <asp:Button ID="btn_send" runat="server" Width="250px" Text="Send" 
                onclick="btn_send_Click" />
        </div>
    </ContentTemplate>
    <Triggers>
        <asp:AsyncPostBackTrigger ControlID="btn_send" EventName="click" />
    </Triggers>
    </asp:UpdatePanel>

这个PostBack是AJAX PostBack还是标准PostBack? - James Hill
2
请提供一些代码,以便我们了解哪种方法适用于您的情况。 - danyloid
4个回答

1

Javascript无法在服务器上运行,但是您可以在服务器代码中选择的位置使用Response.Write("<script>..</script>)将Javascript注入HTTP响应流。

Response.Write("<script>..</script>)会在页面开始呈现之前将脚本写入页面,这可能会导致副作用,请参见 Response.Write()和ClientScript.RegisterStartupScript()之间的区别?

因此,正如@dannyloid发布的那样,请查看ClientScript.RegisterStartupScript


你检查过脚本是否在客户端页面中呈现了吗? - Alan Stephens

1

JavaScript 是一种客户端语言,因此 无法 在服务器上运行。

编辑

根据您更新的问题,以下类似的代码应该能很好地工作:

JavaScript

Sys.WebForms.PageRequestManager.getInstance().add_endRequest(endRequestHandler);

function endRequestHandler(sender, args)
{
    var objDiv = document.getElementById("div1");
    objDiv.scrollTop = objDiv.scrollHeight;
}

1
从技术上讲,有noderhino可以在服务器端运行,不是吗?(虽然我不想暗示KarsM的解决方案是其中任何一个。) - Jeroen
@Jeroen,从技术角度来看,我想是的。不过我认为这就像比较苹果和橙子一样。看看Rhino在首页上说的:“Rhino是一个完全由Java编写的JavaScript开源实现”。也许这超出了我的理解范围,但这看起来不像JS。 - James Hill
我发现了一些类似于btn.attributes.add("onClick",javaScriptFunctionCallHere);的东西,但不知道这是否有效。 - Mad coder.
@JamesHill 或许可以说客户端是苹果,服务器端是橙子。但它们都是水果(JavaScript)啊 ;)。 - Jeroen
它的工作正常,但当我向上滚动时,根据AjaxTimer的间隔,它会向下滚动到底部。这是由于UpdatePanel在AjaxTimer的间隔刷新时更新所致。 - Mad coder.
显示剩余4条评论

1

编辑

根据提供的代码,如果您想在服务器端注册脚本,这应该可以工作:

Button1_Click(object sender, EventArgs e)
{
    ListBox1.Items.Add(TextBox1.Text); //for example

    ScriptManager.RegisterStartupScript(UpdatePanel2, UpdatePanel2.GetType(), "scriptKey", "var objDiv = document.getElementById('div1'); objDiv.scrollTop = objDiv.scrollHeight;", true);
}

如果您想在客户端注册脚本,也可以使用James提供的代码,但请记住,每次完成AJAX请求时都会执行该脚本(每次刷新任何更新面板时都会执行该脚本)。如果您要每次刷新UpdatePanel1时滚动元素,并且没有其他使用同一页上的Timer控件刷新的更新面板,则James提供的代码将更有用,而我的代码仅在按下发送按钮时滚动。

更新

很抱歉-似乎在执行服务器单击事件处理程序之后,但在重新加载第一个更新面板内部的HTML之前执行了该代码(您可以在服务器单击事件处理程序中设置断点,并在注册的脚本中设置警报)。因此,在执行脚本时,div元素仍然包含旧的HTML。

作为一种hack方法,您可以使用带有小超时的setTimeout函数(在我的示例中,100毫秒足够)。我正在寻找一种适当的方法来检查更新面板内部的HTML是否重新加载,并将尽快找到答案更新。


我尝试了你的代码,但对我仍然不起作用。还需要进行更正吗? - Mad coder.
@KarsM 代码执行了吗?我已经使用您提供的代码创建了演示项目,它可以正常工作。这是URL,以便您查看代码http://dl.dropbox.com/u/26396738/UpdatePanelClientScript.7z - danyloid
我尝试使用ScriptManager.RegisterStartupScript(UpdatePanel2,UpdatePanel2.GetType(),“scriptKey”,@“<script>document.write('hello'); </ script> ;”,true);,但是没有效果:( - Mad coder.
@KarsM,您需要从字符串中删除<script>标签,就像以下示例中的ScriptManager.RegisterStartupScript(UpdatePanel2, UpdatePanel2.GetType(), "scriptKey", @"document.write('hello');", true);一样。如果将最后一个参数设置为true,则脚本会自动包装。同样,您也可以使用ScriptManager.RegisterStartupScript(UpdatePanel2, UpdatePanel2.GetType(), "scriptKey", @"<script>document.write('hello'); </script>;", false); - danyloid
但这也给我提供了与OnClientClick函数相同的东西。 - Mad coder.
@KarsM 更新了答案。URL 可用的项目将在几分钟内更新 - 它包含一个修复行为的 hack(使用 setTimeout 函数)。我会尽快找到正确的方法来修复它,并更新答案。如果您不喜欢使用 setTimeout 的那个 hack,仍然有其他几个可用的 hack。 - danyloid

0

2
-1,没有理解用户需求就将像Node.js这样不同和复杂的东西推荐给他们是愚蠢的。大部分时候,当有人说他们需要在服务器上运行JS时,是因为他们并不完全理解JS以及如何正确使用它。 - James Hill

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接