-
13 Feb 2008 9:40 AM #1
[2.0.1] IE offsetParent / getBoundingClientRect after DOM replace issue
[2.0.1] IE offsetParent / getBoundingClientRect after DOM replace issue
Hello. This is an IE-only issue related to ext-base for 2.0.1. I have fixed this locally by hacking ext-base to catch the exception.
Related forum threads:
http://extjs.com/forum/showthread.php?t=24481
http://extjs.com/forum/showthread.php?t=9769
http://extjs.com/forum/showthread.php?t=8853
I discovered this while developing a Ext.ux.Portal application that allows the dynamic addition of new Portlet Panels. The crux of the problem is (again, this is IE-only):
- I have a draggable Ext Panel in the page (an Ext.ux.Portlet).
- I replace a parent of the panel via Ajax and re-render the Portal (this happens when adding a new Portlet to the Portal).
- I mousedown on the Ext Panel to drag and an "Unspecified Error" is thrown which points to ext-base:
line 97 (ext 2.0.1): b = el.getBoundingClientRect(); - The cause of this is that IE cannot successfully call getBoundingClientRect (an IE-only method) or offsetParent if a parent element has been replaced in the DOM. Read more about this here:
http://weblogs.asp.net/rajbk/archive...avascript.aspx - If I surround this with a try/catch and return [0,0], everything's fine:
Code:// this is from the minified version try{ M=G.getBoundingClientRect(); N=C(document).getScroll(); return[M.left+N.left,M.top+N.top]; }catch(ex){ return [0,0]; }}
I have tried catching (literally) every reference to getXY in ext-all, hoping I could find something to override, but I think the call to getXY that's throwing the exception is possibly internal to ext-base. I can't really tell what's going on in IE without the Firebug debugger.
Also, I think y'all are handling a similar situation in DragDropMgr's getLocation method (line 8686 of ext-all-debug.js). There's a call to getXY() there, surrounded by a try/catch. When I try to drag my replaced panel, that exception is thrown multiple times because of the call to getBoundingBoxRect. Except there you catch and ignore it...
Thanks for any input!
LB
PS: Someone will likely suggest that I just do portal.items.add(new Portlet) + doLayout(), rather than re-rendering the whole thing, but that's not possible in our particular situation. The Portal is held inside a Tab that's managed by Wicket, not Ext. When the tab changes, all its child markup is lost purposely -- we can't keep all the markup in all tabs present in the DOM at the same time.Last edited by Lester Burlap; 13 Feb 2008 at 9:46 AM. Reason: added ext-all-debug line number
-
13 Feb 2008 11:37 AM #2
This error is the result of calling getXY on an element that is no longer part of the DOM. That generally means when you overwrote the HTML (generally a bad idea with Components) you still have event handlers attached that are firing and causing the error to occur.
Changing the parentNode of an element is fine - the problem is when somewhere up the chain the is a node that is an orphan.
-
21 Feb 2008 2:06 AM #3
@LB,I think my situation is the same to yours.There is a method named "gotoPage" in "main.js",I create new sub-Tab in this method when page have been changed. The portal is held inside the tab.It worked well first time,but occured error when reload the portal page into the tab at this line "M=G.getBoundingClientRect();".
I solved this problem with your code like the following: (I'm sorry to my poor english.^_^)
PHP Code:(function(){
var libFlyweight;
function fly(el) {
if (!libFlyweight) {
libFlyweight = new Ext.Element.Flyweight();
}
libFlyweight.dom = el;
return libFlyweight;
}
Ext.lib.Dom.getXY = function(el) {
var p, pe, b, scroll, bd = (document.body || document.documentElement);
el = Ext.getDom(el);
if(el == bd){
return [0, 0];
}
if (el.getBoundingClientRect) {
try{ // LB's code
b = el.getBoundingClientRect();
}catch(ex){
return [0,0];
}
scroll = fly(document).getScroll();
return [b.left + scroll.left, b.top + scroll.top];
}
var x = 0, y = 0;
p = el;
var hasAbsolute = fly(el).getStyle("position") == "absolute";
while (p) {
x += p.offsetLeft;
y += p.offsetTop;
if (!hasAbsolute && fly(p).getStyle("position") == "absolute") {
hasAbsolute = true;
}
if (Ext.isGecko) {
pe = fly(p);
var bt = parseInt(pe.getStyle("borderTopWidth"), 10) || 0;
var bl = parseInt(pe.getStyle("borderLeftWidth"), 10) || 0;
x += bl;
y += bt;
if (p != el && pe.getStyle('overflow') != 'visible') {
x += bl;
y += bt;
}
}
p = p.offsetParent;
}
if (Ext.isSafari && hasAbsolute) {
x -= bd.offsetLeft;
y -= bd.offsetTop;
}
if (Ext.isGecko && !hasAbsolute) {
var dbd = fly(bd);
x += parseInt(dbd.getStyle("borderLeftWidth"), 10) || 0;
y += parseInt(dbd.getStyle("borderTopWidth"), 10) || 0;
}
p = el.parentNode;
while (p && p != bd) {
if (!Ext.isOpera || (p.tagName != 'TR' && fly(p).getStyle("display") != "inline")) {
x -= p.scrollLeft;
y -= p.scrollTop;
}
p = p.parentNode;
}
return [x, y];
}
})();
-
21 Feb 2008 2:38 AM #4
@bluethinking, you might want to state what that block of code is for?

Sencha Docs / Ext 3.x - ( Docs | Examples )
Learning Center / Saki's Examples (for 2.x) / HOWTO - ( Report Bugs | Post Proper Code )
-
21 Feb 2008 5:29 PM #5
-
29 Feb 2008 8:47 AM #6
same error, different case
same error, different case
I recreated this error when I coded an editor grid with two columns, Date and Time, which consist of editable DateField and TimeField fields, respectively.
Everything worked fine until I edit a cell in the Date column and then click on a cell in the Time column. I then applied Lester's fix to the ext-base.js file, and that did the trick.
Thanks, Lester!
Someone on the Ext team might want to incorporate this into the codebase.
Jason
-
11 Mar 2008 11:37 AM #7
I've been running our app now for about a month with that hack to ext-base and haven't seen any adverse side effects... glad to see it helped some others (my 48 hours of IE-based debugging hell)!
LBB
-
1 Oct 2008 7:48 AM #8
Thanks for the hack
Thanks for the hack
it's working for me, no time to debug any more, it was just what I needed for now.
-
4 Nov 2008 10:16 AM #9
Fixed IE spotlight problem
Fixed IE spotlight problem
I had to use this hack to get, my implantation of extjs spotlight working on ie thanks!
-
27 Jan 2009 3:33 PM #10
Same problem here
Same problem here
I was having the same problem and Lester's code worked for me as well.
This may not be a true bug in Ext-JS (per Mr. Slocum's comments), but it isn't obvious to me what is causing the issue and I wonder if the solution shouldn't be added to the code base.


Reply With Quote
