| 1 | <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
|
|---|
| 2 | <html lang="en">
|
|---|
| 3 | <head>
|
|---|
| 4 | <title>jQuery width() Bug</title>
|
|---|
| 5 | <style type="text/css">
|
|---|
| 6 | #div1 {
|
|---|
| 7 | position: absolute;
|
|---|
| 8 | border: 1px dashed black;
|
|---|
| 9 | padding: 10px;
|
|---|
| 10 | }
|
|---|
| 11 | #div2 {
|
|---|
| 12 | position: absolute;
|
|---|
| 13 | border: 1px dashed black;
|
|---|
| 14 | padding: 10px;
|
|---|
| 15 | }
|
|---|
| 16 | #div3 {
|
|---|
| 17 | width: 200px;
|
|---|
| 18 | position: absolute;
|
|---|
| 19 | border: 1px dashed black;
|
|---|
| 20 | padding: 10px;
|
|---|
| 21 | }
|
|---|
| 22 | #div4 {
|
|---|
| 23 | width: 200px;
|
|---|
| 24 | position: absolute;
|
|---|
| 25 | border: 1px dashed black;
|
|---|
| 26 | padding: 10px;
|
|---|
| 27 | }
|
|---|
| 28 | </style>
|
|---|
| 29 | <script type="text/javascript" src="js/jquery-nightly.js"></script>
|
|---|
| 30 | <script type="text/javascript">
|
|---|
| 31 | $(function() {
|
|---|
| 32 | $("#div2").hide();
|
|---|
| 33 | $("#div1w").text( $("#div1").width() );
|
|---|
| 34 | $("#div2w").text( $("#div2").width() );
|
|---|
| 35 |
|
|---|
| 36 | $("#showBtn").click(function(evt) {
|
|---|
| 37 | $("#div1").toggle(); // get div1 out of the way
|
|---|
| 38 | $("#div2").toggle();
|
|---|
| 39 | $("#div2w").text( $("#div2").width() );
|
|---|
| 40 | });
|
|---|
| 41 |
|
|---|
| 42 | $("#div4").hide();
|
|---|
| 43 | $("#div3w").text( $("#div3").width() );
|
|---|
| 44 | $("#div4w").text( $("#div4").width() );
|
|---|
| 45 |
|
|---|
| 46 | $("#showBtn2").click(function(evt) {
|
|---|
| 47 | $("#div3").toggle(); // get div3 out of the way
|
|---|
| 48 | $("#div4").toggle();
|
|---|
| 49 | $("#div4w").text( $("#div4").width() );
|
|---|
| 50 | });
|
|---|
| 51 | });
|
|---|
| 52 | </script>
|
|---|
| 53 | </head>
|
|---|
| 54 |
|
|---|
| 55 | <body>
|
|---|
| 56 | <h1>width() Bug</h1>
|
|---|
| 57 | <p>jQuery's width() method returns an incorrect value when used on an invisible element with
|
|---|
| 58 | absolute or fixed positioning. However, this is only the case when the invisible element does
|
|---|
| 59 | not have an explicitly assigned width. This can be traced to the css() method: in its "width"
|
|---|
| 60 | case for invisible elements, it clones the node and sets the padding/border widths to zero to
|
|---|
| 61 | measure the element. The problem is that it also explicitly sets the "left" and "right" edge
|
|---|
| 62 | positions, which will implicitly change the element's width when it has no explicit width. That
|
|---|
| 63 | code appears to be intended to position the element at the origin point of the page, but due to
|
|---|
| 64 | a simple oversight actually ends up changing the element size. This behaviour is consistently
|
|---|
| 65 | incorrect on Firefox 2, IE 7, and Opera 9 (all on Windows; I don't have access to a Mac).</p>
|
|---|
| 66 |
|
|---|
| 67 | <p>The work-around, is of course, to display the element before trying to get its size. However,
|
|---|
| 68 | you shouldn't have to do this, and usually you want to position the element before displaying
|
|---|
| 69 | it. Changing the positioning to something else is no good, since that completely changes how
|
|---|
| 70 | the browser sizes the element.</p>
|
|---|
| 71 |
|
|---|
| 72 | <p>This demonstrates the bug. Watch the #div2/#div4 width values as you click the buttons.</p>
|
|---|
| 73 |
|
|---|
| 74 |
|
|---|
| 75 | <h2>Div's without explicit widths</h2>
|
|---|
| 76 | <table>
|
|---|
| 77 | <tr><th>Div id</th><th>Result of width()</th></tr>
|
|---|
| 78 | <tr><td>div1</td><td id="div1w"></td></tr>
|
|---|
| 79 | <tr><td>div2</td><td id="div2w"></td></tr>
|
|---|
| 80 | </table>
|
|---|
| 81 |
|
|---|
| 82 | <input type="button" id="showBtn" value="Toggle #div2">
|
|---|
| 83 |
|
|---|
| 84 | <div id="div1">
|
|---|
| 85 | This is div #div1
|
|---|
| 86 | </div>
|
|---|
| 87 | <div id="div2">
|
|---|
| 88 | Div #div2 lies here
|
|---|
| 89 | </div>
|
|---|
| 90 |
|
|---|
| 91 |
|
|---|
| 92 | <h2 style="margin-top: 3em">Div's with explicit widths</h2>
|
|---|
| 93 | <table>
|
|---|
| 94 | <tr><th>Div id</th><th>Result of width()</th></tr>
|
|---|
| 95 | <tr><td>div3</td><td id="div3w"></td></tr>
|
|---|
| 96 | <tr><td>div4</td><td id="div4w"></td></tr>
|
|---|
| 97 | </table>
|
|---|
| 98 |
|
|---|
| 99 | <input type="button" id="showBtn2" value="Toggle #div4">
|
|---|
| 100 |
|
|---|
| 101 | <div id="div3">
|
|---|
| 102 | This is div #div3
|
|---|
| 103 | </div>
|
|---|
| 104 | <div id="div4">
|
|---|
| 105 | Div #div4 lies here
|
|---|
| 106 | </div>
|
|---|
| 107 |
|
|---|
| 108 |
|
|---|
| 109 | <h2 style="margin-top: 3em">The Fix</h2>
|
|---|
| 110 | <p>The bug has an easy, one-line fix:</p>
|
|---|
| 111 |
|
|---|
| 112 | <strong>From: <a href="http://dev.jquery.com/browser/trunk/jquery/src/core.js?rev=3669#L773">src/core.js@3669, line 773</a></strong>
|
|---|
| 113 | <pre>right: "0",</pre>
|
|---|
| 114 |
|
|---|
| 115 | <strong>To:</strong>
|
|---|
| 116 | <pre>top: "0",</pre>
|
|---|
| 117 | </body>
|
|---|
| 118 | </html>
|
|---|