Retrieve Element Intended for Click, But Click Event Canceled by Java Code in WebView

Nitish Kumar Singh

Dec 5, 2023

Hello developers! In this blog post, we will learn how to "Retrieve the Element Intended for a Click, but the Click Event is Canceled by Java Code in WebView." Okay, let's simplify it. I want to retrieve an element (JavaScript object of an HTML element) in JavaScript code that is about to be clicked, but it was not clicked because I canceled the click event in Java code within the onTouch method of OnTouchListener attached to the WebView.

Okay, maybe you're wondering, "Why do I want to do this?" or maybe not if you're searching for this. Just watch the video below, and you'll automatically understand why I want to do this.

Video Demonstrating use of elementFromPoint() function of DOM on NKS CODING LEARNINGS

To achieve this, we use OnTouchListener on the WebView to cancel the click event, the loadUrl() method of WebView to run JS code, and the elementFromPoint() function of the document (DOM document) to get the element that is about to be clicked.

The following is the Java code to perform all these tasks:

WebView webView = findViewById(R.id.yourWebViewId);
WebSettings webSettings = webView.getSettings();
webSettings.setJavaScriptEnabled(true);
webView.setWebViewClient(new WebViewClient());
// if you want to get some data from JS code
webView.addJavascriptInterface(new JsBridge(){
    @Override
    public void takeDataFromJS (String data) {
       // Do what you want with data
    }
},"AndroidJsBridge");
// load url you want
webView.loadUrl("https://example.com/");

// To cancel click event and get click points and run desire JS code
webView.setOnTouchListener(new View.OnTouchListener() {
    @Override
    public boolean onTouch(View v, MotionEvent event) {
       if (event.getAction() == MotionEvent.ACTION_DOWN) {
            // Get the x and y coordinates of the touch event
            int x = (int) event.getX();
            int y = (int) event.getY();
            Log.d(TAG, "onTouch: ");

            // Execute JavaScript to find the element under the touch coordinates
            webView.loadUrl("javascript:((x,y)=>{\n" +
                  "var r = document.elementFromPoint(x,y);\n" +
                  // Do wat you want to do with this element and then finally pass data as string to Java code
                  "window.AndroidJsBridge.takeDataFromJS(JSON.stringify(data));"+
                  "})("+x/screenDensityOfPhone+","+y/screenDensityOfPhone+");");
       }
    }
});

In the above code, screenDensityOfPhone is a variable of type float, and we can get it using the code below:

float screenDensityOfPhone = getResources().getDisplayMetrics().density;

We use screenDensityOfPhone because Java pixels and JS pixels are not the same. The JsBridge class is defined as follows:

public class JsBridge {
    @JavascriptInterface
    public void takeDataFromJS(String data){
        
    }
}

The elementFromPoint() function of the document returns the topmost element at the specified coordinates (relative to the viewport). You can also use the elementsFromPoint function to get all elements at the specified coordinates that are available one over the other.

Okay, I hope you learn how to do this and gain something by reading this blog post.

Published on Dec 5, 2023
Comments (undefined)

Read More