js提取指定网站内容(前几天脑子里忽然简书的图片分享效果,感觉很简洁)
优采云 发布时间: 2022-01-05 18:13js提取指定网站内容(前几天脑子里忽然简书的图片分享效果,感觉很简洁)
前几天,脑子里突然闪过简书的图片分享效果。感觉非常简单和美丽。想着自己的方法能不能实现,所以今天就有了这篇文章。好的,我们先来看看效果图:
项目地址:
欢迎star,问题~
要达到这个效果,首先要明白几个问题:
一、如何获取选中的网页内容
二、如何加载和显示获取的网页内容
一、如何获取选中的网页内容
获取选定的网页内容非常困难。通过Java获取选中的网页内容非常困难,要达到效果,必须获取选中的网页内容。我们可以改变我们的想法。既然不容易通过Java层获取,那么使用JavaScript是不是更容易呢?嗯,后来的实现也证实了这个想法是正确的,JavaScript很容易获取到选中的网页内容。
那么我们的思路是:当用户点击生成的图片分享按钮时,我们调用JavaScript方法获取选中的网页内容,同时回调Java的get content方法,将获取的网页内容传回Java层,我们可以得到网页内容。
简单看一下代码:
mWebView.addJavascriptInterface(new WebAppInterface(onGetDataListener), "JSInterface"); public void getSelectedData(WebView webView) { String js = "(function getSelectedText() {" + "var txt;" + "if (window.getSelection) {" + "var range=window.getSelection().getRangeAt(0);" + "var container = window.document.createElement('div');" + "container.appendChild(range.cloneContents());" + "txt = container.innerHTML;" + "} else if (window.document.getSelection) {" + "var range=window.getSelection().getRangeAt(0);" + "var container = window.document.createElement('div');" + "container.appendChild(range.cloneContents());" + "txt = container.innerHTML;" + "} else if (window.document.selection) {" + "txt = window.document.selection.createRange().htmlText;" + "}" + "JSInterface.getText(txt);" + "})()"; // calling the js function if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) { webView.evaluateJavascript("javascript:" + js, null); } else { webView.loadUrl("javascript:" + js); } webView.clearFocus(); } static class WebAppInterface { WebViewHelper.OnGetDataListener onGetDataListener; WebAppInterface(WebViewHelper.OnGetDataListener onGetDataListener) { this.onGetDataListener = onGetDataListener; } @JavascriptInterface public void getText(String text) { onGetDataListener.getDataListener(text); } } public interface OnGetDataListener{ void getDataListener(String text); }
上面的实现思路是,当我们想要获取选中的网页内容时,将自己编写的一段JavaScript脚本注入到WebView中。这段JavaScript代码的意思是获取当前页面收录html标签的选中内容,调用JSInterface.getText(txt)方法。将内容返回给Java的getText(String text)方法,我们设置onGetDataListener.getDataListener(text)回调方法,在需要的地方调用获取内容。
二、如何加载和显示获取的网页内容
我们已经获得了网页的内容。调用TextView的setText(Html.fromHtml())方法来显示我们选择的效果是合理的,但是考虑到美观和保存截图的功能以及图片的正常显示,我选择使用WebView来加载得到的网页内容。
我是这样处理的:首先在本地assets文件夹中创建一个html页面,加载页面中的基本显示内容并添加css标签修改加载的内容,当获取到网页内容时,本地html page动态替换为JavaScript指定对应的标签内容为获取的网页内容,在本地html页面修改显示内容。
看代码:
webView.loadUrl("file:///android_asset/generate_pic.html"); public void changeDay(String strData,String userInfo,String userName,String other) { if(userInfo == null) userInfo =""; if(strData == null) strData =""; if(userName == null) userName =""; if(other == null) other =""; strData+="<br /><br />n" + "tt"+userInfo+"n" + "tt<br /><br />n" + "ttn" + "tt<br />n" + "tt<p style="/spancolor: orangered;font-size: x-small;text-align: center;letter-spacing: span class="hljs-number"0.5/spanpx;span class="hljs-string"">由"+userName+"发送 "+other+""; webView.loadUrl("javascript:changeContent("" + strData.replace("n", "\n").replace(""", "\"").replace("'", "\'") + "")"); webView.setBackgroundColor(Color.WHITE); }</p>
白色和黑色的不同显示效果可以通过changeDay方法中改变css样式来实现,比较简单。
但这里存在问题:当所选页面内容具有图片并且图像显示在相对路径中时,无法加载图像。
在这种情况下,图片是相对路径,即在本地对应的相对路径下查找。本地一定找不到,图片也不会显示。
为了能正常显示图片,在选中的内容页面调用onLoadResource方法判断加载的资源并保存图片路径,因为既然选中的页面图片是可以显示和处理的,就说明路径是http路径,可以显示图片。
看代码:
mWebView.setWebViewClient(new WebViewClient(){ @Override public void onLoadResource(WebView view, String url) { //Log.e("TAG","url :"+url); if(url.toLowerCase().contains(".jpg") ||url.toLowerCase().contains(".png") ||url.toLowerCase().contains(".gif")){ mlistPath.add(url); } super.onLoadResource(view, url); }
当显示选中的内容页面时,动态修改显示的图片路径以显示图片:
webView.setWebViewClient(new WebViewClient(){ @Override public boolean shouldOverrideUrlLoading(WebView view, String url) { //view.loadUrl(url); return true; } public WebResourceResponse shouldInterceptRequest(WebView view, String url) { WebResourceResponse response = null; for (String path:WebViewHelper.getInstance().getAllListPath()){ if (path.toLowerCase().contains(url.replace("file://","").toLowerCase())){ try { response = new WebResourceResponse("image/png", "UTF-8", new URL(path).openStream()); } catch (IOException e) { e.printStackTrace(); } } } return response; } });
这样我们的图片就可以显示出来了!
最后,实现我们的截图保存功能,看代码:
/** * 截屏 * * @return */ public Bitmap getScreen() { Bitmap bmp = Bitmap.createBitmap(webView.getWidth(), 1, Bitmap.Config.ARGB_8888); int rowBytes = bmp.getRowBytes(); bmp = null; if (rowBytes*webView.getHeight()>=getAvailMemory()){ return null; } bmp = Bitmap.createBitmap(webView.getWidth(), webView.getHeight(), Bitmap.Config.ARGB_8888); Canvas canvas = new Canvas(bmp); webView.draw(canvas); return bmp; } private long getAvailMemory() { return Runtime.getRuntime().maxMemory(); }
这里需要对保存的图片大小做判断,防止创建过大的OOM图片。
至此,基本功能已经实现。把照片分享给你的朋友~
项目地址:
欢迎star,问题~