473,395 Members | 1,418 Online
Bytes | Software Development & Data Engineering Community
Post Job

Home Posts Topics Members FAQ

Join Bytes to post your question to a community of 473,395 software developers and data experts.

Reliable getObjectPosition() function?

I've found that under some circumstances, some code that I've been using to
find an object's coordinates with respect to the viewport does not behave
correctly.

Is there a function that has been extensively tested under lots of different
page conditions that will return the x,y position of an object?

Things to consider:
1. Full browser support, as much as possible (meaning, works in any browser
where it's possible, not just the latest browsers implementing the latest
features. Ideally, use DOM and standards, but fall back to proprietary
properties if necessary)
2. Any containing element may be scrolled using overflow:auto (most
algorithms do not consider this)
3. absolute and relative positioning
4. css margins, paddings, etc
5. Different doctypes, and returning the correct values given no doctype,
loose, strict, etc

I've got my code working better now, under every condition I actually need
to support (it was failing because of being within a DIV with
overflow:auto). But I'd really like to have a more robust function, and
rather than do all the testing myself, I was hoping there was an accepted
standard function that was written and/or tested by several 'experts'. It
would certainly save me time ;)

Thanks,

--
Matt Kruse
Javascript Toolbox: http://www.JavascriptToolbox.com/
Jul 23 '05 #1
8 1410
On Fri, 18 Jun 2004 15:03:30 -0500, Matt Kruse <ne********@mattkruse.com> wrote:
I've found that under some circumstances, some code that I've been using to
find an object's coordinates with respect to the viewport does not behave
correctly.

Is there a function that has been extensively tested under lots of different
page conditions that will return the x,y position of an object?

Things to consider:
1. Full browser support, as much as possible (meaning, works in any browser
where it's possible, not just the latest browsers implementing the latest
features. Ideally, use DOM and standards, but fall back to proprietary
properties if necessary)
2. Any containing element may be scrolled using overflow:auto (most
algorithms do not consider this)
3. absolute and relative positioning
4. css margins, paddings, etc
5. Different doctypes, and returning the correct values given no doctype,
loose, strict, etc

I've got my code working better now, under every condition I actually need
to support (it was failing because of being within a DIV with
overflow:auto). But I'd really like to have a more robust function, and
rather than do all the testing myself, I was hoping there was an accepted
standard function that was written and/or tested by several 'experts'. It
would certainly save me time ;)

Thanks,

Here's something I've been experimenting with (not extensively):

function _xPageY(e) {
if (!(e=xGetElementById(e))) return Number.NaN;
var b, y = 0;
while (e) {
if (e.offsetTop) {
y += e.offsetTop;
}
e = e.offsetParent
if (e) {
b = xGetComputedStyle(e, 'border-top-width');
if (b) {
y += b;
}
if (e.scrollTop) {
y -= e.scrollTop;
}
}
}
return y;
}

* Given this html (with 4.01 strict doctype):

<div id='container'>
...text...
<div id='d1'>d1</div>
...text...
</div>

* Given this css:

body {
margin:0; padding:0;
}
#container {
overflow:auto;
position:absolute;
left:10px; top:100px;
width:200px; height:300px;
border:2px solid #000;
margin:0; padding:4px;
}
#d1 {
position:absolute;
margin:0; padding:0;
left:10px; top:10px;
}

* Preliminary testing on Win2K:

IE 6.0 - successful.

Mozilla 1.5 - successful when container has overflow != auto.

Mozilla 1.6 - unsuccesful.

Opera 7.x - unsuccesful, Opera still has bug #130324.

* Observation on Moz:

Moz seems to be giving d1.offsetTop as:

xGetComputedStyle('d1', 'top') - xGetComputedStyle('container', 'border-top-width')

So sometimes it is negative.
This was just a quick test. I'll experiment more when I get a chance.

Mike
Jul 23 '05 #2
Matt Kruse wrote:
I've found that under some circumstances, some code that I've been
using to find an object's coordinates with respect to the viewport
does not behave correctly.

Is there a function that has been extensively tested under lots of
different page conditions that will return the x,y position of an
object?
Yes many. But you are talking about one all singing and dancing fully
generalised element position reporting function and I don't think you
will find one. I also don't think using such a function would be a good
idea anyway.

You are asking for a function that, given an indefinitely nested
sequence of scrolling DIV elements, will be able to report the exact
pixel location of any element within the innermost no matter how any of
the containing DIVs are scrolled. The code needed to do that is bulky
even without some of the serious problems in some fairly common browsers
(e.g. Opera 7).

Having content (or some content) within a scrolling element is
realistic. Having a scrolling element within a scrolling element is a
possibility, but nesting 3 or more scrolling elements would be bad UI
design (IMO). Knowing the context of the script; that you have a
scrolling element to deal with and which element it was, allows all of
the issues to be side stepped in ways that are just not available to the
truly general method.

Recently I have written a number of element position retrieval
components. None of them suite all contexts, they are not designed to.
They offer a common interface to the position information and I write
the code that needs the information so that it uses that interface. Once
I know the context of the application I can choose one of the components
to work along side the script that needs the information, such that it
uses the algorithm best suited to the context.

The very simplest algorithm cannot cope with borders on elements,
scrolling or padding or margins on the body/html element. Other
component implementations can handle different permutations of
requirements, but none of them can cope with everything at once (and I
don't think that it can be done). That limitation doesn't matter to me
because no real context will ask for the simultaneous handling of every
permutation of factors that impact on position information.

It also means that any application is not downloading more code, or
performing more operations, than is required in its context. The truly
general function (if achievable) will not be able to boast this, by a
long way.
Things to consider:
1. Full browser support, as much as possible (meaning, works in any
browser where it's possible, not just the latest browsers
implementing the latest features. Ideally, use DOM and standards, but
fall back to proprietary properties if necessary)
2. Any containing element may be scrolled using overflow:auto (most
algorithms do not consider this)
3. absolute and relative positioning
And floats?
4. css margins, paddings, etc
Borders?
5. Different doctypes, and returning the correct values given no
doctype, loose, strict, etc


That is more a question of standards mode against quirks mode.

<snip>

Richard.
Jul 23 '05 #3
Richard Cornford wrote:
Yes many. But you are talking about one all singing and dancing fully
generalised element position reporting function and I don't think you
will find one.
And I haven't, yet, so I'm working on one. It's an interesting task :)
I also don't think using such a function would be a
good idea anyway.
Well, we've had this discussion before! heh

But, if you're writing some reusable code to position a calendar popup, for
example, it's not reusable unless it can cope with existing in a variety of
environments. Having a reusable component which must be re-coded each time
to handle the environment that it exists in isn't a good idea, IMO.
You are asking for a function that, given an indefinitely nested
sequence of scrolling DIV elements, will be able to report the exact
pixel location of any element within the innermost no matter how any
of the containing DIVs are scrolled.
Yes. It's not all _that_ complicated. You just walk up the chain, and check
to see if the current object is scrolled, and adjust. It's not a lot of
code, since it's just the general concepts applied in a loop.
but none of them can cope with everything at once (and I
don't think that it can be done).
Too difficult for you? :)
It also means that any application is not downloading more code, or
performing more operations, than is required in its context. The truly
general function (if achievable) will not be able to boast this, by a
long way.


I don't care. At least they'll be reliable, no matter where I choose to use
them.
3. absolute and relative positioning

And floats?


Should be computed correctly by the browser already, just as any normal
object is in the flow of a page.
4. css margins, paddings, etc

Borders?


If possible, sure why not? I know that borders and the box model stuff
varies between browsers, but hopefully that will be something that can be
overcome.
5. Different doctypes, and returning the correct values given no
doctype, loose, strict, etc

That is more a question of standards mode against quirks mode.


I know. And that relates directly to how the measurements must be made.

I'll post my working code when I get it pretty close to being acceptable.
I'm sure you and/or others can help me refine it to work in the most
situations possible. If coded, commented, and tested correctly, then it
should be able to be trimmed down by any developer who doesn't need to
support every page layout feature or every browser. Even as a purely
educational exercise, surely it's not a waste of time...

--
Matt Kruse
Javascript Toolbox: http://www.JavascriptToolbox.com/
Jul 23 '05 #4
Matt Kruse wrote:
Richard Cornford wrote: <snip> But, if you're writing some reusable code to position a calendar
popup, for example, it's not reusable unless it can cope with
existing in a variety of environments. Having a reusable component
which must be re-coded each time to handle the environment that it
exists in isn't a good idea, IMO.
You clearly didn't understand what I was describing. The positioning
information comes from a low-level component. That component can be
swapped for others that offer the same interface and implement
positioning algorithms to suite other contexts. The code that uses the
component is only interested in the interface and doesn't care which
component is providing it. So moving code that is interested in
positioning information is only a matter of deploying it alongside a
suitable version of the component. It does not need to be re-coded, and
any pre-existing version of the component doesn't need to be re-coded
(and a new context can be handled by writing a new component providing
the same interface, which itself becomes re-usable code).
You are asking for a function that, given an indefinitely nested
sequence of scrolling DIV elements, will be able to report the exact
pixel location of any element within the innermost no matter how any
of the containing DIVs are scrolled.


Yes. It's not all _that_ complicated. You just walk up the chain, and
check to see if the current object is scrolled, and adjust. It's not
a lot of code, since it's just the general concepts applied in a loop.


It is a general concept that requires at least 4 times the code that is
needed in the simplest (and most common) case, and it requires
considerably more operations in each iteration of the loop making it a
lot slower. Using a heavyweight positioning algorithm to handle the
simple and common HTML contexts seems wasteful, but is necessitated by
your generalised library approach.
but none of them can cope with everything at once (and I
don't think that it can be done).


Too difficult for you? :)


No, there is an apparent logical paradox in the general algorithm. It
can be avoided by not attempting to be truly general as all conditions
will not apply simultaneously in real situations. But the general code
cannot know which don't apply.
It also means that any application is not downloading more code, or
performing more operations, than is required in its context. The
truly general function (if achievable) will not be able to boast
this, by a long way.


I don't care. At least they'll be reliable, no matter where I choose
to use them.


While my approach is only reliable and efficient?

<snip> I'll post my working code when I get it pretty close to being
acceptable. I'm sure you and/or others can help me refine it to work
in the most situations possible. If coded, commented, and tested
correctly, then it should be able to be trimmed down by any developer
who doesn't need to support every page layout feature or every
browser. Even as a purely educational exercise, surely it's not a
waste of time...


There is no harm in trying, but to save effort in the long run you
should try to get Opera 7 and Konqueror/Safari into your test-set
browsers at the earliest opportunity as they manifest the most
problems/diversity.

Richard.
Jul 23 '05 #5
Richard Cornford wrote:
It is a general concept that requires at least 4 times the code that
is needed in the simplest (and most common) case, and it requires
considerably more operations in each iteration of the loop making it a
lot slower.
In reality, I doubt it. Once completed, I'll test and see. Code runs very
quickly, and I doubt there will be any perceivable difference.
I don't care. At least they'll be reliable, no matter where I choose
to use them.

While my approach is only reliable and efficient?


Your approach would not be reliable in unknown environments.
There is no harm in trying, but to save effort in the long run you
should try to get Opera 7 and Konqueror/Safari into your test-set
browsers at the earliest opportunity as they manifest the most
problems/diversity.


I have 8 versions of Opera on my machine that I test with, including 3
versions of Opera 7.x. I've got a Mac at work that I test with that has
Safari, and I try to test with it also, but oh, how I do hate the Mac :)

--
Matt Kruse
Javascript Toolbox: http://www.JavascriptToolbox.com/
Jul 23 '05 #6
Matt Kruse wrote:
Richard Cornford wrote:
It is a general concept that requires at least 4 times the code that
is needed in the simplest (and most common) case, and it requires
considerably more operations in each iteration of the loop making it
a lot slower.
In reality, I doubt it. Once completed, I'll test and see. Code runs
very quickly, and I doubt there will be any perceivable difference.


That has got to depend entirely on how much element position retrieval
is needed. For the position of one element once, the difference is
unlikely to be perceivable. But for a DHTML system that wants to
accommodate relative CSS units used for sizes and positions along with
the user's ability to re-scale fonts (at any moment they feel like it)
then the potential need for element position/size information is greatly
increased, and so the significance of the efficiency of the retrieval
method (especially if the DOM is deep).
I don't care. At least they'll be reliable, no matter where I choose
to use them.

While my approach is only reliable and efficient?


Your approach would not be reliable in unknown environments.


That is irrelevant, practical applications of browser scripts are not
used in unknown contexts.

<snip> ... . I've got a Mac at work that I test with that
has Safari, and I try to test with it also, but oh,
how I do hate the Mac :)


I don't like Macs either, they are very alien when you are used to other
systems. I tend to test Konqueror on Linux first and mostly what works
there will work on Safari and only need a quick check with a Mac to
ensure that it really does.

Richard.
Jul 23 '05 #7
Richard Cornford wrote:
In reality, I doubt it. Once completed, I'll test and see. Code runs
very quickly, and I doubt there will be any perceivable difference.

That has got to depend entirely on how much element position retrieval
is needed.


For my purposes, it's only to position an element once, usually be a form
input field.
For other applications, where the position needs to be calculated quickly
and often, it may not be the best solution.

However, an exhaustive solution which works in any environment is surely
beneficial even to someone wishing to trim down and speed up the algorithm,
because taking chunks out is a whole lot easier than adding in everything
required!

Finding a full solution "solves the problem". Once the full solution is
known, it's up to the developer to decide if they need the whole solution,
or just part of it.
Your approach would not be reliable in unknown environments.

That is irrelevant, practical applications of browser scripts are not
used in unknown contexts.


Well, that's purely argumentative, because you know what I'm trying to
accomplish, and you simply disagree with the goal!

Furthermore, it _is_ relevant. This whole topic was brought up by a
situation where a web-based application went through a redesign. Instead of
long scrolling pages, the layout was changed to have a scrolling "content"
window. Positioning of calendar popups and other widgets broke, because the
positioning code wasn't able to adapt to overflow:auto in DIV elements. Had
the code been more robust in this area, no re-coding would have been
necessary. The application and UI developers would be free to redesign the
layout as they wish, without worrying if components would then 'break'. For
them to bring in the author of the positioning code every time they change
layouts would be impractical. Especially in an environment where users can
select their "skins" for the app, and have completely different layouts of
the application. Does each skin require different code? That's completely
impractical. A single exhaustive solution which can be used in all contexts
is a superior approach.

--
Matt Kruse
Javascript Toolbox: http://www.JavascriptToolbox.com/
Jul 23 '05 #8
Matt Kruse wrote:
Richard Cornford wrote: <snip> However, an exhaustive solution which works in any environment is
surely beneficial even to someone wishing to trim down and speed up
the algorithm, because taking chunks out is a whole lot easier than
adding in everything required!
If a totally general element position reporting function could be
created then it would be useful, as it would effectively describe the
whole problem. And, once understood, would allow aspects of the
algorithm to be omitted from implementations where they were not
significant.
Finding a full solution "solves the problem". Once the full solution
is known, it's up to the developer to decide if they need the whole
solution, or just part of it.
However, on the one hand you are proposing creating code so that it is
easy to use for people with a negligible knowledge of browser scripting
and then proposing that they comprehend and optimise complex functions
for the context in which they use them.
Your approach would not be reliable in unknown environments.

That is irrelevant, practical applications of browser scripts are not
used in unknown contexts.


Well, that's purely argumentative,


You started it :)
because you know what I'm trying to
accomplish, and you simply disagree with the goal!
It remains the case that unreliability that follows from your design
goal is not relevant to scripts that do not share that goal, and are not
unreliable in the context of their application.
Furthermore, it _is_ relevant. This whole topic was brought up by a
situation where a web-based application went through a redesign.
Instead of long scrolling pages, the layout was changed to have a
scrolling "content" window. Positioning of calendar popups and other
widgets broke, because the positioning code wasn't able to adapt to
overflow:auto in DIV elements. Had the code been more robust in this
area, no re-coding would have been necessary. The application and UI
developers would be free to redesign the layout as they wish, without
worrying if components would then 'break'.
If someone plans to re-design a web site/application they should be
anticipating that scripts will break (and consider themselves luck if
they don't). Consider all of the possible re-design outcomes. The vast
majority would not have necessitated any changes in your script. Another
group of possibilities would have broken it in a different way. While
one small sub-set of re-design options introduce the scrolling problem
that your script could not handle. And for this you propose creating a
bulky and relatively slow generalised element position reporting
function and inflicting it on all of the users all of the time, so that
in the event of a re-design, and that re-design being such that it would
impact on a specific position reporting function, whoever is doing the
re-design can avoid having to arrange slight modifications to an
existing script.
For them to bring in the author of the positioning code
every time they change layouts would be impractical.
It wouldn't necessarily have to be the author of the original. They
could, for example, ask the individual who has been considering
optimising the general element retrieval function to do the job. Though
going back to the original author would probably prove least trouble. In
the case of my component design replacing the component in use with a
pre-existing alternative better suited to the new contest wouldn't be
complex of time consuming.
Especially in an environment where users can select
their "skins" for the app, and have completely different layouts of
the application. Does each skin require different code? That's
completely impractical.
Now there you have a specific context that would warrant a more
general/flexible positioning algorithm, but not necessarily a truly
general one as control could still exist over the scope of the applied
"skins". When I have worked on user skinable Intranet applications the
user's choice of skins was extensive but the skins themselves offered
variations in presentation style and colors but almost no variation in
page layout.
A single exhaustive solution which can be
used in all contexts is a superior approach.


I will still maintain that applying totally generalised code in all
situations is inappropriate and wasteful. However, until you have a
working implementation of the truly general element position reporting
function the superiority of its hypothetical application is pure
speculation.

Richard.
Jul 23 '05 #9

This thread has been closed and replies have been disabled. Please start a new discussion.

Similar topics

1
by: maxim vexler | last post by:
in a book i am ready now : O'Reilly - Web Database Application with PHP and MySQL, 2nd ed. by David Lane, Hugh E. Williams on chapter 9 the author give an example for age validation :...
8
by: Oliver | last post by:
Hi, I often have hits on my homepage with referrer strings that do not link to my page. Where does this come from? Does it mean that the visitor has been on the refferer before going to my site?...
0
by: relisoft | last post by:
Seattle, WA -- Seattle-based Reliable Software® announces the release their Windows Library into the public domain. Reliable Software Windows Library, RSWL, is the foundation for their compact,...
2
by: D. Alvarado | last post by:
Hello, Can anyone recommend a good Javascript cross-browser string replace method? On both PC Mozilla Firefox and IE 6, I tried this var str = requiredField.replace("_", " "); where...
11
by: OlafMeding | last post by:
Because of multithreading semantics, this is not reliable. This sentence is found in the Python documentation for "7.8.1 Queue Objects". This scares me! Why would Queue.qsize(), Queue.empty(...
4
by: John Grant | last post by:
If I build a web services today with VS 2005 does it support reliable messaging? If I use WSE 3.0 will it support reliable messaging? If I don’t have reliable messaging can I make a web method...
1
by: relisoft | last post by:
SEATTLE, Washington. - July 12, 2006: Reliable Software® announces the upcoming release of Code Co-op® version 5.0. Code Co-op is an affordable peer-to-peer version control system for distributed...
1
by: =?Utf-8?B?S2F1c2hhbCBNZWh0YQ==?= | last post by:
Hi, I am facing the ServerTooBusyException when using reliable session and net.tcp binding. I have single server and single client application. The client registers for the event at the...
3
by: Cyprus106 | last post by:
I can't seem to get a reliable function that grabs the actual date 30 days in the future. Adding +30 to the date() function doesn't seem to compensate for if the next month has less than the +30...
0
by: ryjfgjl | last post by:
In our work, we often receive Excel tables with data in the same format. If we want to analyze these data, it can be difficult to analyze them because the data is spread across multiple Excel files...
0
by: emmanuelkatto | last post by:
Hi All, I am Emmanuel katto from Uganda. I want to ask what challenges you've faced while migrating a website to cloud. Please let me know. Thanks! Emmanuel
0
BarryA
by: BarryA | last post by:
What are the essential steps and strategies outlined in the Data Structures and Algorithms (DSA) roadmap for aspiring data scientists? How can individuals effectively utilize this roadmap to progress...
1
by: nemocccc | last post by:
hello, everyone, I want to develop a software for my android phone for daily needs, any suggestions?
0
by: Hystou | last post by:
There are some requirements for setting up RAID: 1. The motherboard and BIOS support RAID configuration. 2. The motherboard has 2 or more available SATA protocol SSD/HDD slots (including MSATA, M.2...
0
marktang
by: marktang | last post by:
ONU (Optical Network Unit) is one of the key components for providing high-speed Internet services. Its primary function is to act as an endpoint device located at the user's premises. However,...
0
by: Hystou | last post by:
Most computers default to English, but sometimes we require a different language, especially when relocating. Forgot to request a specific language before your computer shipped? No problem! You can...
0
Oralloy
by: Oralloy | last post by:
Hello folks, I am unable to find appropriate documentation on the type promotion of bit-fields when using the generalised comparison operator "<=>". The problem is that using the GNU compilers,...
0
jinu1996
by: jinu1996 | last post by:
In today's digital age, having a compelling online presence is paramount for businesses aiming to thrive in a competitive landscape. At the heart of this digital strategy lies an intricately woven...

By using Bytes.com and it's services, you agree to our Privacy Policy and Terms of Use.

To disable or enable advertisements and analytics tracking please visit the manage ads & tracking page.