From: moha297 on


I want to get the top and left values for a div on the screen.

I have been using the code to calculate the top and left values.

var total1 = 0;
var total2 = 0;
while(element){
total1+=element.offsetTop;
total2+=element.offsetLeft;
try{
element=element.offsetParent;
}catch(E){
break;
}
}

For the same DOM TREE this code is giving a performance reading of
30msec in IE8 and 80 to 200msec in IE6. I want to gain a considerable
performance improvement in IE6.

I am open to all ideas.

By the way I also tried

var total1 = 0;
var total2 = 0;
do{
total1+=element.offsetTop;
total2+=element.offsetLeft;
}while(element=element.offsetParent);

after reading a blog entry or two. The performace is similar.

I found that the bulk of the time is always spent in getting property
value rather than parsing the DOM TREE which less constantly from my
logs.(I might be wrong)

Also the code I have put here is on the fly....might have made
mistakes.

Am looking at performance gain. The floor is open to try anything only
constraint is just javascript, jquery, prototype etc are not an
option.

Thanks in advance!! :)
From: Peter Michaux on
On Dec 28, 11:32 am, moha297 <moha...(a)gmail.com> wrote:
>
> I want to get the top and left values for a div on the screen.

physical screen or upper-left corner of the page (which may be out of
view if the page is scrolled.)?

As Richard Cornford has mentioned here many times, this problem is not
solved in general. If your div has parents that scroll, have table
elements, is a button, etc, then the calculation of the div's upper-
left corner relative to the upper-left corner of the page is complex.


> I have been using the code to calculate the top and left values.
>
> var total1 = 0;
> var total2 = 0;
> while(element){
> total1+=element.offsetTop;
> total2+=element.offsetLeft;
> try{
> element=element.offsetParent;
>
> }catch(E){
> break;
> }
> }

You should not need a try-catch block to calculate the position. Using
feature detection once when this code first runs, or when the page
first loads, should be enough to know how to calculate the offset in
that browser for the remainder of the life of the page.

Also, perhaps someone else can comment on the possible slowness of the
try-catch. I rarely use them.


> For the same DOM TREE this code is giving a performance reading of
> 30msec in IE8 and 80 to 200msec in IE6. I want to gain a considerable
> performance improvement in IE6.

Why is 80 ms considered a performance problem?


> I am open to all ideas.
>
> By the way I also tried
>
> var total1 = 0;
> var total2 = 0;
> do{
> total1+=element.offsetTop;
> total2+=element.offsetLeft;
>
> }while(element=element.offsetParent);
>
> after reading a blog entry or two. The performace is similar.
>
> I found that the bulk of the time is always spent in getting property
> value rather than parsing the DOM TREE which less constantly from my
> logs.(I might be wrong)

"parsing the DOM TREE"? That is done when the page loads, not when
your calculation is occurring.


> Also the code I have put here is on the fly....might have made
> mistakes.

The better the code you post, the more valuable the responses will be.

Peter
From: Thomas 'PointedEars' Lahn on
moha297 wrote:

> I want to get the top and left values for a div on the screen.
>
> I have been using the code to calculate the top and left values.
>
> var total1 = 0;
> var total2 = 0;
> while(element){
> total1+=element.offsetTop;
> total2+=element.offsetLeft;
> try{
> element=element.offsetParent;
> }catch(E){

Should be `e' as it does not refer to a constructor.

> break;
> }
> }
>
> For the same DOM TREE this code is giving a performance reading of
> 30msec in IE8 and 80 to 200msec in IE6.

That is unsurprising since that try...catch statement does not do anything
useful here as the assignment is not going to fail:

If `element' does not refer to an object, the `while (element)' statement
prevents execution from ever reaching the problematic assignment.

If `element' does refer to an object, and that object does not have an
`offsetParent' property or its `offsetParent' property value is `undefined'
or `null', `element' will be assigned either `undefined' or `null'. Since
that converts to `false', the next iteration is not going to happen and the
case that one would attempt to access the `offsetParent' property of
`undefined' or `null'.

> I want to gain a considerable
> performance improvement in IE6.
>
> I am open to all ideas.

In most cases you do not need to determine the absolute position of an
element in the first place. For example, if you want to move an element by
10 px towards the right margin and by 20 px towards the bottom margin, you
simply increase its current `left' and `top' px-measured style property
values by those distances (while keeping the unit). If you have not set
those properties before, use the element's computed style.

However, if you insist, read this article, among others about this oft-
discussed problem in this newsgroup:

<https://developer.mozilla.org/en/Determining_the_dimensions_of_elements>

> By the way I also tried
>
> var total1 = 0;
> var total2 = 0;
> do{
> total1+=element.offsetTop;
> total2+=element.offsetLeft;
> }while(element=element.offsetParent);
>
> after reading a blog entry or two.

Do not believe into anything written.

> The performace is similar.

It should be more efficient. Are you sure your benchmark is sound?

> I found that the bulk of the time is always spent in getting property
> value rather than parsing the DOM TREE which less constantly from my
> logs.(I might be wrong)

You are. You do not know what "(to) parse" means to begin with.

> Also the code I have put here is on the fly....might have made
> mistakes.

It is hardly readable in the first place.

> Am looking at performance gain. The floor is open to try anything only
> constraint is just javascript, jquery, prototype etc are not an
> option.

jQuery and Prototype are written in "javascript", though. But you are
correct avoiding them because of their bad code quality.


PointedEars
--
realism: HTML 4.01 Strict
evangelism: XHTML 1.0 Strict
madness: XHTML 1.1 as application/xhtml+xml
-- Bjoern Hoehrmann
From: GTalbot on
On 28 déc, 12:32, moha297 <moha...(a)gmail.com> wrote:
> I want to get the top and left values for a div on the screen.
>

As Peter Michaux replied to you, your description of the problem for
which you require assistance is not accurate, too general. An URL
would have helped. And maybe, just maybe, you may be wrongly using
offsetLeft and offsetTop to get the left and top values of a div on
the screen. We can't be sure of this without a real webpage, URL.

> I have been using the code to calculate the top and left values.
>
> var total1 = 0;
> var total2 = 0;
> while(element){
> total1+=element.offsetTop;
> total2+=element.offsetLeft;
> try{
> element=element.offsetParent;
>
> }catch(E){
> break;
> }
> }

First, the while statement does not make sense.

You want an element (which is going to execute the controlled block)
that has offsetTop and offsetLeft values to do the controlled block.
Therefore, your while statement should be

while (element.offsetParent) {..controlled block..}
meaning as long as the current element being examined has an non-null
offsetParent...

Second, using a try.. catch does not perfection make sense from a
debugging perspective and from a property detection support. Let's say
the assignment fails because the current element being examined in
that while block does not have an offsetParent: why should it
generates an exception or an error object? Anyway, try.. catch is for
managing exceptions, for debugging purposes. At least, this is what I
would want to do when choosing to add a try...catch. And here, you do
not even try to identify the error message, error line, type of error,
etc.. So why resort to a try..catch block anyway?

Third, your local variable identifiers (total1, total2) are not
recommendable. You should always try to choose identifiers for
variables that are meaningful, intuitive, that helps debugging, code
maintenance, examining in debugging tools, that helps review by others
who may not be accustomed to your internal function logic (or help
review by yourself years later). This helps everyone and can make a
huge difference when the code is very long, complex, with many
intricated functions.

Here's how I did the same function 7 years ago:


var Element = evt.target ;
var CalculatedTotalOffsetLeft = CalculatedTotalOffsetTop = 0 ; while
(Element.offsetParent)
{
CalculatedTotalOffsetLeft += Element.offsetLeft ;
CalculatedTotalOffsetTop += Element.offsetTop ;
Element = Element.offsetParent ;
} ;

OffsetXForNS6 = evt.pageX - CalculatedTotalOffsetLeft ;
OffsetYForNS6 = evt.pageY - CalculatedTotalOffsetTop ;



http://www.gtalbot.org/DHTMLSection/WindowEventsNS6.html#screenLeft#NoteOffsetXY

http://www.gtalbot.org/DHTMLSection/WindowEventsIE6.html#screenLeft#NoteOffsetXY

> For the same DOM TREE this code is giving a performance reading of
> 30msec in IE8 and 80 to 200msec in IE6. I want to gain a considerable
> performance improvement in IE6.


IE6 <sigh .. Why do you need to support IE6?>. Imagine that people
are less and less using that browser and that IE8 implemented an
improved offsetParent, offsetLeft and offsetTop model.

With those numbers, don't you want to tell your IE6 users to upgrade
or to switch? It would solve many many problems...

"30msec in IE8 and 80 to 200msec" does not mean much if we do not know
on which machine (CPU, RAM, video card, etc) these results are
gathered from. 30msec is very long for a super-computer and 200msec is
very fast on a Pentium 1 90Mhz.

If nodeA is an area HTML element which has a map HTML element
somewhere in the ancestor chain, then nodeA.offsetParent returns the
nearest ancestor map HTML element... but that is not the case in IE 7;
IE8 corrected this.

http://www.gtalbot.org/BrowserBugsSection/MSIE8Bugs/CSSOM-offsetParent-prop..html#FourthTest

If an element has no offsetParent, then its offsetLeft value must be 0
and its offsetTop value must be 0 ... but that is not the case in IE6.

http://www.gtalbot.org/BrowserBugsSection/MSIE6Bugs/OffsetValues.html

> I am open to all ideas.


Post an URL. Make sure your webpage is using valid markup code
(including a doctype declaration, preferably declaring a strict DTD),
uses valid CSS code.

http://validator.w3.org/
http://jigsaw.w3.org/css-validator/

Also, read the comp.lang.javascript FAQ on posting code:

http://www.jibbering.com/faq/#posting

> By the way I also tried
>
>     var total1 = 0;
>     var total2 = 0;
> do{
>   total1+=element.offsetTop;
>     total2+=element.offsetLeft;
>
> }while(element=element.offsetParent);


An assignment in a while clause is not recommendable, at least,
definitely not my recommendation. Some assignment may succeed and
return 0 (and be resolved as false while the assignment is successful
and correct).

Same thing with assignment in a if clause:
if(a = b)
may succeed but the value may be resolved as false because b == 0.

Some other regular posters may help me here on this precise issue.

> after reading a blog entry or two. The performace is similar.

Why is performance important to you, with regards to offsetTop and
offsetLeft and with regards to IE 6?
Please elaborate.

(There is such a thing has having an overexcessive number of
positioned containers (like nested tables)... in a very bloated
webpage)

> I found that the bulk of the time is always spent in getting property
> value rather than parsing the DOM TREE which less constantly from my
> logs.(I might be wrong)

Post an URL according to the constraints I gave you.

And if you are open to all ideas, then add a IE6nomore or IE6RIP
button in your webpage so that people get the message that IE6 is
buggy, not recommendable, etc. should upgrade or switch.


> Also the code I have put here is on the fly....might have made
> mistakes.

Well, whose fault is it then? Are you asking to get code answers on
the fly as well... with possible mistakes too?

"
The better the code you post, the more valuable the responses will
be.
"
Thank you Peter Michaud for speaking up my mind. :)

Gérard
From: GTalbot on
On 28 déc, 12:32, moha297 <moha...(a)gmail.com> wrote:

> For the same DOM TREE this code is giving a performance reading of
> 30msec in IE8 and 80 to 200msec in IE6. I want to gain a considerable
> performance improvement in IE6.

Those "30msec in IE8 and 80 to 200msec in IE6" numbers are entirely
dependent and relative to the depth of the DOM tree of the tested
webpage and to the CPU+RAM of the tested machines. The best possible
(short term and long term) proactive solution for anyone/everyone
involved is still to always use updated web-capable softwares and not
to use very buggy, unreliable, non-trustworthy software like IE6.



> I am open to all ideas.
>
> By the way I also tried
>
>     var total1 = 0;
>     var total2 = 0;
> do{
>   total1+=element.offsetTop;
>     total2+=element.offsetLeft;
>
> }while(element=element.offsetParent);

Making an assignment in a while statement is not recommendable;
definitely not my recommendation. The while statement should be a
condition, an expression resulting into a boolean condition (and only
that). The while statement should not be an assignment: you want to
avoid side effects here.

Correct and coherent is:

do
{
total1+=element.offsetTop;
total2+=element.offsetLeft;
element = element.offsetParent;
/* moves upward in the offsetParent containment hierarchy: this
assignment must succeed because the while statement must have been
true */
}
while(element.offsetParent);
/* first test if the current element being actually examined has an
offsetParent before entering the controlled block */

Gérard