ASP.NET Control 的 GetElementById 不断返回“null”;
我花了一个多小时试图解决这个问题,我很绝望。我正在尝试访问 DOM 中从 ASP.NET 控件创建的节点。我使用完全相同的 id,并且在页面渲染后查看 HTML 源代码时可以看到它们是匹配的。这是我的[根据建议修改,但仍然不起作用]代码:
ASP.NET Header
<asp:Content ID="HeaderContent" runat="server" ContentPlaceHolderID="HeadContent">
<script type="text/javascript">
$(document).ready(
var el = document.getElementById('<%= txtBox.ClientID %>');
el.onchange = alert('test!!');
)
</script>
</asp:Content>
ASP.NET Body
<asp:TextBox ID="txtBox" runat="server"></asp:TextBox>
Resulting Javascript & ASP.NET Header ASP.NET Body Resulting Javascript &从上面的 HTML
<script type="text/javascript">
$(document).ready(
var el = document.getElementById('MainContent_txtBox');
el.onchange = alert('test!!');
)
</script>
...
<textarea name="ctl00$MainContent$txtBox" id="MainContent_txtBox"></textarea>
我只能假设脚本是在控件 id 解析之前加载的,但是当我使用 Chrome 的“检查元素”功能查看时间线时,情况似乎并非如此。当我创建一个常规文本区域框来测试和实现相同的代码(当然不同的 id)时,警报框会触发。
我到底错过了什么?这让我发疯>。<
编辑:奇怪的代码可以工作,但仅在初始页面加载时有效;触发 onload 而不是 onchange。甚至 jQuery 也表示 .ready 显然无法正常工作。啊!!
$(document).ready(function() {
document.getElementById('<%= txtBox.ClientID %>').onchange = alert('WORKING!');
})
I'm desperate having spent well over an hour trying to troubleshoot this. I am trying to access a node in the DOM which is created from an ASP.NET control. I'm using exactly the same id and I can see that they match up when looking at the HTML source code after the page has rendered. Here's my [MODIFIED according to suggestions, but still not working] code:
ASP.NET Header
<asp:Content ID="HeaderContent" runat="server" ContentPlaceHolderID="HeadContent">
<script type="text/javascript">
$(document).ready(
var el = document.getElementById('<%= txtBox.ClientID %>');
el.onchange = alert('test!!');
)
</script>
</asp:Content>
ASP.NET Body
<asp:TextBox ID="txtBox" runat="server"></asp:TextBox>
Resulting Javascript & HTML from above
<script type="text/javascript">
$(document).ready(
var el = document.getElementById('MainContent_txtBox');
el.onchange = alert('test!!');
)
</script>
...
<textarea name="ctl00$MainContent$txtBox" id="MainContent_txtBox"></textarea>
I can only assume that the script is loading before the control id has been resolved, yet when I look at the timeline with Chrome's "Inspect Element" feature, it appears that is not the case. When I created a regular textarea box to test and implement the identical code (different id of course), the alert box fires.
What on earth am I missing here? This is driving me crazy >.<
EDIT: Wierd code that works, but only on the initial page load; firing onload rather than onchange. Even jQuery says that .ready doesn't work properly apparently. Ugh!!
$(document).ready(function() {
document.getElementById('<%= txtBox.ClientID %>').onchange = alert('WORKING!');
})
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(3)
假设渲染的标记确实按该顺序出现,问题是当您的 JavaScript 尝试查找该元素时该元素还不存在。
要么将该 JS 移动到元素下方(最好是在正文的末尾),要么将其包装在 jQuery 的文档准备中事件处理程序。
更新:
为了响应您的编辑,您已经差不多完成了,但是(正如其他人提到的)您需要为 onchange 事件分配一个函数,而不是
alert()< 的返回结果/代码>。类似这样:
通过编写
onchange =alert('Working');
,您要求 JavaScript 将alert()
方法的结果分配给 onchange 属性。这就是为什么它在页面加载时立即执行它,但实际上从未响应 onchange 事件(因为您没有为该函数分配运行 onchange 的函数)。Assuming the rendered markup does appear in that order, the problem is that the element doesn't yet exist at the time your JavaScript is attempting to locate it.
Either move that JS below the element (preferably right at the end of the body) or wrap it in something like jQuery's document ready event handler.
Update:
In response to your edits, you're almost there but (as others have mentioned) you need to assign a function to the onchange event, not the return result of
alert()
. Something like this:By writing
onchange = alert('Working');
, you were asking JavaScript to assign the result of thealert()
method to the onchange property. That's why it was executing it immediately on page load, but never actually in response to the onchange event (because you hadn't assigned that a function to run onchange).选择 jQuery。
那么你可以
Pick up jQuery.
Then you can
其他答案已经指出了错误(尝试在 DOM 节点出现在文档中之前访问它们),我只会指出替代解决方案。
简单方法
在 HTML 中添加脚本元素,位于您要访问的元素的结束标记下方。最简单的形式是将其放在结束正文标记之前。此策略还可以使页面显示得更快,因为浏览器不会暂停加载脚本的 HTML。总体加载时间是相同的,但是脚本仍然需要加载并执行,只是这个顺序让用户感觉更慢。
使用 window.onload 或
每个浏览器都支持此方法,但它会在加载所有内容后触发,因此页面可能会在短时间内显示为不活动状态(如果加载已解除,则可能会显示很长时间)。但它非常坚固。
使用 DOM 就绪函数
其他人建议使用 jQuery,但您可能不希望仅仅为了 DOM 就绪函数就需要 4,000 行和 90kb 的代码。 jQuery 相当复杂,很难从库中删除。然而,David Mark 的 MyLibrary 非常模块化,并且很容易提取您想要的部分。代码质量也非常好,至少与任何其他库相同。
以下是从 MyLibrary 中提取的 DOM 就绪函数的示例:
将其用于您的情况:
或者可以提供匿名函数:
如果您只需要一个用于特定情况的函数,则可以在 10 行代码中完成非常简单的 DOM 就绪函数,但当然它们的健壮性较差并且可重复使用性较差。
Other answers have pointed out the error (attempting to access DOM nodes before they are in the document), I'll just point out alternative solutions.
Simple method
Add the script element in the HTML below the closing tag of the element you wish to access. In its easiest form, put it just before the closing body tag. This strategy can also make the page appear faster as the browser doesn't pause loading HTML for script. Overall load time is the same however, scripts still have to be loaded an executed, it's just that this order makes it seem faseter to the user.
Use window.onload or <body onload="..." ...>
This method is supported by every browser, but it fires after all content is loaded so the page may appear inactive for a short time (or perhaps a long time if loading is dealyed). It is very robust though.
Use a DOM ready function
Others have suggested jQuery, but you may not want 4,000 lines and 90kb of code just for a DOM ready function. jQuery's is quite convoluted so hard to remove from the library. David Mark's MyLibrary however is very modular and quite easy to extract just the bits you want. The code quality is also excellent, at least the equal of any other library.
Here is an example of a DOM ready function extracted from MyLibrary:
Using it for your case:
or an anonymous function can be supplied:
Very simple DOM ready functions can be done in 10 lines of code if you just want one for a specific case, but of course they are less robust and not as reusable.