asp.net 用户控件不会在 updatepanel 中触发 javascript
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/15988629/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
asp.net usercontrol won't fire javascript inside updatepanel
提问by Adam Wood
I've seen similar issues to this and answers but none seem to fix the issue.
我见过与此类似的问题和答案,但似乎都没有解决问题。
I have a user control inside an update panel. Inside my user control I output javascript.
我在更新面板中有一个用户控件。在我的用户控件中,我输出 javascript。
The javascript will not fire when triggered. If I move the javascript to the parent page outside of the usercontrol/updatepanels then it fires. This doesn't make sense to do this as I can't use this usercontrol on another page without either duplicating code...by either duplicating the entire javascript (different site) or adding references to a .js file in every page it's used on (same site). It's just less portable
javascript 不会在触发时触发。如果我将 javascript 移动到 usercontrol/updatepanels 之外的父页面,那么它就会触发。这没有意义,因为我不能在另一个页面上使用这个用户控件而不复制代码......通过复制整个 javascript(不同的站点)或在它使用的每个页面中添加对 .js 文件的引用在(同一站点)。它只是不那么便携
I merely want to output the javascript with the control (inside the update panel).
我只想输出带有控件的 javascript(在更新面板内)。
The updatepanel is mentioned for accuracy of what I'm doing. It doesn't work even if I place the usercontrol outside of updatepanels.
提到更新面板是为了确保我正在做的事情的准确性。即使我将用户控件放在更新面板之外,它也不起作用。
Keeping it simple (This does not work for me):
保持简单(这对我不起作用):
USERCONTROL:
用户控制:
<%@ 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" />
Debugging in chrome tells me "Uncaught ReferenceError: test is not defined"
在 chrome 中调试告诉我“未捕获的 ReferenceError:未定义测试”
If I add the javascript directly to the onclick as below, it works:
如果我将 javascript 直接添加到 onclick 如下,它可以工作:
onclick="alert('Hello World!');"
And as stated above, moving the function to the parent page ALSO works.
如上所述,将功能移动到父页面也有效。
It's as if the browser ignores the script output from the user control.
就好像浏览器忽略了用户控件的脚本输出。
Any ideas?
有任何想法吗?
回答by Aristos
When you have an UpdatePanel
and that UpdatePanel
updates it's content, it treats it's content as simple text/html (not code), it does not have any parser available to run the script and make it available for the page.
当您有一个UpdatePanel
并UpdatePanel
更新其内容时,它将其内容视为简单的文本/html(不是代码),它没有任何解析器可用于运行脚本并使其可用于页面。
So this content,
所以这个内容,
<script type="text/javascript">
function test() { alert('Hello World!'); }
</script>
<a href="javascript:void(0);" onclick="javascript:test();">
Find For Me
</a>
after client side code of update panel runs and updates content of the page, the script part is not parsed - its simple text/html for the page.
在更新面板的客户端代码运行并更新页面内容后,不会解析脚本部分 - 页面的简单文本/html。
This part however runs
然而这部分运行
<a href="javascript:void(0);" onclick="alert('Hello World!');">Find For Me</a>
because the parse of the onclick
attribute is done when you click on it.
因为onclick
当你点击它时,属性的解析就完成了。
There are following workarounds available:
有以下解决方法可用:
- Move your javascript into external file
- Move you script outside of the UpdatePanel
- Register the script in the code behind with RegisterClientScriptBlockor alternative functions.
- 将您的 javascript 移动到外部文件中
- 将您的脚本移到 UpdatePanel 之外
- 使用RegisterClientScriptBlock或替代函数在后面的代码中注册脚本。
回答by Adam Wood
Thanks to Aristos for sending me down the right path... Though his solution works, it did not answer the question of outputting the javascript from inside the usercontrol but instead suggested moving it outside. This was not the desired outcome, as stated, as it's not kept inside the control for easier portability.
感谢 Aristos 送我走正确的道路......虽然他的解决方案有效,但它没有回答从用户控件内部输出 javascript 的问题,而是建议将其移到外部。如前所述,这不是想要的结果,因为它没有保存在控件中以方便携带。
Here is my solution that accomplishes this: CS file:
这是我完成此操作的解决方案:CS 文件:
String script = "<script type=\"text/javascript\">";
script += "function test() {";
script += "alert('Hello World!');";
script += "</script>";
Page.ClientScript.RegisterClientScriptBlock(Page.GetType(), "locationScript", script);
One might use a stringbuilder if script is longer, but eitherway works.
如果脚本较长,可以使用 stringbuilder,但无论如何都可以。
This keeps the code entirely inside the usercontrol and it works from the onclick event of the a tag.
这将代码完全保留在用户控件中,并通过 a 标记的 onclick 事件工作。
回答by Daniel
In Addition to the solution that Adam Wood posted, I should say that you must use ScriptManager to register the script when using update panel, at least in .net 4.0 because otherwise it won′t work.
除了 Adam Wood 发布的解决方案之外,我应该说在使用更新面板时必须使用 ScriptManager 来注册脚本,至少在 .net 4.0 中,否则它将无法工作。
So you can put on the PageLoad event of the usercontrol:
所以你可以把用户控件的 PageLoad 事件:
string script = @" alert('this is a test');
alert('it worked')";
ScriptManager.RegisterStartupScript(Page,Page.GetType(),"scriptMelhoria",script,true);
回答by tolga güler
Try this;
试试这个;
You can find your script elements after udpdate panel callback and evaluate them.
您可以在 udpdate 面板回调后找到您的脚本元素并对其进行评估。
Add a special attribute to your inline script tag to select elements after callback request.
向您的内联脚本标记添加一个特殊属性,以在回调请求后选择元素。
<script type="text/javascript" data-tag='myscript'>
function test() {
alert('Hello World!');
}
</script>
And add this script to your update panel container aspx file.
并将此脚本添加到您的更新面板容器 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>
回答by vittore
Preferred way of dealing with javscript code that is bound to DOM elements within UpdatePanel
is to subscribe to endRequest
event of PageRequestManagerand execute your code here. For instance you want to set click event handlers here.
处理绑定到其中的 DOM 元素的 javscript 代码的首选方法UpdatePanel
是订阅PageRequestManager 的endRequest
事件并在此处执行您的代码。例如,您想在此处设置单击事件处理程序。
// 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')
}
Alternative solution will be to use event delegationlike so:
另一种解决方案是使用事件委托,如下所示:
function pageLoad() {
// delegate click event on .myButton inside .container
// to the .container DOM element
$('.container').on('click', '.myButton', test)
}
And have div
with a class named container
around your update panel. In this case your div.container
is never removed from DOM so all event handlers on it will hold after partial postbacks.
并在更新面板周围div
命名一个类container
。在这种情况下,您div.container
永远不会从 DOM 中删除,因此它上的所有事件处理程序将在部分回发后保留。
Same code without jquery and using only asp.net ajax will look like this:
没有 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")
}