0

Hey!

Simple question, is there any way I can get a webbrowser to wait until an element is present? I'm not an amazing coder, so here's my best example of what I'm trying to do -

            Do While PageLoaded = False
            Dim OObject As Object
            OObject = WebBrowser1.Document.GetElementById("Element-That-I-Need-Loaded")
            If (OObject Is Nothing) Then
                Pageloaded = False
            Else
                PageLoaded = True
            End If
        Loop

The problem with this is that the element doesn't have an ID, so when I'm trying to do something like click it, I have to do something like this -

            For Each altelm As HtmlElement In WebBrowser1.Document.GetElementsByTagName("SPAN")
            If altelm.GetAttribute("classname").ToString = "Classname-of-Element-I-Need-Loaded" Then
                altelm.Focus()
                altelm.InvokeMember("click")
            End If

I apologise if this is worded poorly, I'm new to this :)

Thanks!

ENVY
  • 1
  • 1
  • Read documentation related to [`DocumentCompleted`](https://stackoverflow.com/questions/7901701/documentcompleted) event – Sunil Apr 02 '18 at 13:58
  • Waiting loops are almost always a bad choice. Use the [**`WebBrowser.DocumentCompleted` event**](https://msdn.microsoft.com/en-us/library/system.windows.forms.webbrowser.documentcompleted(v=vs.110).aspx) (or a timer, if the element is added some time after the page has loaded). – Visual Vincent Apr 02 '18 at 16:01
  • Thanks! I've tried using that, but the element loads seperately to the rest of the page, meaning you have to scroll down then the element will load in. Currently I'm using a timer, but if people have slower internet to mine, the timer may be too quick. – ENVY Apr 02 '18 at 23:54
  • You are supposed to use the timer to _**check**_ for the element periodically, not to delay the execution of your code. Give the timer an interval of, say, 250-500 ms. Then put your second code block (from your question) in the timer's `Tick` event, and below the `altelm.InvokeMember("click")` line you add `Timer1.Stop()`. Now the timer will run that code every _x_ milliseconds until the element is found, then it runs the code inside the `If` statement and stops. – Visual Vincent Apr 03 '18 at 09:56
  • Hi again! I haven't heard from you in a while so I just wanted to check if my answer was of any help? – Visual Vincent May 19 '18 at 09:23

1 Answers1

0

Use a timer that checks for the element periodically. Start the timer in the DocumentCompleted event, then stop it once the element has been found.

Private WithEvents WaitTimer As New Timer With {.Interval = 250}

Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click
    WebBrowser1.Navigate("http://www.somewebsite.com/")
    AddHandler WebBrowser1.DocumentCompleted, AddressOf SomeWebsite_DocumentCompleted
End Sub

Private Sub SomeWebsite_DocumentCompleted(sender As Object, e As WebBrowserDocumentCompletedEventArgs)
    WaitTimer.Start()
    RemoveHandler WebBrowser1.DocumentCompleted, AddressOf SomeWebsite_DocumentCompleted
End Sub

Private Sub WaitTimer_Tick(sender As Object, e As EventArgs) Handles WaitTimer.Tick
    'Look for the element every time the timer ticks.
    For Each altelm As HtmlElement In WebBrowser1.Document.GetElementsByTagName("SPAN")
        If altelm.GetAttribute("className") = "Classname-of-Element-I-Need-Loaded" Then 'No need to call ToString() since GetAttribute() already returns a string.
            altelm.Focus()
            altelm.InvokeMember("click")
            WaitTimer.Stop() 'Element found, stop the timer.
        End If
    Next
End Sub
Visual Vincent
  • 18,045
  • 5
  • 28
  • 75