getElementsByClassName не работает в VBS

У меня есть сценарий VBS в HTA, который должен проверять учетные данные для входа из формы входа HTA, пытаясь войти на внешнюю веб-страницу с теми же учетными данными. "getElementsByClassName", похоже, не работает, потому что каждый раз, когда я запускаю скрипт, он выдает:

Объект не поддерживает это свойство или метод: 'IE.Document.getElementsByClassName(...). InnerHTML'

Этот сценарий должен открывать страницу входа в IE, вводить учетные данные для входа и проверять сообщение об ошибке. Сообщение об ошибке появляется на странице, если учетные данные неверны, и имеет класс "alert alert-error".

<script language="vbscript">

Set IE = CreateObject("InternetExplorer.application")
IE.Visible = True
IE.navigate "https://www.mypage.com/login"

Do Until IE.ReadyState = 4
wscript.sleep 200
Loop

IE.Document.All.Item("username").Value = "loginUsername"
IE.Document.All.Item("password").Value = "loginPassword"
IE.Document.All.Item("submit").Click

Do Until IE.ReadyState = 4
wscript.sleep 200
Loop

set error = IE.Document.getElementsByClassName("alert alert-error").innerHTML
if error="" then
X=MsgBox("You have successfully been logged in!")
else
X=MsgBox("An error occured, you are not logged in.")
end if

</script>

Я надеюсь, что этой информации достаточно для решения проблемы. Спасибо!

1 ответ

Прежде всего, getElementsByClassName() возвращает коллекцию объектов-элементов указанного className, это не один объект. Итак, утверждение getElementsByClassName("alert alert-error").innerHTML является недействительным и приведет к ошибке.

Вам нужно будет перечислить коллекцию для нацеливания объектов внутри нее способом, подобным следующему:

var colAlertErrorElements = IE.Document.getElementsByClassName("alert alert-error");

for (var i=0; i<colAlertErrorElements.length; i++) {
    var objErrorElement = colAlertErrorElements[i];
    if (objErrorElement.innerHTML == "') {
        // no error
    }
    else {
        // error
    }
}

Вы должны написать свой собственный fnc, он не встроен в объект DOM. Я в основном перевожу старый JavaScript fnc, написанный несколько лет назад, для административного управления через Интернет. DOM предоставляет те же функции, независимо от языка, запрашивающего его (js, vbs и т. Д.).

Я включаю fnc GetParentTagName, чтобы пропустить поиск из основного документа (быстрее). Обратитесь к fnc "GetElementsByClass" за основным скриптом. Вы можете настроить более общее, например, поиск любого имени атрибута, а не только атрибута класса.

Вот код (HTML ex + VBS для HTA):

HTML code
=========
<table name="product_not_approve">
    <tbody name="cieA" >
        <tr class="tr_205F51AF-4245-4258-96A3-76DC13B978BB">
            <td fieldname="checkbox_delete">
                <input type="checkbox" name="delete_opt_cieA" value="205F51AF-4245-4258-96A3-76DC13B978BB" />
            </td>
        </tr>
    </tbody>
    <tfoot>
        <tr>
            <td>
                <a href="#" onclick="Admin_Accept_Save_Change me">Make change</a>
            </td>
        </tr>
    </tfoot>
</table>

VBS code
' =================================================================
Sub Admin_Accept_Save_Change(this)

    'msgbox this = window.event.srcElement
    'msgbox this.outerHTML

    Dim oEleParent : Set oEleParent = GetParentTagName(this, "table")
    'msgbox oEleParent.tagName & " - " & oEleParent.outerHTML

    ' Fnc GetElementsByClass((searchClass, node, tag)) return a dictionary object, node can be null, search from DOM body
    Dim oEles : Set oEles = GetElementsByClass("tr_" & "205F51AF-4245-4258-96A3-76DC13B978BB", oEleParent, "tr")
    Dim oEle

    For i = 0 To oEles.Count - 1
        'msgbox oEles.Keys()(i) & ", " & TypeName(oEles.Items()(i))
        Set oEle = oEles.Items()(i)
        msgbox oEle.outerHTML
    Next

    ' Cancel href event
    window.event.returnValue = False

End Sub


' =================================================================
Function GetParentTagName(oEle, tagName)

    Dim oParent : Set oParent = oEle.parentNode ' oEle.parentElement.outerHTML

    Do While UCase(oParent.tagName) <> UCase(tagName)
        Set oParent = oParent.parentNode

        If UCase(oParent.tagName) = "BODY" Then
            Set oParent = Nothing
            Exit Do
        End If
    Loop  

    Set GetParentTagName = oParent

End Function


' =================================================================
Function GetElementsByClass(searchClass, node, tag)

    If IsNull(node) Then Set node = document
    If IsNull(tag) Or tag = "" Then tag = "*"

    Dim oElements : Set oElements = node.getElementsByTagName(tag)
    Dim oDic : Set oDic = CreateObject("Scripting.Dictionary")
    oDic.CompareMode = vbTextCompare

    ' msgbox "typename node = " & TypeName(node) & vbCrLf & _
           ' "tag = " & tag & vbCrLf & _
           ' "searchClass = " & searchClass & vbCrLf & _
           ' "nb of ele found = " & oElements.length

    Dim i : i = 0
    Dim oEle, oAtt

    Do While i < oElements.length
        Set oEle = oElements(i)
        Set oAtt = oEle.Attributes.getNamedItem("class") ' Return a DispHTMLDOMAttribute object

        If oAtt.value = searchClass Then
            'msgbox "Found class : " & oAtt.name & " - " & oAtt.value
            oDic.Add oDic.count + 1, oEle
        End If

        i = i + 1
    Loop

    'msgbox "Nb of DOM element found : " & oDic.Count
    Set GetElementsByClass = oDic

End Function
Другие вопросы по тегам