R2D221 / WebView2.DOM

C# DOM bindings to be used with WebView2
MIT License
51 stars 10 forks source link

how can I custom excute js #13

Closed MichaelCHF closed 2 years ago

MichaelCHF commented 2 years ago

1._ = await webView.CoreWebView2.AddScriptToExecuteOnDocumentCreatedAsync(@"function test2(){alert('test2')}");

  1. _ = await webView.GetCoreWebView().ExecuteScriptAsync("test2()");//Error,await

private async void MainWindow_Loaded(object sender, RoutedEventArgs e) { await webView.EnsureCoreWebView2Async();

        _ = await webView.CoreWebView2.AddScriptToExecuteOnDocumentCreatedAsync(@"function test2(){alert('test2')}");

        await WebView2DOM.InitAsync(webView);
        webView.CoreWebView2.DOMContentLoaded += async (s, e) =>
        {
            await webView.InvokeInBrowserContextAsync(DOMContentLoaded);
            //_ = await webView.ExecuteScriptAsync("test2()");//is ok
        };
        webView.NavigateToString(@"
            <h1>Welcome to C# DOM</h1>
            <p>The current time is <span id='current-time'></span></p>
            <p>requestAnimationFrame FPS (called from C#) is <span id='fps'></span></p>
            <p>
                <button id='jsAlertButton'>(JS) Show alert</button>
                <br />
                <button id='csAlertButton'>(C#) Change window size</button>
            </p>
        ");
    }

    private async void DOMContentLoaded(WebView2.DOM.Window window)
    {
        var jsAlertButton = (HTMLButtonElement)window.document.getElementById("jsAlertButton");
        var csAlertButton = (HTMLButtonElement)window.document.getElementById("csAlertButton");

        jsAlertButton.onclick += JsAlertButton_onclick;
        csAlertButton.onclick += CsAlertButton_onclick;

        var currentTime_span = (HTMLElement)window.document.getElementById("current-time");
        currentTime_span.style.color = "red";

        var fps = (HTMLElement)window.document.getElementById("fps");

        _ = await webView.GetCoreWebView().ExecuteScriptAsync("test2()");//Error

        jsAlertButton.onmouseenter += JsAlertButton_onmouseenter;

        callback(Duration.Zero);
        void callback(Duration timestamp)
        {
            currentTime_span.innerText = GetCurrentDateTime();

            fps.innerText = $"{calculateFps(timestamp)}";

            _ = window.requestAnimationFrame(callback);
        }

    }
R2D221 commented 2 years ago

When you say it's an error, what error message do you get?

MichaelCHF commented 2 years ago

image

R2D221 commented 2 years ago

This is something I must investigate. I'll let you know when I release a fix for this.

R2D221 commented 2 years ago

I've investigated it, and the error is that you can't call GetCoreWebView() inside the DOMContentLoaded method.

WebView2.DOM runs in a different thread, but interacting with the base controls must still be done within a UI thread.

The correct way to invoke it is like this:

private async void DOMContentLoaded(WebView2.DOM.Window window)
{
    // Here we're in the browsing context

    _ = await webView.Dispatcher.InvokeAsync(async () =>
    {
        // Here we're back in the UI context

        _ = await webView.CoreWebView2.ExecuteScriptAsync("test2()");
    });
}