我已经看到类似的问题和答案,但似乎没有解决问题。
我在更新面板中有一个用户控件。在我的用户控件中,我输出了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!');"
如上所述,将功能移动到父页面也可以。
就好像浏览器忽略了用户控件的脚本输出。
有什么想法吗?
答案 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 :(得分: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代码的首选方法是订阅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')
}
替代解决方案是使用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")
}