美文网首页Android开发经验谈程序员今日看点
Android WebView修改加载页面的DOM结构

Android WebView修改加载页面的DOM结构

作者: 小李子吃苹果 | 来源:发表于2017-01-07 18:18 被阅读0次

    最近做一款工具类app,要加入一个简单的搜索功能,为用户提供便利。

    那有何难?直接用WebView加载一下百度和Google的搜索链接不就完了嘛...
    经过分析,百度的搜索url是https://www.baidu.com/s?wd=keyword,Google的搜索url是https://www.google.com/search?q=keyword。身在天朝,先拿百度做个试验吧~

    嗖嗖嗖代码出来了,最简单的WebView使用

    private static final String BAIDU_SEARCH_URL = "https://www.baidu.com/s?wd=webtest";
    private WebView mWebView;
    
    @Override
    protected void onCreate(Bundle savedInstanceState) {    
      super.onCreate(savedInstanceState);    
      mWebView = new WebView(this);    
      setContentView(mWebView);    
    
      mWebView.loadUrl(BAIDU_SEARCH_URL);
    }
    

    结果上个图,恩,完美盗用了百度的成果


    加载百度搜索结果

    这时候,万恶的pm跳出来了,“咱们能把百度的脑袋砍了吗?”......OK,我懂你兄弟

    砍Baidu的脑袋

    虽然我也不知道这么做是否侵犯了百度的利益,但是既然pm提出来了,咱们也得给他实现不是。经过一番调查,最后确定了如下方案:

    • 加载百度页面
    • 加载完成的回调中,向页面注入JavaScript代码
    • JavaScript代码将配置的dom元素移除

    关键点就是怎么判断页面加载完成以及如何注入砍脑袋的JavaScript代码。

    WebView有个回调类叫WebChromeClient,它里面有个onProgressChanged(WebView view, int newProgress)的回调方法,每当dom树的加载进度变化时,就通知给我们的app。所以,我们可以近似地认为回调进度是100时就是页面加载完成的时刻。

    那怎么确定需要删除的dom元素id呢?我们可以到Chrome的开发者工具找到百度脑袋的dom元素id,如下图所示

    找百度脑袋的id

    好了,万事俱备,上代码

    // 需要隐藏的dom元素id
    private static final String[] HIDE_DOM_IDS = {"page-hd", "page-tips"};
    
    // 定义WebChromeClient
    private WebChromeClient mSearchChromeClient = new WebChromeClient() {  
      @Override    
      public void onProgressChanged(WebView view, int newProgress) {  
        Log.d(SEARCH_TAG, "on page progress changed and progress is " + newProgress);        
        // 进度是100就代表dom树加载完成了
        if (newProgress == 100) {            
          mWebView.loadUrl(getDomOperationStatements(HIDE_DOM_IDS));        
        }    
      }
    };
    
    mWebView.setWebChromeClient(mSearchChromeClient);
    
    public static String getDomOperationStatements(String[] hideDomIds) {   
      StringBuilder builder = new StringBuilder();    
      // add javascript prefix    
      builder.append("javascript:(function() { ");   
      for (String domId : hideDomIds) {        
        builder.append("var item = document.getElementById('").append(domId).append("');");        
        builder.append("item.parentNode.removeChild(item);");    
      }    
      // add javascript suffix    
      builder.append("})()");    
      return builder.toString();
    }
    
    final.gif

    可以看到百度脑袋一闪而过,被切掉了。闪这一下倒是比较容易解决,可以通过先mWebView.setVisibility(View.INVISIBLE),执行JavaScript代码1s后再mWebView.setVisibility(View.VISIBLE)解决,就不再赘述了。

    总结:虽然这个场景实用性不强,但可权且当做WebView操作页面元素的一个例子,提供一种自定义WebView的思路。

    相关文章

      网友评论

        本文标题:Android WebView修改加载页面的DOM结构

        本文链接:https://www.haomeiwen.com/subject/cyvxbttx.html