Android、iOS的webview注入JavaScript代码修改网页内容
需要修改webview中的网页内容、网页元素动作
1.实现原理
webview导航栏方法中执行JavaScript代码
浏览器地址栏是支持运行JavaScript代码的
javascript:开头后跟要执行的语句
// 弹窗
javascript:alert('hello world!');
ps:不可以复制粘贴的方式来测试,这样是无效的,至少“javascript:”是手写补全才可以
那么webview是否也可以呢?
在webview中同样适用本方法
虽然webview没有可见的地址栏,但是webview提供操作导航导航栏的方法
2.常用JavaScript代码片段
// 通过class查找隐藏本element
javascript:(function() {
document.getElementsByClassName('your_class_name')[0].style.display='none';
})();
// 通过id查找因此本element
javascript:(function() {
document.getElementById('your_id').style.display='none';
})();
// 某个element点击事件 并且修改打开一个弹窗后的页面element
javascript:(function() {
// 首次页面加载必须有的element
var url = 'https://www.baidu.com';
var text = 'p标签文本被替换了';
var bottom = document.getElementsByClassName('bottom')[0];
bottom.onclick = function(){
// 弹窗element
var dialogButton = document.getElementsByClassName('button')[0];
var dialogItem = document.getElementsByClassName('item')[2].getElementsByTagName('p')[1];
dialogButton.onclick = function(){window.open(url, '_self');}; // 点击事件跳转
dialogItem.replaceWith(text); // 修改标签文本内容
};
})();
// 如果某些页面元素是在页面完成后出现的
// 也就是webview 到了 onPageFinished 周期中,页面元素还未加载出来,需要使用定时器来处理
// 定时器轮询检查页面元素对象,直到找到需要的处理的页面元素对象后进行处理,然后销毁定时器
var timer = setInterval(function () {
if (document.getElementsByClassName("class name")[0]) {
// 你的业务代码
clearInterval(timer); // 销毁定时器
}
}, 1000);
3.Android中实现webview注入JavaScript代码
// java
final WebView webview = (WebView)findViewById(R.id.browser);
webview.getSettings().setJavaScriptEnabled(true);
webview.setWebViewClient(new WebViewClient() {
@Override
public void onPageFinished(WebView view, String url)
{
// hide element by class name
webview.loadUrl("javascript:(function() { " +
"document.getElementsByClassName('your_class_name')[0].style.display='none'; })();");
// hide element by id
webview.loadUrl("javascript:(function() { " +
"document.getElementById('your_id_name').style.display='none';})();");
}
});
webview.loadUrl(url);
4.iOS中实现webview注入JavaScript代码
// objective-c
5.Flutter中实现webview注入JavaScript代码
参考 Android 和 iOS
6.进阶注入外部引入的hook.js代码
注入的JavaScript代码需要修改重新发包?
注入的JavaScript很大一段硬编码到APP包中如何管理?
进阶实现注入外部hook.js
把JavaScript代码单独写在hook.js并放置在cdn上
// https://www.iamle.com/hook.js
'v0.0.1 app webview hook'
;(function (window) {
//your code
})(window)
// app 用webview.loadUrl方法中注入js
javascript:(function() {
var script = document.createElement('script');
script.type = 'text/javascript';
script.src = 'https://www.iamle.com/hook.js';
document.body.appendChild(script);
})();
// Android java为例
@Override
public void onPageFinished(WebView view, String url)
{
String js = "javascript:(function() {";
js += "var script = document.createElement('script');";
js += "script.type = 'text/javascript';";
js += "script.src = 'https://www.iamle.com/hook.js';";
js += "document.body.appendChild(script);";
js += "})();";
view.loadUrl(js);
}
这样后续修改只需要修改hook.js即可,APP不用重新打包📦
7.经验
在webview中不支持window.location.href进行网址导航
但是支持使用window.open, window.open(‘https://www.iamle.com‘, ‘_self’);