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