在WebView中选择元素并获取详细信息 [英] Select element inside WebView and get details

查看:109
本文介绍了在WebView中选择元素并获取详细信息的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我已经在我的android应用中实现了一个webview,并试图在用户单击布局时突出显示或标记元素.

i have implemented a webview in my android app and trying to highlight or to mark element when user click in the layout.

webview初始化如下:

The webview is initialized as following :

myWebView.getSettings().setJavaScriptEnabled(true);
//myWebView.getSettings().setGeolocationEnabled(true);
//myWebView.getSettings().setJavaScriptCanOpenWindowsAutomatically(true);
myWebView.getSettings().setBuiltInZoomControls(true);
myWebView.getSettings().setDomStorageEnabled(true);
myWebView.setWebViewClient(new WebViewController());

例如,如屏幕截图所示,尝试标记用户单击的元素:

Trying to mark the element which is clicked by user for example like in this screenshot :

带点选择

我通过jsoup获取所有页面div:

I'm getting all the page divs via jsoup :

doc = Jsoup.connect(url).get();
final Elements alldivs = doc.select("div");
ArrayList<String> list = new ArrayList<String>();
for (org.jsoup.nodes.Element e : alldivs) {
if (!e.id().equals(""))
list.add(e.id());
}

但是如何将所选内容标记为上面的照片,然后再从div ID中选择标记的内容.

But how to mark the selection as the photo above, and after that select marked content from div id.

如何制作这样的东西?

我正在使用此javascript进入Webview突出显示选择内容,但如何以编程方式获取被点击的元素,例如:所选div的ID或其他值

I'm using this javascript into webview to hightlight the selection but how to get the clicked element programmatically like : id of selected div or other values

public class MyWebViewClient extends WebViewClient {
    @Override
    public void onPageFinished(WebView view, String url) {
        view.loadUrl("javascript: "
                + "Object.prototype.each = function (fn, bind) {\n" +
                "                console.log(bind);\n" +
                "                for (var i = 0; i < this.length; i++) {\n" +
                "                    if (i in this) {\n" +
                "                        fn.call(bind, this[i], i, this);\n" +
                "                    }\n" +
                "                }\n" +
                "            };\n" +
                "\n" +
                "            var _addListener = document.addEventListener || document.attachEvent,\n" +
                "                _eventClick = window.addEventListener ? 'click' : 'onclick';\n" +
                "\n" +
                "            var elements = document.getElementsByTagName(\"div\");\n" +
                "\n" +
                "            elements.each(function (el) {\n" +
                "                _addListener.call(el, _eventClick, function () {\n" +
                                 // todo process the clicked div element
                "                    el.style.cssText = \"border-color:  black;border-style:  dashed;\"\n" +
                "                }, false);\n" +
                "            })");
    }
}

推荐答案

如果我理解正确,则希望将一些信息从HTML组件获取到本机端.

If I understand correctly, you want to get some information from the HTML component into the native side.

根据此答案,无法将任意对象传递给Java,但是至少您可以传递单击的节点的HTML代码,然后对其进行本地解析.

According to this answer, it is not possible to pass arbitrary objects to Java, but at least you can pass the HTML code of the clicked node and then parse it natively.

基于您的代码完全可以做到这一点.

This code based on yours does exactly that.

MainActivity.java:我猜这很容易解释.我唯一与您不同的是从单独的文件中获取Javascript代码,因此更易于维护.

MainActivity.java: I guess this is pretty self-explanatory. The only thing I did different from you is to get the Javascript code from a separate file, so it's easier to maintain.

public class MainActivity extends AppCompatActivity {
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        final WebView myWebView = findViewById(R.id.webView);
        final WebSettings settings = myWebView.getSettings();

        settings.setJavaScriptEnabled(true);
        myWebView.setWebViewClient(new WebViewClient() {
            @Override
            public void onPageFinished(WebView view, String url) {
                super.onPageFinished(view, url);
                final String injectedJs = "javascript:(function(){" + injectedJs() + "})()";
                myWebView.loadUrl(injectedJs);
            }
        });

        myWebView.addJavascriptInterface(
                new Object() {
                    @JavascriptInterface
                    public void onClick(String param) {
                        Toast.makeText(MainActivity.this, param, Toast.LENGTH_LONG).show();
                    }
                },
                "appHost"
        );
        myWebView.loadUrl("https://google.com");
    }

    // Javascript code to inject on the Web page
    private String injectedJs() {
        BufferedReader stream = null;
        StringBuilder jsBuilder = new StringBuilder();
        try {
            stream = new BufferedReader(new InputStreamReader(getAssets().open("js.js")));
            String line;
            while ((line = stream.readLine()) != null) {
                jsBuilder.append(line.trim());
            }
            return jsBuilder.toString();
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            if (stream != null) {
                try {
                    stream.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }
        return "";
    }
}


js.js:这部分的基础是您的代码.请记住,由于 injectedJs()会删除所有行标记,因此每个语句都需要完成,包括注释,因此,使用/*...*/而不是//


js.js: The base of this part is your code. Keep in mind that since injectedJs() removes all line markers, every statement needs to finish, including comments, hence the /*...*/ instead of //

/* Keep track of the last clicked element so we can un-highlight it */
var lastSelectedItem = null;

var showHighlighted = function(/* HTML element */view, /*boolean */highlighted) {
    if (view) {
        view.style.cssText = highlighted? 'border-color: black;border-style: dashed;' : '';
    }
};

/* This new method, _addEventListener and _eventClick are the same as yours */
Object.prototype.each = function (fn, bind) {
                for (var i = 0; i < this.length; i++) {
                    if (i in this) {
                        fn.call(bind, this[i], i, this);
                    }
                }
            };

var _addListener = document.addEventListener || document.attachEvent,
    _eventClick = window.addEventListener ? 'click' : 'onclick';

/* I changed the element selection criteria, but you can change it back easily.
   I am adding event listeners all the leaf elements in the DOM. */
var elements = document.body.getElementsByTagName('*');
elements.each(function (el) {
    if (el.children.length == 0) {
        _addListener.call(el, _eventClick, function () {
            /* First, deal with the previously selected item*/
            showHighlighted(lastSelectedItem, false);
            if (lastSelectedItem !== null) {
                appHost.onClick(lastSelectedItem.outerHTML);                
            }

            /* Update the selected item reference */
            lastSelectedItem = el;


            /* Finally, deal with the previously selected item*/
            showHighlighted(lastSelectedItem, true);
            appHost.onClick(el.outerHTML);
        }, false);
    }
});

这篇关于在WebView中选择元素并获取详细信息的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆