2016-01-20 1 views
0

En utilisant Internet Explorer Je voudrais obtenir la position où une personne a cliqué sur le texte. Une erreur de 3 à 4 caractères est correcte. Le texte n'est pas modifiable et se trouve généralement dans un élément span.Comment obtenir l'élément HTML et la position dans le texte de l'élément où une personne a cliqué

Je suis conscient que je pourrais mettre en place un écouteur d'événement click pour HTMLDocument mais je n'ai pas toujours l'objet HTMLDocument et donc peut manquer l'événement. J'ai essayé d'obtenir un IHTMLSelectionObject, puis j'ai créé une plage de texte avec IHTMLTxtRange, mais quand on clique simplement sur la page web, au moins 1 caractère est sélectionné alors l'IHTMLTxtRange a un parent du HTMLBody et non du élément qui a été cliqué.

Le HTMLDocument.activeElement est également peu fiable. Dans mes tests, il ne retourne jamais l'élément cliqué, il renvoie généralement un parent principal de l'élément quelque part dans l'arbre. En utilisant MSHTML, existe-t-il un autre moyen d'atteindre cet objectif?

J'ai aussi essayé d'utiliser l'API WIN GetCursorPos mais je ne sais pas quoi faire avec cette position, je ne sais pas comment la convertir en élément réel.

EDIT: J'ai également pensé à une idée intéressante. Lorsque j'ai besoin de connaître l'élément qui a le curseur, je définis un événement mouseDown ou click sur l'ensemble du document. Ensuite, lancez mon propre clic et attraper l'événement. Dans le IHTMLEventObj de l'événement est un FromElement que j'avais espéré me dire où le curseur était. Il semble que ce soit toujours rien pour les événements mouseDown et click. Pour moi au moins cet objet n'est utilisé que dans les événements mouseover par exemple.

Ce qui suit est ce que j'ai quand au moins un caractère est sélectionné.

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

Jetez un oeil à cette question [Comment obtenir un mot sous le curseur en utilisant JavaScript?] (Http://stackoverflow.com/questions/2444430/comment-obtenir-un-mot-sous-curseur-en utilisant-javascript) qui ont de bonnes réponses. Vous pouvez utiliser une de ces réponses javascript et il suffit d'injecter le script dans la page par programmation.Vous pouvez également réécrire la logique en C# et lier aux événements en utilisant le code C# et l'API de contrôle du navigateur Web. J'ai utilisé cette recherche: javascript obtenir le mot sous le signe –

+0

Merci pour le commentaire. Je ne suis pas un expert en JavaScript, mais il semble que toutes les réponses reposent sur un événement de souris qu'ils ajoutent, dans certains cas, ils ajoutent d'abord un span à chaque mot et ajoutent un écouteur d'événement à chacun de ces tags. Je ne peux pas utiliser les événements tout le temps. – darbid

+0

Vous êtes les bienvenus, L'idée principale est d'envelopper tout le mot dans une durée, puis au lieu de la souris sur, vous pouvez utiliser l'événement click. –

Répondre

0

Je ne peux pas poster de réponse avec une belle fonction qui montre comment faire cela mais je vais vous expliquer les parties importantes.

  1. utilisez l'API Win32 GetCursorPos pour obtenir le point sur l'écran sur lequel l'utilisateur a cliqué en dernier.
  2. Si vous avez des iFrames qui signifie plus d'un HTMLDocument, vous devez parcourir vos iFrames et utiliser HTMLFrameElement clientWidth et clientHeight avec un IHTMLWindow3 screenTop et screenLeft pour trouver quel HTMLDocument votre point est sur.
  3. Convertir ce point à un point par rapport à l'aide du IHTMLWindow-vous dans le numéro 2.
  4. Une fois que vous avez le droit HTMLDocument et un point par rapport à ce document, vous pouvez ensuite utiliser la méthode elementFromPoint sur un objet IHTMLDocument2.
  5. Une fois que vous avez cela, vous connaissez maintenant le point et l'élément sur lequel vous avez cliqué.

    Fonction privée 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