简体   繁体   English

从asp.net代码隐藏执行Javascript函数?

[英]Executing a Javascript function from an asp.net codebehind?

OK, this feels like a question that should be easy to answer, but as with so much mixing of asp.net and jQuery, it's a bit of a nightmare. 好吧,这感觉就像一个应该很容易回答的问题,但是就像asp.net和jQuery这么多混合一样,这有点像噩梦。

What I want to do is be fading a div in and out at various times during the client's viewing of my asp.net page; 我想做的是在客户端查看我的asp.net页面的过程中,在不同时间淡入淡出div ; I fade it out using jQuery's fadeTo() before triggering an UpdatePanel update (to indicate that the data there is not fresh) and I want to fade it in again once the UpdatePanel has been updated. 我在触发UpdatePanel更新之前使用jQuery的fadeTo()其淡出(以指示那里的数据不新鲜),并且我想在UpdatePanel更新后再次淡入它。 I've gotten as far as updating the UpdatePanel in the codebehind, and this results in the div 's content changing... but how do I fade the div back in again? 我已经在代码隐藏中更新了UpdatePanel,这导致div的内容发生了变化......但是我如何再次淡入div呢?

The way I see it, there are 2 ways; 我看待它的方式有两种方式; register an event handler on page load to detect when the div 's content has been changed and fade it back in, or call a function from the asp.net codebehind when I've updated the div to fade it back in. 在页面加载时注册事件处理程序以检测div的内容何时被更改并淡入其中,或者在我更新div以将其淡入时从asp.net代码隐藏中调用函数。

In the first case, there doesn't seem to be any event triggered by the div 's content changing, so I can't seem to do that. 在第一种情况下,似乎没有任何事件由div的内容改变引发,所以我似乎无法做到这一点。 If anyone knows how I could get a client event to trigger when I update the div , that would be a nice solution. 如果有人知道如何在更新div时触发客户端事件,那将是一个很好的解决方案。

In the second case, I thought that this was what ClientScriptManager was for, but it doesn't quite do what I want. 在第二种情况下,我认为这就是ClientScriptManager用途,但它并没有完全符合我的要求。 I want to be able to register a particular Javascript function with ClientScriptManager and then tell ClientScriptManager to execute it in the client, from my codebehind. 我希望能够使用ClientScriptManager注册特定的Javascript函数,然后告诉ClientScriptManager在我的代码隐藏中在客户端中执行它。 You can't seem to do that. 你似乎无法做到这一点。 ClientScriptManager.RegisterClientScriptBlock() simply inserts some <script> into the HTML output, rather than calling a function. ClientScriptManager.RegisterClientScriptBlock()只是将一些<script>插入到HTML输出中,而不是调用函数。 Presumably this would work if I kept registering things like: 据推测,如果我继续注册以下内容,这将会起作用:

<script>fadeBackIn();</script>

because the Javascript would be immediately evaluated and run, but this feels messy, and that feeling is intensified by the fact that I'd have to keep randomly generating a new unique value for the key argument of ClientScriptManager.RegisterClientScriptBlock() , because it's specifically designed to stop this kind of repeated code. 因为Javascript会被立即评估和运行,但这感觉很麻烦,而且我必须为ClientScriptManager.RegisterClientScriptBlock()key参数随机生成一个新的唯一值,这种感觉会加剧,因为它具体旨在阻止这种重复的代码。 However, I'm struggling to see an alternative. 但是,我很难看到另一种选择。 Can anyone come up with a good idea as to a better mechanism to get this to work? 任何人都可以想出一个更好的机制来让这个工作吗?

I'd really like something along the lines of: 我真的很喜欢以下内容:

ClientScriptManager.RegisterClientScriptFunction("fadeBackIn", "function fadeBackIn(){ ... }");

[...]

ClientScriptManager.ExecuteClientScriptFunction("fadeBackIn");

but I don't see that functionality available. 但我没有看到可用的功能。 :-( :-(

You can attach to the page loaded event. 您可以附加到页面加载的事件。 The pageLoaded handler recieves an argument of type PageLoadedEventArgs which contains a get_panelsUpdated method that you can call to enumerate all the UpdatePanels whose content was just updated. pageLoaded处理程序接收一个类型为PageLoadedEventArgs的参数,该参数包含一个get_panelsUpdated方法,您可以调用该方法枚举其内容刚刚更新的所有UpdatePanel。

Example: 例:

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

function pageLoaded(sender, args) 
{
    var panels = args.get_panelsUpdated();

    if (panels.length > 0) 
    {
        for (var i in panels) 
        {
            if (panels[i].id == "DesiredUpdatePanelId") 
            {
                fadeBackIn(); 
            }
        }
    }
}

Because html is stateless, you'll need an asynchronous way of determining if the content has changed in your div. 因为html是无状态的,所以你需要一种异步的方法来确定div中的内容是否已经改变。 I would try using the window.setInterval to check if your content has changed every 500ms or so. 我会尝试使用window.setInterval来检查您的内容是否每500毫秒左右更改一次。

If your div looks like this: 如果您的div看起来像这样:

<div id="mycontent">Blah, blah.</div>

Then this might be a solution: 那么这可能是一个解决方案:

$(function(){

   var $mycontent = $('#mycontent');
   var myContentHtml = $mycontent.html();
   var intervalId;

   function checkIfDivChanged()
   {
      window.clearInterval(intervalId);

      if (myContentHtml != $mycontent.html())
      {
         myContentHtml = $mycontent.html();

         // run update here..
         fadeBackIn();

         // if you want to stop the check then uncomment next line..
         // return;
      }

      intervalId = window.setInterval(checkIfDivChanged, 500);          
   }

   checkIfDivChanged();
});

If you are using, or are willing to use the ASP.NET Ajax Control Toolkit, it contains a control that does exactly what you are looking for: UpdatePanelAnimation. 如果您正在使用或者愿意使用ASP.NET Ajax控件工具包,它将包含一个完全符合您要求的控件:UpdatePanelAnimation。

Take a look here for more information on that control, and here for more information on using animations. 看看这里的上控制的详细信息,并在这里对利用动画的更多信息。

I have written small script with pure JavaScript (no jQuery required), you can just have this script in your page and change the alert part.. plus of course the ID of the div element. 我用纯JavaScript编写了小脚本(不需要jQuery),你可以在你的页面中使用这个脚本并更改警报部分..当然还有div元素的ID。

<script type="text/javascript">
var _watchTimer = 0;
window.onload = function WindowLoad(evt) {
    _watchTimer = window.setInterval("WatchForChange();", 100);
}

function WatchForChange()
{
    var oDiv = document.getElementById("MyDivToWatch");
    if (oDiv == null)
    {
        window.clearInterval(_watchTimer);
        return;
    }
    var prevHtml = oDiv.getAttribute("prev_html") || "";
    var curHtml = oDiv.innerHTML;
    if (prevHtml != curHtml)
    {
        if (prevHtml.length > 0)
        {
            alert("content changed");
        }
        else
        {
            //first run, ignore
        }
        oDiv.setAttribute("prev_html", curHtml);
    }
}
</script>
<div id="MyDivToWatch">I can be changed..</div>
<button type="button" onclick="document.getElementById('MyDivToWatch').innerHTML += ' like this..';">Change</button>

Added the whole code used to test, used a button to dynamically change the contents but it should work with changing it via AJAX call aka UpdatePanel. 添加了用于测试的整个代码,使用按钮动态更改内容,但它应该通过AJAX调用也称为UpdatePanel来更改它。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM