最近做一款工具類app,要加入一個簡單的搜索功能,為用戶提供便利。
那有何難?直接用WebView加載一下百度和Google的搜索鏈接不就完了嘛...
經(jīng)過分析,百度的搜索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);
}
結(jié)果上個圖,恩,完美盜用了百度的成果
這時候,萬惡的pm跳出來了,“咱們能把百度的腦袋砍了嗎?”......OK,我懂你兄弟
雖然我也不知道這么做是否侵犯了百度的利益,但是既然pm提出來了,咱們也得給他實現(xiàn)不是。經(jīng)過一番調(diào)查,最后確定了如下方案:
- 加載百度頁面
- 加載完成的回調(diào)中,向頁面注入JavaScript代碼
- JavaScript代碼將配置的dom元素移除
關(guān)鍵點就是怎么判斷頁面加載完成以及如何注入砍腦袋的JavaScript代碼。
WebView有個回調(diào)類叫WebChromeClient,它里面有個onProgressChanged(WebView view, int newProgress)
的回調(diào)方法,每當dom樹的加載進度變化時,就通知給我們的app。所以,我們可以近似地認為回調(diào)進度是100時就是頁面加載完成的時刻。
那怎么確定需要刪除的dom元素id呢?我們可以到Chrome的開發(fā)者工具找到百度腦袋的dom元素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();
}
可以看到百度腦袋一閃而過,被切掉了。閃這一下倒是比較容易解決,可以通過先mWebView.setVisibility(View.INVISIBLE)
,執(zhí)行JavaScript代碼1s后再mWebView.setVisibility(View.VISIBLE)
解決,就不再贅述了。
總結(jié):雖然這個場景實用性不強,但可權(quán)且當做WebView操作頁面元素的一個例子,提供一種自定義WebView的思路。