Jump to content

How to evaluate the absolute pixel coordinates of an item in an HTML page?


Recommended Posts

Here is what I've found out so far:

Let's imagine that:

- you've created an IE object

- you work with the one and only form inside the page you browse

- you are getting ready to iterate on all the objects in that form

$oIE = _IECreate(...)
 
 
$oForm = _IEFormGetObjByName($oIE, "theForm")
$oObjects = _IEFormElementGetCollection($oForm)
 
For $oObject In $oObjects
 
        if $oObject.id = "the_id_Im_looking_for" Then
                ...
        EndIf
Next

- you want to know the pixel position of one of the $oObject

...How do you do that? Here is what I've found:

1. One CANNOT necessarily use property "$oObject.style.pixelTop"

Apparently that property is available only when the creator of the page has applied a style to the page -- for example using CSS.

However, if "pixelTop" (i.e. "top") was never set, then$oObject.style.pixelTop will have the value 0 even though the object can be anywhere in the page (for example because there are other objects displayed before it)

2. Simple-yet-imperfect solution: Add up all "offsetParent"

Here is a function that calculates the vertical position in pixels using the sum of all offsetParent

Func sumOffsetParent($oObject)
    $safetyLimit = 1000
    
    $total = 0
    $tempObj = $oObject
    $loop = 0 ;safety
    while IsObj($tempObj) and $loop < $safetyLimit
        $total = $total + $tempObj.offsetTop
        $tempObj = $tempObj.offsetParent
        $loop = $loop+1 ;safety
    WEnd
    
    if $loop >= $safetyLimit then return -1 ; an error occurred: The document seems to have over 1000 parents
    
    return $total
EndFunc

IMPORTANT NOTES:

- This function is rather universal (Firefox, IE, Opera, etc.)

...BUT...

- It doesn't take your browser's zoom in account

- This function has been flagged as BAD PRACTICE by Microsoft. The reason is that it doesn't take the upper margin of the document in account AND it doesn't take the potential rotation of the object in account (yes, in later browsers, an object can be rotated!)

This bad practice warning is detailed here : http://msdn.microsoft.com/en-us/library/ms530302%28v=VS.85%29.aspx

Read it, it's extremely interesting

Instead, they recommend to use the following sum: getBoundingClientRect().top + window.pageYOffset . See the next section.

3. Good practice for IE9+ getBoundingClientRect().top + window.pageYOffset

Here is a little function :

Func GetObjectPos_Y($oIE, $oObject)
     return ($oObject.getBoundingClientRect().Top + $oIE.document.window.pageYOffset)
EndFunc

According to Microsoft it's the best practice for latest standards.

- pageYOffset is available only from IE9

- getBoundingClientRect().Top doesn't return the same value depending on the IE version.

In other words, be careful before you use this.

4. Don't forget your browser's zoom!!!

Here is a function I stole from another thread on this forum :

Func GetIEZoom($oIE, $dimension= "y")
    $oScreen = $oIE.document.parentWindow.screen
    $iXDPI = $oScreen.deviceXDPI
    $iYDPI = $oScreen.deviceYDPI
    $iLogicalXDPI = $oScreen.logicalXDPI
    $iLogicalYDPI = $oScreen.logicalYDPI
    $iXZoom = $iXDPI / $iLogicalXDPI * 100
    $iYZoom = $iYDPI / $iLogicalYDPI * 100
 
    LogMsg("$iXDPI = " & $iXDPI & "; $iYDPI = " & $iYDPI)
    LogMsg("$iLogicalXDPI = " & $iLogicalXDPI & "; $iLogicalYDPI = " & $iLogicalYDPI)
    LogMsg("Horizontal Zoom = %" & $iXZoom & "; Vertical Zoom = %" & $iYZoom)   
    
    if       $dimension = "x" then  return $iXZoom
    If      $dimension = "y" then   return $iYZoom
    ; else
    MyMsgBox(0, "Error", "Internal Error")
    LogMsg("GetIEZoom: bad paremeter: '" & $dimension & "'")
    return -1
 
    
EndFunc

You can call either GetIEZoom($oIE, "x") or GetIEZoom($oIE, "y").

A value like "100" means the regular zoom. "25" means a 25% zoom.

5. Final versions :

so now you know that you can either use :

sumOffsetParent($oObject)*GetIEZoom($oIE, "y") / 100

...or...

GetObjectPos_Y($oIE, $oObject)*GetIEZoom($oIE, "y") / 100

It will give you a decimal value. You need to round it to the nearest pixel.

6. What about the size of the browser's title bar/menu/etc.?

Sometimes you don't only want to know the position of stuff inside the HTML page but you want to know the absolute position of some stuff relatively to the upper-left pixel of the browser window (including the titel bar, the menu, etc.)

I won't detail the solution here, but you can get clues from the GetIEZoom function : $oScreen = $oIE.document.parentwindow.screen lets you get the dimensions of the window AROUND the HTML document (namely: the browser window).

EDIT: JohnOne suggests function ControlGetPos()

Edited by MonsieurOUXX
Link to comment
Share on other sites

"$oScreen = $oIE.document.parentwindow.screen lets you get the dimensions of the window AROUND the HTML document (namely: the browser window)"

As does ControlGetPos()

EDIT:

If you can obtain theses dimensions/co-ordinates of a firefox 4 + control, I'll take my hat off to you.

Edited by JohnOne

AutoIt Absolute Beginners    Require a serial    Pause Script    Video Tutorials by Morthawt   ipify 

Monkey's are, like, natures humans.

Link to comment
Share on other sites

EDIT:

If you can obtain theses dimensions/co-ordinates of a firefox 4 + control, I'll take my hat off to you.

I thought that was a fun challenge and a good way to get to know the FF UDF. I didn't get there all the way but close enough to satisfy my curiosity.

The script is in another topic with the IE version.

Edited by Robjong
Link to comment
Share on other sites

  • 7 years later...
#include <Ie.au3>

;~ Set SciTEWindow Minimize
WinSetState("Class:SciTEWindow","",@SW_MINIMIZE)

;~ Open IE
$oIE = _IECreate("www.google.com")
_IELoadWait($oIE,1,30000)

;~ Set Window IE >Google> Maximize
WinSetState("Google","",@SW_MAXIMIZE)

;~ Get Object IE > inputs
$oInput = _IETagNameGetCollection($oIE,"input")

;~ Get position IE Control\
$Position = ControlGetPos("Google","","Internet Explorer_Server1")

;~ Get Value position element jscript
$bottom = $oInput(2).getBoundingClientRect().bottom
$height = $oInput(2).getBoundingClientRect().height
$left = $oInput(2).getBoundingClientRect().left
$right = $oInput(2).getBoundingClientRect().right
$top = $oInput(2).getBoundingClientRect().top
$width = $oInput(2).getBoundingClientRect().width

;~ Calcule Position
$x = $left + ($width/2) + $Position[0]
$y = $top + ($height/2) + $Position[1]

;~ Activate Window IE for Click
WinActivate("Google","")

;~ Click positon Calculate
MouseClick("",$x,$y,1,Null)

 

Link to comment
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now
 Share

  • Recently Browsing   0 members

    • No registered users viewing this page.
×
×
  • Create New...