Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

getElementById() fails to get element when display:none

We have several cases of $get('foo') or document.getElementById('foo') failing when the element being looked for has style="display:none;". This seems to work in some browsers but not others; specifically the case shown below works fine in IE9 with compatibility mode but fails when compatibility mode is turned off.

Can anyone explain why this might happen, and how we can work around it? An example follows.

Our ASPX page contains

<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>

that results in this generated 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>

The following Javascript statements should result in the wrapper variables containing objects but in some browsers, or compatibility modes in IE9, the value of jobAddressWrapper is null. The value of predefinedReplyWrapper is never null. The only difference between them is that JobAddressCheckboxWrapper has style="display:none;".

var jobAddressWrapper = $get('JobAddressCheckboxWrapper');
var predefinedReplyWrapper = $get('PredefinedReplyCheckBoxWrapper');

or

var jobAddressWrapper = document.getElementById('JobAddressCheckboxWrapper');
var jobAddressWrapper = document.getElementById('PredefinedReplyCheckBoxWrapper');

The HTML pattern with elements wrapped by a span is not relevant; there are other cases where elements are not wrapped by spans but can still not be reference if they have style="display:none;".

Updates (in response to comments, etc.):

  1. $get provides a shortcut to the getElementById method of the Sys.UI.DomElement class. More info here
  2. These calls are made in functions called both from onload and in response to user interaction. The problem happens in either case.
like image 861
Steve Crane Avatar asked Nov 03 '22 17:11

Steve Crane


2 Answers

This really is an odd problem to have, so before anything else check the code for typos and scope confusion! Also this is really, really old - so hopefully you are not still having this problem. =)

One solution you might find, however, will often help when you are trying to work past such problems, or even better find their cause. Use jQuery selection $('#AnyID'), mind the css # syntax if you're not familiar.

Browsers have come a long way in attempting to be more compatible, with a long way to go. Earlier on I used jQuery quite often to deduce why a vanilla JS instruction was not working the way I intended it to in one browser and would work in another. Usually I would find that I didn't understand JS well enough and jQuery just knew already what I needed learn =)

like image 143
Garet Claborn Avatar answered Nov 08 '22 04:11

Garet Claborn


this answer is perhaps not relevant to every instance of the problem, but I encountered it while using ASP.NET Master pages;

with ContentPlaceHolderID="MainContent", my div id="IdValidationErrorDiv" actually has a rendered id of "MainContent_IdValidationErrorDiv".

calling getElementById with this id succeeded.

like image 25
DOrbital Avatar answered Nov 08 '22 05:11

DOrbital