This example demonstrates how to use JavaScript MutationObserver in combination with JavaScript-.NET Bridge API. The goal of this example is to transmit every change of the HTML element to the .NET side and display it in the Output window.


The HTML page that we are listening to has timer that updates value of the span element. The source code of the page is the following:

<!DOCTYPE html>
<html>
  <head>
    <title>index</title>
  </head>
  <body>
    <div>
      <span class="countdown" id="countdown"></span>
    </div>
    <script src="https://code.jquery.com/jquery-3.2.1.slim.min.js"
               crossorigin="anonymous"></script>
    <script type="text/javascript">
        $(document).ready(function () {
          var counter = 1;
          setInterval(function() { $(".countdown").text(counter++); }, 1000);
        });
    </script>
  </body>
</html>

The source code of the WPF Window that displays the web page, injects MutationObserver and listens to it is the following:

C#

public partial class MainWindow : Window
{
    private WPFBrowserView view;
    private MutationObserverListener listener;

    public MainWindow()
    {
        InitializeComponent();

        listener = new MutationObserverListener();

        view = new WPFBrowserView();
        this.MainPanel.Children.Add(view);            
        view.Browser.FinishLoadingFrameEvent += 
                Browser_FinishLoadingFrameEvent;

        string indexFilePath = System.IO.Path.Combine(
                Environment.CurrentDirectory, "index.html");
        view.Browser.LoadURL(indexFilePath);
    }

    private void Browser_FinishLoadingFrameEvent(object sender, FinishLoadingEventArgs e)
    {
        if (e.IsMainFrame)
        {
            // Injecting the listener .NET object into Javascript
            JSValue value = view.Browser.ExecuteJavaScriptAndReturnValue("window");
            value.AsObject().SetProperty("MutationObserverListener", listener);

            // Script for attaching observer to the element with id 'countdown'
            string observerScript =
            "var spanElement = document.getElementById('countdown');" +
            "var observer = new MutationObserver(" +
            "function(mutations){" +
            "window.MutationObserverListener.CharacterDataChanged(spanElement.innerHTML);" +
            "});" +
            "var config = { childList: true };" +
            "observer.observe(spanElement, config);";

            // Executing script that attaches observer
            view.Browser.ExecuteJavaScript(observerScript);
        }
    }
}

public class MutationObserverListener
{
    public void CharacterDataChanged(string innerText)
    {
        Console.WriteLine(innerText);
    }
}

VB.NET

Public Partial Class MainWindow
    Inherits Window

    Private view As WPFBrowserView
    Private listener As MutationObserverListener

    Public Sub New()
        InitializeComponent()
        listener = New MutationObserverListener()
        view = New WPFBrowserView()
        Me.MainPanel.Children.Add(view)
        AddHandler view.Browser.FinishLoadingFrameEvent, AddressOf Browser_FinishLoadingFrameEvent
        Dim indexFilePath As String = System.IO.Path.Combine(Environment.CurrentDirectory, "index.html")
        view.Browser.LoadURL(indexFilePath)
    End Sub

    Private Sub Browser_FinishLoadingFrameEvent(ByVal sender As Object, ByVal e As FinishLoadingEventArgs)
        If e.IsMainFrame Then
            Dim value As JSValue = view.Browser.ExecuteJavaScriptAndReturnValue("window")
            value.AsObject().SetProperty("MutationObserverListener", listener)
            Dim observerScript As String = "var spanElement = document.getElementById('countdown');" &
                                           "var observer = new MutationObserver(" & "function(mutations){" &
                                           "window.MutationObserverListener.CharacterDataChanged(spanElement.innerHTML);" &
                                           "});" & "var config = { childList: true };" &
                                           "observer.observe(spanElement, config);"
            view.Browser.ExecuteJavaScript(observerScript)
        End If
    End Sub