1

使用 Internet Explorer 我想获得一个人点击文本的位置。3 到 4 个字符的错误是可以的。文本不可编辑,通常位于 span 元素中。

我知道我可以为 HTMLDocument 设置一个单击事件侦听器,但是我并不总是拥有 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 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
4

1 回答 1

0

我不能用一个很好的功能来发布答案,展示如何做到这一点,但我会解释重要的部分。

  1. 使用 Win32 API GetCursorPos 来获取用户最后点击的屏幕上的点。
  2. 如果您有 iFrame,这意味着不止一个 HTMLDocument,那么您需要遍历您的 iFrame,并使用 HTMLFrameElement clientWidth 和 clientHeight 以及 IHTMLWindow3 screenTop 和 screenLeft 来找出您的观点所在的 HTMLDocument。
  3. 使用您在数字 2 中找到的 IHTMLWindow 将此点转换为相对点。
  4. 一旦您拥有正确的 HTMLDocument 和相对于该文档的点,您就可以在 IHTMLDocument2 对象上使用 elementFromPoint 方法。
  5. 一旦你有了这个,你现在就知道被点击的点和元素了。

    私有函数 getElementTextPosition() 作为布尔值

        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
    
于 2016-01-25T06:50:21.827 回答