SWilk
2008-Feb-20 18:10 UTC
Element.getDimensions() -- Element display not set, but ancestor''s display:none. Bug?
Hi, I have found an irritating behaviour of Element.getWidth(), or a bug maybe. Assume we have some code: <div style="display: none;"> <!-- many elements here: a table with about 60 inputs, labels etc --> <input id="elem" class="a_class_that_sets_the_width" /> </div> I read the elem.getWidth() in page onLoad event handler. The div is invisible ATM. I need to change the width (substract 22px and add it to padding, then place an icon over the input, to be specific). I''m doing it from script that have to be universal, so I can''t hard-code the final width. Unfortunatelly, the Prototype''s getDimensions() method used by getWidth() checks only if the elems.style.display is none/null, which isn''t in this case - it''s inline. As the result, getDimensions returns zeros for both width and height. I tried to modify method to disable checking for display, so the metod did it''s "magic" to determine dimensions. Not succeded either. Is there any way of determining dimensions of an element inside another, invisible, element? Regards, Szymon Wilkołazki --~--~---------~--~----~------------~-------~--~----~ You received this message because you are subscribed to the Google Groups "Ruby on Rails: Spinoffs" group. To post to this group, send email to rubyonrails-spinoffs-/JYPxA39Uh5TLH3MbocFFw@public.gmane.org To unsubscribe from this group, send email to rubyonrails-spinoffs-unsubscribe-/JYPxA39Uh5TLH3MbocFFw@public.gmane.org For more options, visit this group at http://groups.google.com/group/rubyonrails-spinoffs?hl=en -~----------~----~----~----~------~----~------~--~---
kangax
2008-Feb-20 19:16 UTC
Re: Element.getDimensions() -- Element display not set, but ancestor''s display:none. Bug?
Szymon, There''s a patch in a trac [1] which might or might not make its way into the core. The patch makes sure #getDimensions temporarily "displays" all "hidden" ancestors of an element, allowing clientWidth/ clientHeight (used internally) to yield the correct results. We are deciding on some performance issues at the moment, as this could lead to undesired overhead. [1] http://dev.rubyonrails.org/ticket/11142 Best, kangax On Feb 20, 1:10 pm, SWilk <wilkola...-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org> wrote:> Hi, > > I have found an irritating behaviour of Element.getWidth(), or a bug > maybe. > > Assume we have some code: > > <div style="display: none;"> > <!-- many elements here: a table with about 60 inputs, labels etc --> > <input id="elem" class="a_class_that_sets_the_width" /> > </div> > > I read the elem.getWidth() in page onLoad event handler. The div is > invisible ATM. I need to change the width (substract 22px and add it > to padding, then place an icon over the input, to be specific). I''m > doing it from script that have to be universal, so I can''t hard-code > the final width. > > Unfortunatelly, the Prototype''s getDimensions() method used by > getWidth() checks only if the elems.style.display is none/null, which > isn''t in this case - it''s inline. As the result, getDimensions returns > zeros for both width and height. > > I tried to modify method to disable checking for display, so the metod > did it''s "magic" to determine dimensions. Not succeded either. > > Is there any way of determining dimensions of an element inside > another, invisible, element? > > Regards, > Szymon Wilkołazki--~--~---------~--~----~------------~-------~--~----~ You received this message because you are subscribed to the Google Groups "Ruby on Rails: Spinoffs" group. To post to this group, send email to rubyonrails-spinoffs-/JYPxA39Uh5TLH3MbocFFw@public.gmane.org To unsubscribe from this group, send email to rubyonrails-spinoffs-unsubscribe-/JYPxA39Uh5TLH3MbocFFw@public.gmane.org For more options, visit this group at http://groups.google.com/group/rubyonrails-spinoffs?hl=en -~----------~----~----~----~------~----~------~--~---
Jon L.
2008-Feb-20 19:24 UTC
Re: Element.getDimensions() -- Element display not set, but ancestor''s display:none. Bug?
The short answer: no, you can''t. There''s work-arounds, as kangax suggested. But, dynamic width and height are based on the browser''s rendering of an element. So, if the element is not rendered (or, hidden) then its width and height are 0. There aren''t any "what would" values; just "what are" (hopefully, that makes sense). - Jon L. On Feb 20, 12:10 pm, SWilk <wilkola...-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org> wrote:> Hi, > > I have found an irritating behaviour of Element.getWidth(), or a bug > maybe. > > Assume we have some code: > > <div style="display: none;"> > <!-- many elements here: a table with about 60 inputs, labels etc --> > <input id="elem" class="a_class_that_sets_the_width" /> > </div> > > I read the elem.getWidth() in page onLoad event handler. The div is > invisible ATM. I need to change the width (substract 22px and add it > to padding, then place an icon over the input, to be specific). I''m > doing it from script that have to be universal, so I can''t hard-code > the final width. > > Unfortunatelly, the Prototype''s getDimensions() method used by > getWidth() checks only if the elems.style.display is none/null, which > isn''t in this case - it''s inline. As the result, getDimensions returns > zeros for both width and height. > > I tried to modify method to disable checking for display, so the metod > did it''s "magic" to determine dimensions. Not succeded either. > > Is there any way of determining dimensions of an element inside > another, invisible, element? > > Regards, > Szymon Wilkołazki--~--~---------~--~----~------------~-------~--~----~ You received this message because you are subscribed to the Google Groups "Ruby on Rails: Spinoffs" group. To post to this group, send email to rubyonrails-spinoffs-/JYPxA39Uh5TLH3MbocFFw@public.gmane.org To unsubscribe from this group, send email to rubyonrails-spinoffs-unsubscribe-/JYPxA39Uh5TLH3MbocFFw@public.gmane.org For more options, visit this group at http://groups.google.com/group/rubyonrails-spinoffs?hl=en -~----------~----~----~----~------~----~------~--~---
SWilk
2008-Feb-21 09:46 UTC
Re: Element.getDimensions() -- Element display not set, but ancestor''s display:none. Bug?
Hi, kangax wrote:> > There''s a patch in a trac [1] which might or might not make its way > into the core. The patch makes sure #getDimensions temporarily > "displays" all "hidden" ancestors of an element, allowing clientWidth/ > clientHeight (used internally) to yield the correct results.I applied the patch and it works perfectly for me. Thank you.> We are deciding on some performance issues at the moment, as this > could lead to undesired overhead. >In my case it works grate and I haven''t experience much performance influence by this change but I''ll test it more before I''ll put patched prototype.js into my production env. Thanks once more for your help and much thanks for all of you who writes prototype. Regards Szymon Wilkolazki> On Feb 20, 1:10 pm, SWilk <wilkola...-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org> wrote: >> Hi, >> >> I have found an irritating behaviour of Element.getWidth(), or a bug >> maybe. >> >> Assume we have some code: >> >> <div style="display: none;"> >> <!-- many elements here: a table with about 60 inputs, labels etc --> >> <input id="elem" class="a_class_that_sets_the_width" /> >> </div>[cut]>> Unfortunatelly, the Prototype''s getDimensions() method used by >> getWidth() checks only if the elems.style.display is none/null, which >> isn''t in this case - it''s inline. As the result, getDimensions returns >> zeros for both width and height.--~--~---------~--~----~------------~-------~--~----~ You received this message because you are subscribed to the Google Groups "Ruby on Rails: Spinoffs" group. To post to this group, send email to rubyonrails-spinoffs-/JYPxA39Uh5TLH3MbocFFw@public.gmane.org To unsubscribe from this group, send email to rubyonrails-spinoffs-unsubscribe-/JYPxA39Uh5TLH3MbocFFw@public.gmane.org For more options, visit this group at http://groups.google.com/group/rubyonrails-spinoffs?hl=en -~----------~----~----~----~------~----~------~--~---
Szymon Wilkołazki
2008-Feb-26 16:48 UTC
Re: Element.getDimensions() -- Element display not set, but ancestor''s display:none. Bug?
Hi, kangax wrote:> Szymon, > > There''s a patch in a trac [1] which might or might not make its way[...]> We are deciding on some performance issues at the moment, as this > could lead to undesired overhead. >Ok, I noticed performance issues with this patch. It happens in one of my pages where I call getDimensions in onScroll event. The element which dimensions I need to fetch is visible. I assumed that if the element has either width or height non-zero, then it is visible and we can safely return those values. If both width and height are zeros, then we can''t be sure if the element is visible but width and height set to zeros or if it or it''s ancestors are invisible, so we execute the code staaky provided in his patch [1]. Please correct me if this assumption is incorrect. I modified my copy of prototype.js (previously patched with [1], elementgetdimensions_displaynone_anc_reccollect_unit.diff) so it looks like this: getDimensions: function(element) { element = $(element); + var dimensions = { + width: element.clientWidth, + height: element.clientHeight + }; + if (dimensions.width == 0 && dimensions.height == 0) { var restore = element.ancestors(function(element) { return !element.visible() }), styles = []; restore.push(element); // All *Width and *Height properties give 0 on elements with // display none, // or when ancestors have display none, so enable those // temporarily restore.each(function(r) { styles.push({ display: r.getStyle(''display''), position: r.getStyle(''position''), visibility: r.getStyle(''visibility'') }); r.setStyle({display: ''block'', position: ''absolute'', visibility: ''visible''}); }); - var dimensions = { + dimensions = { width: element.clientWidth, height: element.clientHeight }; restore.each(function(r, index) { r.setStyle(styles[index]); }); + } return dimensions; }, Now the function works fast when it is possible and provides correct results for both hidden and shown elements. I will optimize my code, too. It should not execute getDimensions with every onscroll event.> [1] http://dev.rubyonrails.org/ticket/11142 >Regards, Szymon Wilkolazki --~--~---------~--~----~------------~-------~--~----~ You received this message because you are subscribed to the Google Groups "Ruby on Rails: Spinoffs" group. To post to this group, send email to rubyonrails-spinoffs-/JYPxA39Uh5TLH3MbocFFw@public.gmane.org To unsubscribe from this group, send email to rubyonrails-spinoffs-unsubscribe-/JYPxA39Uh5TLH3MbocFFw@public.gmane.org For more options, visit this group at http://groups.google.com/group/rubyonrails-spinoffs?hl=en -~----------~----~----~----~------~----~------~--~---
kangax
2008-Feb-26 19:39 UTC
Re: Element.getDimensions() -- Element display not set, but ancestor''s display:none. Bug?
Good point! It definitely makes sense to check if element is visible before diving into a somewhat heavy "ancestors enabling" routine. - kangax On Feb 26, 11:48 am, Szymon Wilkołazki <wilkola...-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org> wrote:> Hi, > > > > kangax wrote: > > Szymon, > > > There''s a patch in a trac [1] which might or might not make its way > [...] > > We are deciding on some performance issues at the moment, as this > > could lead to undesired overhead. > > Ok, I noticed performance issues with this patch. It happens in one of > my pages where I call getDimensions in onScroll event. The element > which dimensions I need to fetch is visible. > > I assumed that if the element has either width or height non-zero, > then it is visible and we can safely return those values. If both > width and height are zeros, then we can''t be sure if the element is > visible but width and height set to zeros or if it or it''s ancestors > are invisible, so we execute the code staaky provided in his patch [1]. > > Please correct me if this assumption is incorrect. > > I modified my copy of prototype.js (previously patched with [1], > elementgetdimensions_displaynone_anc_reccollect_unit.diff) > so it looks like this: > > getDimensions: function(element) { > element = $(element); > + var dimensions = { > + width: element.clientWidth, > + height: element.clientHeight > + }; > + if (dimensions.width == 0 && dimensions.height == 0) { > var restore = element.ancestors(function(element) { > return !element.visible() }), > styles = []; > restore.push(element); > > // All *Width and *Height properties give 0 on elements with > // display none, > // or when ancestors have display none, so enable those > // temporarily > restore.each(function(r) { > styles.push({ > display: r.getStyle(''display''), > position: r.getStyle(''position''), > visibility: r.getStyle(''visibility'') > }); > r.setStyle({display: ''block'', > position: ''absolute'', visibility: ''visible''}); > }); > > - var dimensions = { > + dimensions = { > width: element.clientWidth, > height: element.clientHeight > }; > restore.each(function(r, index) { > r.setStyle(styles[index]); > }); > + } > return dimensions; > }, > > Now the function works fast when it is possible and provides correct > results for both hidden and shown elements. > > I will optimize my code, too. It should not execute getDimensions with > every onscroll event. > > > [1]http://dev.rubyonrails.org/ticket/11142 > > Regards, > Szymon Wilkolazki--~--~---------~--~----~------------~-------~--~----~ You received this message because you are subscribed to the Google Groups "Ruby on Rails: Spinoffs" group. To post to this group, send email to rubyonrails-spinoffs-/JYPxA39Uh5TLH3MbocFFw@public.gmane.org To unsubscribe from this group, send email to rubyonrails-spinoffs-unsubscribe-/JYPxA39Uh5TLH3MbocFFw@public.gmane.org For more options, visit this group at http://groups.google.com/group/rubyonrails-spinoffs?hl=en -~----------~----~----~----~------~----~------~--~---
staaky
2008-Feb-26 21:59 UTC
Re: Element.getDimensions() -- Element display not set, but ancestor''s display:none. Bug?
Thanks Szymon, Good find, I''ve added a patch in http://dev.rubyonrails.org/ticket/11142 that uses your suggestion. On 26 feb, 17:48, Szymon Wilkołazki <wilkola...-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org> wrote:> Hi, > > > > kangax wrote: > > Szymon, > > > There''s a patch in a trac [1] which might or might not make its way > [...] > > We are deciding on some performance issues at the moment, as this > > could lead to undesired overhead. > > Ok, I noticed performance issues with this patch. It happens in one of > my pages where I call getDimensions in onScroll event. The element > which dimensions I need to fetch is visible. > > I assumed that if the element has either width or height non-zero, > then it is visible and we can safely return those values. If both > width and height are zeros, then we can''t be sure if the element is > visible but width and height set to zeros or if it or it''s ancestors > are invisible, so we execute the code staaky provided in his patch [1]. > > Please correct me if this assumption is incorrect. > > I modified my copy of prototype.js (previously patched with [1], > elementgetdimensions_displaynone_anc_reccollect_unit.diff) > so it looks like this: > > getDimensions: function(element) { > element = $(element); > + var dimensions = { > + width: element.clientWidth, > + height: element.clientHeight > + }; > + if (dimensions.width == 0 && dimensions.height == 0) { > var restore = element.ancestors(function(element) { > return !element.visible() }), > styles = []; > restore.push(element); > > // All *Width and *Height properties give 0 on elements with > // display none, > // or when ancestors have display none, so enable those > // temporarily > restore.each(function(r) { > styles.push({ > display: r.getStyle(''display''), > position: r.getStyle(''position''), > visibility: r.getStyle(''visibility'') > }); > r.setStyle({display: ''block'', > position: ''absolute'', visibility: ''visible''}); > }); > > - var dimensions = { > + dimensions = { > width: element.clientWidth, > height: element.clientHeight > }; > restore.each(function(r, index) { > r.setStyle(styles[index]); > }); > + } > return dimensions; > }, > > Now the function works fast when it is possible and provides correct > results for both hidden and shown elements. > > I will optimize my code, too. It should not execute getDimensions with > every onscroll event. > > > [1]http://dev.rubyonrails.org/ticket/11142 > > Regards, > Szymon Wilkolazki--~--~---------~--~----~------------~-------~--~----~ You received this message because you are subscribed to the Google Groups "Ruby on Rails: Spinoffs" group. To post to this group, send email to rubyonrails-spinoffs-/JYPxA39Uh5TLH3MbocFFw@public.gmane.org To unsubscribe from this group, send email to rubyonrails-spinoffs-unsubscribe-/JYPxA39Uh5TLH3MbocFFw@public.gmane.org For more options, visit this group at http://groups.google.com/group/rubyonrails-spinoffs?hl=en -~----------~----~----~----~------~----~------~--~---