Getting “Link text” of the link displayed in WebView

送分小仙女□ 提交于 2020-01-25 09:53:07

问题


I have Android WebView which displays some links as:
<a href="http://link1.html">Link1Text</a>
<a href="http://link2.html">Link2Text</a>
Now I would like to retrieve Link1Text and Link2Text when I long press these links. I have contextMenu implemented in the code and I could successfully get the link urls (http://link1.html, http://link2.html) using HitTestResult getExtra() method but how ccan I get those link texts ?

FYI, I require those link texts for implementing "Copy link text" option in the contextMenu.


回答1:


Unfortunately, a clear, official way to do this is not available. Although, there are two APIs (selectText and copySelection) which are pending API council approval, that may help to do this, but they are not available at the moment.




回答2:


To get the text of an achor link:

I. Hook a touchstart listener to every web pages in the onPageFinished() callback of WebViewClient via evaluateJavascript. like:

        //Javascripts to evaluate in onPageFinished

        const w=window;
        w.addEventListener('touchstart',wrappedOnDownFunc);
        function wrappedOnDownFunc(e){
            if(e.touches.length==1){
                w._touchtarget = e.touches[0].target;
            }
            console.log('hey touched something ' +w._touchtarget);
        }

note we've saved the touch target.

II. Then implement OnLongClicklisenter for webview. use evaluateJavascript again when you long pressed on a link object:

            @Override
            public boolean onLongClick(View v) {
                WebView.HitTestResult result = ((WebView)v).getHitTestResult();
                if (null == result) return false;
                int type = result.getType();
                switch (type) {
                    case WebView.HitTestResult.SRC_ANCHOR_TYPE:
                        if(result.getExtra()!=null){
                            ((WebView)v).evaluateJavascript("window._touchtarget?window._touchtarget.innerText:''", new ValueCallback<String>() {
                                @Override
                                public void onReceiveValue(String value) {
                                    System.out.println("hey received link text : "+value);
                                }
                            });
                        }
                    return true;
                }
                return false;
            }

What's more, we can even choose to select the text of the anchor element! Actually this is one of the options that samsung browser offers when you long-pressed an tag .

To achieve this, we still need that recorded touch target. Besides we need 2 new javascript methods:

        function selectTouchtarget(){
            var tt = w._touchtarget;
            if(tt){
                w._touchtarget_href = tt.getAttribute("href");
                tt.removeAttribute("href");
                var sel = w.getSelection();
                var range = document.createRange();
                range.selectNodeContents(tt);
                sel.removeAllRanges();
                sel.addRange(range);
            }
        }
        function restoreTouchtarget(){
            var tt = w._touchtarget;
            if(tt){
                tt.setAttribute("href", w._touchtarget_href);
            }
        }

Finnaly in the onLongClick listener, instead of just fetch the innerText, we programmatically set the selection, trigger the action menu bar, and restore the removed href attribute of our touch target.

    case WebViewmy.HitTestResult.SRC_ANCHOR_TYPE:
        if(result.getExtra()!=null){
            WebViewmy mWebView = ((WebViewmy)v);
            mWebView.evaluateJavascript("selectTouchtarget()", new ValueCallback<String>() {
                @Override
                public void onReceiveValue(String value) {
                    /* bring in action mode by a fake click on the programmatically  selected text. */
                    MotionEvent te = MotionEvent.obtain(0,0,KeyEvent.ACTION_DOWN,mWebView.lastX,mWebView.lastY,0);
                    mWebView.dispatchTouchEvent(te);
                    te.setAction(KeyEvent.ACTION_UP);
                    mWebView.dispatchTouchEvent(te);
                    te.recycle();
                    //if it's not delayed for a while or the href attribute is not removed, then the above code would click into
                    //  the anchor element instead of select it's text.
                    /* restore href attribute */
                    mWebView.postDelayed(() -> mWebView.evaluateJavascript("restoreTouchtarget()", null), 100);
                }
            });
        }
    return true;

In my case, I've extended the WebView as WebViewmy to record last touched positions, lastX and lastY, in the onTouchEvent method.



来源:https://stackoverflow.com/questions/24203282/getting-link-text-of-the-link-displayed-in-webview

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!