getting absolute position of HTML element in webbrowser control with C#

匿名 (未验证) 提交于 2019-12-03 02:48:02

问题:

I was wondering if its possible to get the absolute position of specific HTML element I have loaded in webbrowser control with C#.

I tried almost all of the options that .Net provides.. none of them give me the correct position. all of them give me 0 for Y coordinate.. the element is definitely is not in 0..

does anybody have any solution or idea to solve this?

回答1:

here is the solution I got so far:

// set the size of our web browser to be the same size as the image int width, height; width = webBrowser1.Document.Images[0].ClientRectangle.Width; height = webBrowser1.Document.Images[0].ClientRectangle.Height;

webBrowser1.Width = width; webBrowser1.Height = height;  //scroll vertically to that element webBrowser1.Document.Images[0].OffsetParent.ScrollIntoView(true);  //calculate x, y offset of the element int x = webBrowser1.Document.Images[s].OffsetRectangle.Left +  webBrowser1.Document.Images[s].OffsetParent.OffsetRectangle.Left +  webBrowser1.Document.Images[s].OffsetParent.OffsetParent.OffsetRectangle.Left+ webBrowser1.Document.Images[s].OffsetParent.OffsetParent.OffsetParent.OffsetRectangle.Left+ webBrowser1.Document.Images[s].OffsetParent.OffsetParent.OffsetParent.OffsetParent.OffsetRectangle.Left;  int y = webBrowser1.Document.GetElementsByTagName("HTML")[0].ScrollTop;  //now scroll to that element webBrowser1.Document.Window.ScrollTo(x, y); 

now this code works perfectly.. but there is an issue with calculating the offsets. I need to calculate the offsetparent of the element then calculate the offsetparent of the offsetparent etc.. I need to do that dynamically not adding it one by one.. I don't know how to do that. any ideas?

EDIT: here is my last and final version and it works with any html element it will find the absolute position of any element I want..

   public int getXoffset(HtmlElement el)      {          //get element pos          int xPos = el.OffsetRectangle.Left;           //get the parents pos          HtmlElement tempEl = el.OffsetParent;          while (tempEl != null)          {              xPos += tempEl.OffsetRectangle.Left;              tempEl = tempEl.OffsetParent;          }           return xPos;       }         public int getYoffset(HtmlElement el)      {          //get element pos          int yPos = el.OffsetRectangle.Top;           //get the parents pos          HtmlElement tempEl = el.OffsetParent;          while (tempEl != null)          {              yPos += tempEl.OffsetRectangle.Top;              tempEl = tempEl.OffsetParent;          }           return yPos;      } 

then use the position with:

 //now scroll to that element  webBrowser1.Document.Window.ScrollTo(x, y); 

done!



回答2:

I like previous answers but iterating through parent objects twice is not very effective. Remember - you're working with COM/ActiveX here. This works much faster:

public Point GetOffset(HtmlElement el) {     //get element pos     Point pos = new Point(el.OffsetRectangle.Left, el.OffsetRectangle.Top);      //get the parents pos     HtmlElement tempEl = el.OffsetParent;     while (tempEl != null)     {         pos.X += tempEl.OffsetRectangle.Left;         pos.Y += tempEl.OffsetRectangle.Top;         tempEl = tempEl.OffsetParent;     }      return pos; } 

and then

var point = GetOffset(element); var x = point.X; var y = point.Y; 


回答3:

Thank you, it works like a charm. I had to rewrite it as VB, and just want to share the solution:

Function GetXOffSet(ByVal elem As HtmlElement) As Integer     Dim xPos As Integer = elem.OffsetRectangle.Left     Dim tElm As HtmlElement = elem.OffsetParent     Dim trig As Boolean = False     While Not trig         Try             xPos += tElm.OffsetRectangle.Left             tElm = tElm.OffsetParent         Catch ex As Exception             trig = True         End Try     End While     Return xPos End Function  Function GetYOffSet(ByVal elem As HtmlElement) As Integer     Dim yPos As Integer = elem.OffsetRectangle.Top     Dim tElm As HtmlElement = elem.OffsetParent     Dim trig As Boolean = False     While Not trig         Try             yPos += tElm.OffsetRectangle.Top             tElm = tElm.OffsetParent         Catch ex As Exception             trig = True         End Try     End While     Return yPos End Function 


回答4:

There is a direct way to get the coordinates. IHTMLElement2 has the method getBoundingClientRect that gives you the coordinates of the element.

IHTMLDocument3 doc = (IHTMLDocument3)this.webbrowser.Document; IHTMLElement2 element = (IHTMLElement2)doc.getElementById(idElement); IHTMLRect rect = element.getBoundingClientRect();  int x = rect.left; int y= rect.top; 


回答5:

Just sharing a slightly different implementation based on my needs to get the absolute positioning retangle:

public Rectangle GetAbsoluteRectangle(HtmlElement element) {     //get initial rectangle     Rectangle rect = element.OffsetRectangle;      //update with all parents' positions     HtmlElement currParent = element.OffsetParent;     while (currParent != null) {             rect.Offset(currParent.OffsetRectangle.Left, currParent.OffsetRectangle.Top);             currParent = currParent.OffsetParent;     }      return rect; } 


回答6:

Not sure why but offsetparent is not allways returned (case of IE11, map object) I had to add parentElement in the loop when parentOffset is not provided

    While parent IsNot Nothing             y += parent.offsetTop             x += parent.offsetLeft             If  parent.offsetParent IsNot Nothing Then                 parent = parent.offsetParent               Else                 parent = parent.parentElement             End If     End While 

And you need to add IE browser position, the menu space and borders ...



回答7:

The cleanest way that works for me is the following:

HtmlElement elem = webBrowser.Document.GetElementById(idElement); IHTMLRect rect = ((IHTMLElement2) elem.DomElement).getBoundingClientRect(); // rect.top and rect.left represent absolute coordinates.



标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!