使用Internet Explorer我想获得一个人点击文本的位置。 3到4个字符的错误很好。该文本不可编辑,通常位于span元素中。
我知道我可以为HTMLDocument设置一个click事件监听器,但是我并不总是有HTMLDocument对象,因此可能会错过该事件。
我尝试获取IHTMLSelectionObject,然后使用IHTMLTxtRange创建文本范围,但是当简单地单击网页而不是选择至少1个字符时,IHTMLTxtRange具有HTMLBody的父级而不是元素的父级点击了。
HTMLDocument.activeElement也不可靠。在我的测试中,它实际上永远不会返回单击的元素,它通常会在树的某个位置返回元素的主要父元素。
使用MSHTML还有另一种方法可以实现吗?
我也尝试过使用WIN API GetCursorPos但是我不知道如何处理这个位置,我不知道如何将它转换为实际的元素。
修改 我还想到了一个有趣的想法。当我需要知道带有光标的元素时,我在整个文档上设置了mouseDown或click事件。然后开火我自己的点击并抓住事件。在事件的IHTMLEventObj中是一个FromElement,我希望它能告诉我光标在哪里。对于mouseDown和click事件似乎总是没有任何意义。对我来说,至少这个对象仅用于鼠标悬停事件。
以下是我选择至少一个角色时的情况。
Private Function GetHTMLSelection(ByVal aDoc As IHTMLDocument2, ByRef htmlText As String) As Integer
Dim sel As IHTMLSelectionObject = Nothing
Dim selectionRange As IHTMLTxtRange = Nothing
Dim rangeParent As IHTMLElement4 = Nothing
Dim duplicateRange As IHTMLTxtRange = Nothing
Dim i As Integer
Dim x As Integer
Dim found As Boolean
Try
'get a selection
sel = TryCast(aDoc.selection, IHTMLSelectionObject)
If sel Is Nothing Then
Return -1
End If
'the the range of the selection.
selectionRange = TryCast(sel.createRange, IHTMLTxtRange)
If selectionRange Is Nothing Then
Return -1
End If
'the the parent element of the range.
rangeParent = TryCast(selectionRange.parentElement, IHTMLElement4)
'duplicate our range so we can manipulate it.
duplicateRange = TryCast(selectionRange.duplicate, IHTMLTxtRange)
'make the dulicate range the whole element text.
duplicateRange.moveToElementText(rangeParent)
'get the length of the whole text
i = duplicateRange.text.Length
For x = 1 To i
duplicateRange.moveStart("character", 1)
If duplicateRange.compareEndPoints("StartToStart", selectionRange) = 0 Then
found = True
Exit For
End If
Next
If found Then
Debug.Print("Position is: " + x.ToString)
htmlText = duplicateRange.text
Return x
Else
Return -1
End If
Catch ex As Exception
Return -1
Finally
End Try
End Function
答案 0 :(得分:0)
我不能用一个很好的函数发布答案,说明如何做到这一点,但我将解释重要的部分。
一旦你有了这个,你现在知道点击的点和元素。
私有函数getElementTextPosition()As Boolean
Dim sel As IHTMLSelectionObject = Nothing
Dim selectionRange As IHTMLTxtRange = Nothing
Dim duplicateRange As IHTMLTxtRange = Nothing
Dim i As Integer = 0
Dim found As Boolean
Dim x As Integer
Try
'elementWithCursor is a IHTMLElement class variable
If elementWithCursor IsNot Nothing Then
ReleaseComObject(elementWithCursor)
elementWithCursor = Nothing
End If
'docWithCursor is also a IHTMLDocument2 class variable
'cursorPointInDoc is the point relative to the actual document
elementWithCursor = TryCast(docWithCursor.elementFromPoint(cursorPointInDoc.X, cursorPointInDoc.Y), IHTMLElement)
If elementWithCursor Is Nothing Then
Return False
End If
'get a selection
sel = TryCast(docWithCursor.selection, IHTMLSelectionObject)
If sel Is Nothing Then
Return False
End If
selectionRange = TryCast(sel.createRange, IHTMLTxtRange)
If selectionRange Is Nothing Then
Return False
End If
'First check if We have selection text so we will use that as the selected text
'_SelectedText relates to a class property
If selectionRange.text IsNot Nothing Then
_SelectedText = selectionRange.text
selectionRange.collapse(True)
Else
'the the parent element of the range.
selectionRange.moveToPoint(cursorPointInDoc.X, cursorPointInDoc.Y)
End If
'duplicate our range so we can manipulate it.
duplicateRange = TryCast(selectionRange.duplicate, IHTMLTxtRange)
'make the dulicate range the whole element text.
duplicateRange.moveToElementText(elementWithCursor)
'get the length of the whole text
i = duplicateRange.text.Length
For x = 0 To i
If duplicateRange.compareEndPoints("StartToStart", selectionRange) = 0 Then
found = True
Exit For
End If
duplicateRange.moveStart("character", 1)
Next
If found Then
'_CursorPositionInText is a class property and relates to the position where the person clicked in the html text.
_CursorPositionInText = x
_HTMLElementText = elementWithCursor.innerText
Return True
Else
Return False
End If
Catch ex As Exception
Return False
End Try
End Function