ContentLoading
请拷贝示例文件"CaseStudy\WebViewer\简单浏览器.Table",然后基于新文件测试本节示例代码,避免被不相干的代码干扰。
ContentLoading在开始解析DOM前执行,可以在ContentLoading事件运行js代码,或注入css样式和js函数。
e参数属性:
| 属性名 | 类型 | 说明 |
|---|---|---|
| NavigationId | ULong | 本次导航的唯一ID(也就是框架ID,用于关联后续事件) |
| IsErrorPage | Boolean | 是否是错误页面(404、500 等浏览器内置错误页面) |
提示:
1、由于ContentLoading事件触发时DOM还没有生成,所以在此事件运行的js脚本,不能有操作DOM的代码,但可以注入操作DOM的函数。
2、如果要直接运行操作DOM的代码,请改在NavigationCompleted 或 DOMContentLoaded事件运行。
示例一
例如将ContentLoading事件代码设置为:
'定义JS代码
Dim
jsCode
As
String
=
<![CDATA[
//直接运行代码
alert('页面正在加载!');
//定义变量
window.Foxtable = 'Hello from Foxtable!';
window.Issue =
"开发版
2026";
//
定义函数(不依赖DOM)
window.testFunc1 = function(text) {
alert('【FoxTable注入函数】'
+ text);
};
// 定义函数(依赖DOM,需在DOM就绪后才能调用)
window.testFunc2 = function(message) {
if (!document.body) {
alert('DOM尚未就绪,无法插入元素!');
return;
}
var div = document.createElement('div');
div.style.cssText = 'padding:10px; background:#e6f7ff;
border-left:4px solid #1890ff; margin:10px 0;';
div.innerText
= '[Foxtable
注入]
' + (message || 'Hello from Foxtable!');
document.body.appendChild(div);
};
//
定义有返回值函数
window.calcSum = function(a, b) { return a + b; };
]]>.Value
e.Sender.WebViewer.ExecuteScriptAsync(jsCode)
'运行JS代码
测试js代码
上面在ContentLoading事件通过注入js代码,添加了三个函数和两个变量,我们可以通过以下方法测试js代码。
1、打开窗口后,按F12,打开浏览器的开发者模式,在控制台运行:
window.testFunc1('Foxtable 2026');
或输入js变量名,例如:
Foxtable
2、你可以在Foxtable端运行JS代码,例如插入一个按钮,按钮代码设置为:
Dim
wv
As
WebViewer = e.Form.Controls("WebViewer1").WebViewer
wv.ExecuteScriptAsync("window.testFunc2('Foxtable
2026');")
获得js返回值
ExecuteScriptAsync是异步执行的,如果js函数带有返回值,必须加上Await才能获得返回值。
例如调用上面插入的calcSum函数计算两数之和:
'''Async
Dim
wv
As
WebViewer = e.Form.Controls("WebViewer1").WebViewer
Dim
result
As
String
=
Await
wv.ExecuteScriptAsync("calcSum(100,200);")
'不要漏掉Await
Dim
Val
As
Integer
If
Integer.TryParse(result,
val)
Then
MessageBox.Show("计算结果:"
& val)
End
If
获得变量值也要加上Await:
'''Async
Dim
wv
As
WebViewer = e.Form.Controls("WebViewer1").WebViewer
Dim
result
As
String
=
Await
wv.ExecuteScriptAsync("Issue;")
'不要漏掉Await
MessageBox.Show("Issue值:"
& result)
总之只要获得值,就必须用Await,当然第一行必须是注释标记'''Async,否则无法通过编译。
示例二
前面说过ContentLoading触发时,DOM还没有生成,不要有操作DOM的代码。
实际测试表明,此事件触发时,顶层的Document其实已经生成,只是DOM元素还没有解析生成。
所以我们通过这个事件提前注入非脚本内容(一般是css样式)。
例如我们将ContentLoading改为:
Dim
jsCode
As
String
=
<![CDATA[
(function() {
var style = document.createElement('style');
style.textContent =
`body
{ background-color: #f0f8ff !important; }
#ad-banner, .advertisement { display: none !important; }
h1 { color: red; font-family: 'Arial'; }`;
document.head.appendChild(style);
})();
]]>.Value
e.Sender.WebViewer.ExecuteScriptAsync(jsCode)
'运行JS代码
提醒:代码中红色的两个符号是反引号,不能是双引号或单引号,因为只有反引号才能跨越多行。
上面的代码插入了一段css,实现背景变浅蓝,标题变红,广告元素被隐藏:
