添加链接
link之家
链接快照平台
  • 输入网页链接,自动生成快照
  • 标签化管理网页链接

产品有个需求,要在App中打开天猫购物的链接,并且要隐藏掉H5页面的某些内容,让用户只能浏览商品,而不能购买,这个就需要在Java代码中操作WebView,让H5页面加载完成后能够隐藏掉某些内容。

首先我们来看一下天猫购物的链接地址: https://market.m.taobao.com/apps/market/need/yxIndex.html ,使用WebView打开后页面如下:

这个页面是让用户选择商品的界面,不需要修改,点击某个商品,进入商品详情页面:


需要隐藏的就是这个页面的底部栏,这样用户就只能看商品信息而不能操作该商品了,现在我们分析一下思路,是否可以等页面加载完成后,执行Js代码,找到底部栏并将其隐藏呢?这个是最直接的思路,下面我们就按照这个思路分析,按照这种思路要解决几个问题:

1、需要知道何时页面加载完成了;

2、需要知道如何在Java代码中执行Js代码;

3、需要知道如何利用Js代码找到页面中的底部栏并将其隐藏。

解决了上面三个问题,问题也就基本解决了。首先我们来看一下第一个问题,如何监听WebView加载页面完成了。

1、监听页面加载完成

一般的,我们可以给WebView设置WebViewClient,在WebViewClient的onPageFinished方法中监听页面加载完成。代码如下:

        mWebView.setWebViewClient(new WebViewClient() {
            @Override
            public void onPageFinished(WebView view, String url) {
                super.onPageFinished(view, url);
                // 页面加载完成

2、在Java代码中执行Js代码

我们可以使用WebView提供的loadUrl(String)方法来让Java代码执行Js代码,格式如下:

        //定义javaScript方法
        String javascript = "javascript:function hideBottom() { "
                + "}";
        //加载方法
        mWebView.loadUrl(javascript);
        //执行方法
        mWebView.loadUrl("javascript:hideBottom();");

上面的代码中,我们首先定义了一个js方法hideBottom,然后调用WebView的loadUrl加载该方法,最后再执行该方法即可。

3、在页面中找到底部栏并将其隐藏

在H5页面中找到某个元素还是有很多方法的,比如getElementById()、getElementsByClassName()、getElementsByTagName()等,具体根据页面来选择,我们先在浏览器中查看页面源码,找到底部栏,然后在确定使用哪种方式获得底部栏,在chrome浏览器中点击一个商品查看详情,按F12进入开发者模式调试页面:

点击最左边按钮

这样,当鼠标在页面中移动到了某个元素时,右边会显示出对应的代码,我们找到了底部栏对应的源码如下:

可以看到其并没有设置id,而是设置了class,所以这里我们通过getElementsByClassName()找到底部栏元素,我们可以在浏览器里面调试一下,看能不能找到底部栏并隐藏。我们切换到Console栏,输入如下代码并执行:

document.getElementsByClassName('weex-div weex-ct bpu_bottom_toolbar weex-fixed')[0].style.display='none'

发现页面中的底部栏被隐藏掉了

上面Js的代码,首先通过getElementByClassName方法找到'class'为'weex-div weex-ct bpu_bottom_toolbar weex-fixed'的所有元素,返回的是一个数组,在这个页面中,只有底部栏的'class'为'weex-div weex-ct bpu_bottom_toolbar weex-fixed',所以取数组中的第一个元素对应的就是底部栏元素,然后将底部栏的display属性设置为'none',表示底部栏不显示,这样就可以将底部栏隐藏了。

4、代码编程尝试

根据上面的思路,我们很容易写出如下代码:

        mWebView.setWebViewClient(new WebViewClient() {
            @Override
            public void onPageFinished(WebView view, String url) {
                super.onPageFinished(view, url);
                // 页面加载完成
                hideBottom(); // 执行隐藏底部栏方法
        // 隐藏底部栏方法
        private void hideBottom() {
            try {
                //定义javaScript方法
                String javascript = "javascript:function hideBottom() { "
                        + "document.getElementsByClassName('weex-div weex-ct bpu_bottom_toolbar weex-fixed')[0].style.display='none'"
                        + "}";
                //加载方法
                mWebView.loadUrl(javascript);
                //执行方法
                mWebView.loadUrl("javascript:hideBottom();");
            } catch (Exception e) {
                e.printStackTrace();

编译运行,发现底部栏并没有隐藏,但是在浏览器中我们明明是可以隐藏底部栏的,到底是哪里出了问题呢?看来只能调试了,在Android中可以打印出Js输出的日志,我们通过日志来查看程序的运行情况,在js代码中加入日志:

        String javascript = "javascript:function hideBottom() { "
            + "console.log('hide bottom');"  // 看方法是否执行
            + "console.log(document.getElementsByClassName('weex-div weex-ct bpu_bottom_toolbar weex-fixed').length);" // 打印出数组的长度
            + "document.getElementsByClassName('weex-div weex-ct bpu_bottom_toolbar weex-fixed')[0].style.display='none'"
            + "}";

然后加入如下代码:

        mWebView.setWebChromeClient(new WebChromeClient() {
            public boolean onConsoleMessage(ConsoleMessage cm) {
                Log.i("liunianprint:", "js console log: " + cm.message()); // cm.message()为js日志
                return true;

打开商品详情页面,日志如下:

12-14 15:59:16.386 22315-22315/com.liunian.androidbasic I/liunianprint:: js console log: hide bottom
    js console log: 0

可以看到,js方法是有被执行到的,只是通过

document.getElementsByClassName('weex-div weex-ct bpu_bottom_toolbar weex-fixed')

没有获得到页面中class为'weex-div weex-ct bpu_bottom_toolbar weex-fixed'的元素,返回的数组为空。

为什么会出现这种问题呢?我们可以看到,当日志打印出来的时候,页面其实还没有显示,所以就会导致找不到底部栏元素,也就是说在

onPageFinished调用后,其实页面还没有显示完全,导致从页面中找不到底部元素,根据我的观察,onPageFinished的调用时机一直是一个迷,并且在不同的系统版本和浏览器内核中有不同的表现,也有可能onPageFinished的调用时机是页面下载完成,并没有显示,总之,我们不能在onPageFinished中处理隐藏底部栏的操作。那么,有什么办法能够知道H5页面何时显示完成呢?我们不妨换个思路,是不是可以监听WebView的onDraw方法,onDraw方法,每当WebView需要重绘时都会调用,那么当H5页面显示完成后,肯定会调用该方法,我们可以在onDraw方法调用后在调用隐藏底部栏的方法,那样底部栏应该会隐藏,废话不多说,直接上代码:

public class MyWebView extends WebView {
    public MyWebView(Context context) {
        super(context);
    public MyWebView(Context context, AttributeSet attrs) {
        super(context, attrs);
    public MyWebView(Context context, AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);
    @Override
    protected void onDraw(Canvas canvas) {
        super.onDraw(canvas);
        if (mOnDrawListener != null) {
            mOnDrawListener.onDrawCallBack();
    private OnDrawListener mOnDrawListener;
    public void setOnDrawListener(OnDrawListener onDrawListener) {
        mOnDrawListener = onDrawListener;
    public interface OnDrawListener {
        public void onDrawCallBack();
        mWebView.setOnDrawListener(new MyWebView.OnDrawListener() {
            @Override
            public void onDrawCallBack() {
                hideBottom();

运行程序,底部栏被成功隐藏掉了:

这种方式,hideBottom方法会被调用了多次,经过我的观察,对性能的影响不大,暂时不优化了。

      通过这篇文章,我们可以学到以下几个方面的知识:

      1、如何在Java代码中执行Js代码;

      2、如何分析H5页面并准确的找到其中的某个元素;

      3、如何在Java代码中调试Js代码,并成功打印出Js的log;

      4、onPageFinished是不可靠的,它的调用时机不可控,为了监控H5页面的显示,我们采用了监控WebView的onDraw方法的方式。

      现在前端开发中已经越来越多的使用到了H5页面,主要是因为H5页面可以及时更新、开发速度快、跨平台等特点,在Android中,我们一般使用WebView来显示H5页面,Android自带的WebView还是有很多坑的,比如内存泄露、版本的兼容、onPageFinished的调用时机等等,我们需要小心的处理这些问题。

一、说明       产品有个需求,要在App中打开天猫购物的链接,并且要隐藏掉H5页面的某些内容,让用户只能浏览商品,而不能购买,这个就需要在Java代码中操作WebView,让H5页面加载完成后能够隐藏掉某些内容。二、分析      首先我们来看一下天猫购物的链接地址:https://market.m.taobao.com/apps/market/need/yxIndex.html... <html language="en-us"> <meta http-equiv="Content-Type" content="text/html; charset=utf-8" /> <title>Show And Hidden Demo</title>
什么是WebView WebViewAndroid中UI组件的一种,WebView基于webkit内核,不过由于兼容性的原因在Android5.0后改为了Chromium内核。 WebView可以用来展示网页,常用于我们不想打开浏览器但又想浏览网页的情况。 WebView的使用 WebVeiw的常用方法 加载网页的四种方式 loadUrl(String url) //打开百度网页 webView.loadUrl("https://www.baidu.com/"); //打开sdcard卡的html页
之前转载过Android webview相关的文章,Android Webview开发问题及优化汇总,这里讲解一下实现Webview缩放以及隐藏缩放控制条所遇到的问题和坑 要支持缩放,肯定要先支持
h5加载完成时回调 override fun onPageFinished(view: WebView?, url: String?) { super.onPageFinished(view, url) view?.loadUrl("javascript:" + loadJs() + ";") fun loadJs(): String { var js = "var newscript = document.createElement(\"script\");" 产品突然提出个需求,想去掉一个H5页面中的一段文案,避免用户点击创建新账户,如下图。这个H5页面不是我们自己写的,要不然在H5中添加一个去掉这段文案的方法,在native这边直接调用这个方法就OK了,但是这个H5页面是别人的,怎么处理呢? webview不仅可以加载网页,同时网页的任何元素我们都是可以修改的。例如隐藏元素、替换元素、插入新的元素等等。那现在我们要做的就是:在J...
private WebViewClient mWebViewClient = new WebViewClient() { @Override public boolean shouldOverrideUrlLoading(WebView view, String url) { @Override
今天接到一个需求,要求Webview在加载H5的时候需要隐藏标题。刚接到这个任务的时候第一反应是直接让前端人员删除不久行了,然后就去和产品说,经过我的据理力争,我妥协了。唉!移动端不好做啊!!! 算了,既然来需求了,那就撸起袖子干吧! 还好我们公司的前端对于标题使用的是同一个Class(没有使用id) 这样我弱小的心灵也得到了些许安慰。给前端人员点个赞。 1.首先我们要先监听页面加载完成的情况 web_common_layout.setWebViewClient(new MyWebViewCli
在使用Webview嵌入H5页面时,如何实现全屏功能呢?首先需要了解H5的全屏API是通过requestFullScreen()方法实现的,而Webview是通过WebChromeClient类的onShowCustomView和onHideCustomView方法实现的。 具体实现方法如下: 1. 首先在H5页面中添加全屏按钮,点击按钮后调用requestFullScreen()方法实现全屏。 2. 在Android中,使用WebChromeClient类中的onShowCustomView方法将H5页面全屏展示。 3. 在onShowCustomView方法中创建一个全屏的View,将H5页面的View添加到全屏View中,并将全屏View设置为Activity的ContentView。 4. 当退出全屏时,在WebChromeClient类中使用onHideCustomView方法来恢复Activity的ContentView。 总之,通过WebChromeClient类的onShowCustomView和onHideCustomView方法,我们可以实现在Android Webview中让嵌入的H5页面进行全屏显示的功能。