Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Android webview on document ready callback

When using WebView , is there a way to detect whether the document DOM tree has been loaded finish? I know that the WebViewClient provides a 'onPageFinish' callback,but it's called after all the web resources has been loaded finish.

If the web page is running a slow request (may be a bad request,and its http status is "waiting for responses"), then the "onPageFinish" won't be called until the request finish. I just want to catch the event when the web page's DOM tree loaded finish.

Any one help? Thanks a lot.

like image 624
小灰马 Avatar asked Oct 22 '25 14:10

小灰马


2 Answers

Use onPageCommitVisible replace onPageFinished.

    @Override
    public void onPageStarted(WebView view, String url, Bitmap favicon) {
        super.onPageStarted(view, url, favicon);
        prDialog = new ProgressDialog(MainActivity.this);
        prDialog.setMessage("Please wait ...");
        prDialog.show();
    }

    @Override
    public void onPageCommitVisible(WebView view, String url) {
        super.onPageCommitVisible(view, url);
        if(prDialog != null) prDialog.dismiss();
    }
like image 152
Norman Hsu Avatar answered Oct 27 '25 01:10

Norman Hsu


Javascript has event that use to detect completed building the DOM tree called DOMContentLoaded.

JavaScript Page Load Events

You can inject Javascript with addJavascriptInterface() and let it call the function in Native side that defined with JavaScriptInterface annotation, then execute the DOMContentLoaded with evaluateJavascript like

webView.apply {
    settings.javaScriptEnabled = true
    // Inject Javascript
    addJavascriptInterface(
        DomContentLoadedInterface({ /* Do something */ }),
        DomContentLoadedInterface.KEY
    )

    webViewClient = object : WebViewClient() {
        override fun onLoadResource(view: WebView?, url: String?) {
            super.onLoadResource(view, url)
            // Execute Javascript
            evaluateJavascript(DomContentLoadedInterface.SCRIPT)
        }
    }

    loadUrl(URL)
}

where DomContentLoadedInterface is

class DomContentLoadedInterface(private val action: () -> Unit) {

    @JavascriptInterface
    fun execute() {
        action()
    }

    companion object {
        internal const val KEY = "DomContentLoaded"
        internal const val SCRIPT = "javascript:document.addEventListener('DOMContentLoaded',function(){DomContentLoaded.execute()})"
    }
}

Note: evaluateJavascript will work in onLoadResource (https://stackoverflow.com/a/58932747/9896693) and after onPageFinished

like image 37
Doggo Avatar answered Oct 27 '25 01:10

Doggo



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!