getElementById() 在 display:none 时无法获取元素

Ste*_*ane 5 javascript asp.net-ajax

当要查找的元素具有 时,我们有几种情况$get('foo')document.getElementById('foo')失败style="display:none;"。这似乎在某些浏览器中有效,但在其他浏览器中无效;特别是下面显示的情况在兼容模式下在 IE9 中工作正常,但在兼容模式关闭时失败。

谁能解释为什么会发生这种情况,以及我们如何解决它?下面是一个例子。

我们的 ASPX 页面包含

<span id="JobAddressCheckBoxWrapper" style="display: none;">
  <asp:CheckBox ID="JobAddressCheckBox" CssClass="DefaultTextCell" runat="server" Text="__Job address"
    Style="margin-right: 2em;" onclick="ShowJobAddress();" />
</span>
<span id="PredefinedReplyCheckBoxWrapper">
  <asp:CheckBox ID="PredefinedReplyCheckBox" CssClass="DefaultTextCell" runat="server"
    Text="__Pre-defined reply" onclick="ShowReplies()" AutoPostBack="false" Style="margin-right: 2em;" />
</span>
Run Code Online (Sandbox Code Playgroud)

这导致生成的 HTML

<span style="display: none;" id="JobAddressCheckBoxWrapper">
  <span style="margin-right: 2em;" class="DefaultTextCell">
    <input id="JobAddressCheckBox" onclick="ShowJobAddress();" name="JobAddressCheckBox" type="checkbox">
    <label for="JobAddressCheckBox">Job address</label>
  </span>
</span>
<span id="PredefinedReplyCheckBoxWrapper">
  <span style="margin-right: 2em;" class="DefaultTextCell">
    <input id="PredefinedReplyCheckBox" onclick="ShowReplies();" name="PredefinedReplyCheckBox" type="checkbox">
    <label for="PredefinedReplyCheckBox">Predefined reply</label>
  </span>
</span>
Run Code Online (Sandbox Code Playgroud)

以下 Javascript 语句应该会导致包装器变量包含对象,但在某些浏览器或 IE9 中的兼容模式中,jobAddressWrapper 的值为 null。预定义ReplyWrapper 的值永远不会为空。它们之间的唯一区别是 JobAddressCheckboxWrapper 具有style="display:none;".

var jobAddressWrapper = $get('JobAddressCheckboxWrapper');
var predefinedReplyWrapper = $get('PredefinedReplyCheckBoxWrapper');
Run Code Online (Sandbox Code Playgroud)

或者

var jobAddressWrapper = document.getElementById('JobAddressCheckboxWrapper');
var jobAddressWrapper = document.getElementById('PredefinedReplyCheckBoxWrapper');
Run Code Online (Sandbox Code Playgroud)

元素被 span 包裹的 HTML 模式是不相关的;还有其他情况,元素没有被跨度包裹,但如果有style="display:none;".

更新(回应评论等):

  1. $get 提供了 Sys.UI.DomElement 类的 getElementById 方法的快捷方式。更多信息在这里
  2. 这些调用是在从 onload 和响应用户交互调用的函数中进行的。在任何一种情况下都会出现问题。

Gar*_*orn 1

这确实是一个奇怪的问题,所以在做其他事情之前检查代码是否有拼写错误和范围混淆!而且这真的非常非常旧 - 所以希望你不会仍然遇到这个问题。=)

然而,当您尝试解决此类问题,甚至更好地找到其原因时,您可能会找到一种解决方案,通常会有所帮助。使用 jQuery 选择$('#AnyID'),如果您不熟悉,请注意 css # 语法。

浏览器在尝试提高兼容性方面已经取得了很大的进步,而且还有很长的路要走。早些时候,我经常使用 jQuery 来推断为什么普通 JS 指令在一个浏览器中不能按我预期的方式工作,而在另一个浏览器中却可以工作。通常我会发现我对 JS 的理解不够好,而 jQuery 已经知道我需要学习什么 =)