在一个程序中需要判断WebBrowser打开的页面是否加载完成,通常的做完是使用Busy属性,代码如下:while WebBrowser1.Busy doApplication.ProcessMessages;
对于多框架:procedure TForm1.WebBrowser1NavigateComplete2(Sender: TObject;
const pDisp: IDispatch;
var URL: OleVariant);
begin
if CurDispatch = nil then
CurDispatch := pDisp{ save for comparison }//如何判断WebBrowser中的某一个网页显示是否完成 ?
//只有当这个网页显示完成后才能对这个网页上的元素进行操作,否则会出错的!
//OnDocumentComplete事件在网页中含有Frame时就不行了,每个Frame都会产生OnDocumentComplete事件,无法知道什么时候真正完成了
//原理是:第一次产生NavigateComplete2事件和最后一次产生DocumentComplete事件都是顶级(top-level)Frame,
//所以可以通过比较pDisp来判断是否完成。
//Only the final OnDocumentComplete event passes the same Dispatch interface as the OnNavigateComplete event handler.
///这个访问对于访问纯Html的页面时是一点儿问题都没有的,但有些页面在设计时为了不影响打开速度,
//是让html代码优先显示,然后再运行js代码或框架代码,
//由于我要访问的页面中没有调用框架页面,所以没作测试。end;
procedure TForm1.WebBrowser1DocumentComplete(Sender: TObject;
const pDisp: IDispatch;
var URL: OleVariant);
begintry
if (pDisp = CurDispatch) then
if (pDisp =WebBrowser1.Application )then
ifnot(WebBrowser1.Busy)then
begin
//对于含有ajax的页面,很可能没有加载完成。必须在ProgressChange事件中进行判断
//Beep;
{the document is loaded, not just a frame }
if URL <> 'about:blank' then
addtolog('-页面下载成功 : ' + URL) ;
// 保存页面
doDownJob.SaveHTML();
CurDispatch := nil;
{clear the global variable }
end;
except
addtolog('本次页面下载失败: ' + URL) ;
Processurlbegintime := 0;
//
// Processurlstate := '0';
//状态改为0 ,以使下一个URL可以被处理
Processstate := '0';
//处理结束了end;
end;
这个访问对于访问纯Html的页面时是一点儿问题都没有的,但有些页面在设计时为了不影响打开速度,是让html代码优先显示,然后再运行js代码或框架代码,由于我要访问的页面中没有调用框架页面,所以没作测试。经过一夜的摸索,最终找到了解决办法:procedure TForm1.wb1ProgressChange(Sender: TObject;
Progress,
ProgressMax: Integer);
begin
//判断页面及JS是否执行完毕
if ( Progress = 0 ) and ( ProgressMax = 0 ) and
( OldProgress = -1 ) then
begin
IsWebLoadComplete := True;
end;
OldProgress := Progress;
end;
在此之前我对ProgressChange事件参数中的值进行了跟踪,发现当前进度的值和总进度的值相等后并不一定代表页面全部加载完成,但页面在加载完成后,Progress和ProgressMax的后两个值却总是-1/1000000和0/0。Progress的值为-1,有可能是页面全部加载完成了,但也有可能是只加载完了需要访问的其中一个页面文件。经过多次测试,当-1/1000000和0/0接连出现时,就可以保证页面已经全部加载完成了。
【Delphi中WebBrowser判断页面及JS ajax是否加载完成-转】