Получение абсолютной позиции элемента HTML в управлении веб-браузером с помощью С#
Мне было интересно, можно ли получить абсолютную позицию определенного элемента HTML, который я загрузил в элементе управления webbrowser с помощью С#.
Я попробовал почти все варианты, которые предоставляет .Net.
ни один из них не дает мне правильную позицию. все они дают мне 0 для координаты Y. элемент определенно не в 0..
У кого-нибудь есть решение или идея решить это?
Ответы
Ответ 1
вот решение, которое я получил до сих пор:
// задаем размер нашего веб-браузера того же размера, что и изображение 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);
Забастовкa >
теперь этот код работает отлично.. но есть проблема с вычислением смещений. Мне нужно вычислить offsetparent элемента, а затем вычислить offsetparent offsetparent и т.д. Мне нужно сделать это динамически, не добавляя его один за другим.. Я не знаю, как это сделать. любые идеи?
EDIT:
вот моя последняя и последняя версия, и она работает с любым элементом html, он найдет абсолютную позицию любого элемента, который я хочу.
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;
}
затем используйте позицию с помощью:
//now scroll to that element
webBrowser1.Document.Window.ScrollTo(x, y);
сделано!
Ответ 2
Мне нравятся предыдущие ответы, но итерация через родительские объекты дважды не очень эффективна. Помните - вы работаете с COM/ActiveX здесь. Это работает намного быстрее:
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;
}
а затем
var point = GetOffset(element);
var x = point.X;
var y = point.Y;
Ответ 3
Спасибо, это работает как шарм. Мне пришлось переписать его как VB и просто хочу поделиться решением:
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
Существует прямой способ получить координаты. IHTMLElement2 имеет метод getBoundingClientRect
, который дает вам координаты элемента.
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
Просто делюсь немного другой реализацией, основанной на моих потребностях, чтобы получить прямоугольник абсолютного позиционирования:
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
Не уверен, почему, но offsetparent не всегда возвращен (случай IE11, объект карты)
Мне пришлось добавить parentElement в цикле, когда parentOffset не предоставляется
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
И вам нужно добавить позицию браузера IE, пространство меню и границы...
Ответ 7
Самый чистый способ, который работает для меня, следующий:
HtmlElement elem = webBrowser.Document.GetElementById(idElement);
IHTMLRect rect = ((IHTMLElement2) elem.DomElement).getBoundingClientRect();
// rect.top and rect.left represent absolute coordinates.