asp.net usercontrol不会在updatepanel中激活javascript

时间:2013-04-13 14:01:29

标签: javascript asp.net user-controls

我已经看到类似的问题和答案,但似乎没有解决问题。

我在更新面板中有一个用户控件。在我的用户控件中,我输出了javascript。

触发时javascript不会触发。如果我将javascript移动到usercontrol / updatepanels之外的父页面,则会触发它。这样做是没有意义的,因为我不能在没有重复代码的情况下在另一个页面上使用此usercontrol ...通过复制整个javascript(不同的站点)或在每个页面中添加对.js文件的引用在(同一地点)。它只是不太便携

我只想用控件输出javascript(在更新面板中)。

我提到了updatepanel的准确性。即使我将usercontrol放在updatepanels之外,它也不起作用。

保持简单(这对我不起作用):

用户控件:

<%@ Control Language="C#" AutoEventWireup="true" CodeFile="_location.ascx.cs" Inherits="_location" %>
<script type="text/javascript">
    function test() {
        alert('Hello World!');
    }
</script>

<a href="javascript:void(0);" onclick="javascript:test();">
    Find For Me
</a>

PARENT:

<uc1:_location runat="server" ID="_location"  />

在chrome中调试告诉我“未捕获的ReferenceError:测试未定义”

如果我将javascript直接添加到onclick,如下所示:

onclick="alert('Hello World!');"

如上所述,将功能移动到父页面也可以。

就好像浏览器忽略了用户控件的脚本输出。

有什么想法吗?

5 个答案:

答案 0 :(得分:6)

当你有UpdatePanel并且UpdatePanel更新它的内容时,它会将其内容视为简单的text / html(不是代码),它没有任何可用的解析器来运行脚本并制作它可用于页面。

所以这个内容,

<script type="text/javascript">
    function test() { alert('Hello World!'); }
</script>

<a href="javascript:void(0);" onclick="javascript:test();">
    Find For Me
</a>

在更新面板的客户端代码运行并更新页面内容后,脚本部分不会被解析 - 它是页面的简单文本/ html。

然而,这部分运行

<a href="javascript:void(0);" onclick="alert('Hello World!');">Find For Me</a>

因为onclick属性的解析是在您点击它时完成的。

有以下可用的解决方法:

  1. 将您的javascript移至外部文件
  2. 将脚本移到UpdatePanel之外
  3. 使用RegisterClientScriptBlock或其他功能在后面的代码中注册脚本。

答案 1 :(得分:1)

感谢Aristos让我走上正确的道路......尽管他的解决方案有效,但它没有回答从用户控件内部输出javascript的问题,而是建议将其移到外面。如上所述,这不是理想的结果,因为它没有保留在控件内部以便于移植。

以下是我的解决方案: CS档案:

String script = "<script type=\"text/javascript\">";
script += "function test() {";
    script += "alert('Hello World!');";
script += "</script>";

Page.ClientScript.RegisterClientScriptBlock(Page.GetType(), "locationScript", script);

如果脚本较长,可以使用stringbuilder,但无论如何都可以。

这使代码完全保留在usercontrol中,并且它可以从a标记的onclick事件中运行。

答案 2 :(得分:1)

除了Adam Wood发布的解决方案之外,我应该说在使用更新面板时必须使用ScriptManager注册脚本,至少在.net 4.0中,否则它将无法工作。

因此,您可以使用usercontrol的PageLoad事件:

string script = @" alert('this is a test');
alert('it worked')";
ScriptManager.RegisterStartupScript(Page,Page.GetType(),"scriptMelhoria",script,true);

答案 3 :(得分:0)

试试这个;

您可以在udpdate面板回调后找到您的脚本元素并对其进行评估。

在内联脚本标记中添加一个特殊属性,以便在回调请求后选择元素。

<script type="text/javascript" data-tag='myscript'>
    function test() {
        alert('Hello World!');
    }
</script>

将此脚本添加到更新面板容器的aspx文件中。

<script>

        if (Sys !== undefined) {
            var prm = Sys.WebForms.PageRequestManager.getInstance();
            prm.add_endRequest(endPostbackRequest);
        }

        function endPostbackRequest(sender, args) {
            $("script[data-tag='myscript']:not([data-run])").each(
                function () {
                    eval.apply(window, [$(this).text()]);
                    $(this).attr('data-run', '1');
                });
        }

</script>

答案 4 :(得分:-1)

处理绑定到UpdatePanel中的DOM元素的javscript代码的首选方法是订阅PageRequestManagerendRequest事件并在此处执行您的代码。例如,您想在此处设置点击事件处理程序。

// that is standard way for asp.net to execute JS on page load
// pretty much the same as $(function(){ ...}) with jquery
function pageLoad() {
    // find PRM instance and subscribe to endRequest
    Sys.WebForms.PageRequestManager.getInstance().add_endRequest(endRequest);
}

function endRequest() {
    // set all handlers to DOM elements that are within UpdatePanel
    $('<%= myButton.ClientID %>').on('click', test)
}

function test(e) {
   alert('Hi')
}

替代解决方案是使用event delegation,如下所示:

function pageLoad() {

    // delegate click event on .myButton inside .container
    // to the .container DOM element
    $('.container').on('click', '.myButton', test)

}

div在您的更新面板中包含一个名为container的类。在这种情况下,您的div.container永远不会从DOM中删除,因此其上的所有事件处理程序将在部分回发后保留。

没有jquery的相同代码,仅使用asp.net ajax将如下所示:

function pageLoad() {
   Sys.UI.DomEvent.addHandler($("myContainer"), "click", delegatedTest);
}

function delegatedTest(e) {
   // since asp.net ajax does not support event delegation
   // you need to check target of the event to be the right button 
   if (e.target.id == "myButton") test(e)
}

function test(e) {
   alert("HI")
}