不好意思没积分。我觉得这个问题比较有代表性,也算不仅为自己问了吧,希望好心的高手帮忙。
现在的问题是,当我用IHTMLElement3的FireEvent("onchange")之后,怎么才能判断它运行完毕呢?
我试着去分析WebBrowser的事件,以及用Sleep等,都不能保证页面上JavaScript的onchange事件执行完毕。如果没有执行,那么下级菜单项的内容就不正确。

解决方案 »

  1.   

    通过事件呗,下面是一个典型的列表选择代码:
    Option Explicit
    Private WithEvents ctl00_ContentPlaceHolder1_DropDownList城市 As HTMLSelectElement
    Private WithEvents ctl00_ContentPlaceHolder1_DropDownList区域 As HTMLSelectElement
    Private WithEvents ctl00_ContentPlaceHolder1_DropDownList片区 As HTMLSelectElementPrivate Sub ctl00_ContentPlaceHolder1_DropDownList城市_onchange()
        ctl00_ContentPlaceHolder1_DropDownList区域.Value = "青秀区"
        ctl00_ContentPlaceHolder1_DropDownList区域.FireEvent "onchange"
    End SubPrivate Sub ctl00_ContentPlaceHolder1_DropDownList区域_onchange()
        ctl00_ContentPlaceHolder1_DropDownList片区.Value = "柳沙"
        ctl00_ContentPlaceHolder1_DropDownList片区.FireEvent "onchange"
    End SubPrivate Sub ctl00_ContentPlaceHolder1_DropDownList片区_onchange()
        '提交
    End SubPrivate Sub Form_Load()
        WebBrowser1.Navigate2 "http://house.gxsky.com/intermediary/ChuShou.aspx?type=n"
    End SubPrivate Sub WebBrowser1_DocumentComplete(ByVal pDisp As Object, URL As Variant)
        Dim oDoc As HTMLDocument
        Set oDoc = pDisp.Document
        
        With oDoc
            Set ctl00_ContentPlaceHolder1_DropDownList城市 = .getElementById("ctl00_ContentPlaceHolder1_DropDownList城市")
            Set ctl00_ContentPlaceHolder1_DropDownList区域 = .getElementById("ctl00_ContentPlaceHolder1_DropDownList区域")
            Set ctl00_ContentPlaceHolder1_DropDownList片区 = .getElementById("ctl00_ContentPlaceHolder1_DropDownList片区")
            
            ctl00_ContentPlaceHolder1_DropDownList城市.Value = "南宁市"
            ctl00_ContentPlaceHolder1_DropDownList城市.FireEvent "onchange"
        End With
        
    End Sub
      

  2.   

    我怎么忘了html元素对象也有事件,天呐.那时候竟然傻乎乎的EleSele.OnChange=xx
    ...-_-!
      

  3.   

      首先感谢一下绿豆的解答。我现在已经解决了,而且问题出在调用onchange上。
      我有个四级联动菜单,一级是省,二级是市,三级是市内的支行,四级是支行下的网点(储蓄所),所以是逐级动态加载的。而我要做的是遍历所有的选项,因此放了4个IHTMLSelectElement对象,做循环。在上级的更改选项后执行其onchange代码,并且一定要等其加载完毕,下一级的遍历才正确。当每次从服务器端发送页面请求后,DocumentCompleted重入的次数(通常是固定的,可以自己用个计数变量分析),可以成为加载完毕的判断条件,这比从其他HTML内容分析,方便而准确得多。
      最终问题还是我在一家英文网站上查出来的,当然没有仔细看,也没接着试验。网页上的内容大致为:<select id="Branch1" onchange="xxx(this.name,this.value,'x','null')>,这段代码响应正常的onchange事件没问题,但当我从WebBrowser中发出FireEvent("onchange")时,就出问题了。它应该是被执行了(我试过小改动一下onchange为onchang,或加上一对空括号,会报错),但是问题就出在this.name和this.value上,FireEvent导致的this是谁?JavaScript是动态语言,名字直接用字串拼出来,再发给它,很有eval的效果。但这个this会不会变成了WebBrowser或HTML库的某个对象呢?因为它是正常的对象,所以代码也正常执行,但效果就没有加载成功。于是,换掉FireEvent("onchange"),改用doc.parentWindow.execScript。我把this.name,this.value处,直接用SelectElement的.name和.value,拼接上,结果还是报错。再改成了document.all.Branch1.name,document.all.Branch1.value,程序正常了。具体代码是:
    Call doc.parentWindow.execScript("xxx(document.all.Branch1.name,document.all.Branch1.value,'x','null'),"JavaScript") 'VB
    Do While lCount<2
      DoEvents
    Loop
    结果OK!
      

  4.   

    补充一下,今天又试出一种,通过Call doc.all.Branch1.onchange也可以。
    由于对DOM不熟,则用Dim doc As Object能调用所有接口,缺点就是没有方法属性列表。