【问题标题】:VBA : access an element inside a div loaded with AngularJSVBA:访问加载了 AngularJS 的 div 中的元素
【发布时间】:2016-10-03 21:59:06
【问题描述】:

我卡住了,在 VBA 中我想访问使用 AngularJS 的页面上的 HTML 元素,

所有这些元素“存在”,因为我在使用 IE 调试器工具时看到了它们。它们都在一个名为“cont”的父 div 中。

问题:

当我查看网站的源代码时,这个 div 是空的。我只能看到结构,即:

 <div 
        class="cont"
        data-ng-controller=".."
        ..
        data-ng-init="initApplication()">
</div>

但里面什么都没有。它可能是在 angular 之后加载的。

因此,当我尝试访问此 div 内的按钮时,例如:

Set IE = CreateObject("InternetExplorer.Application")
IE.document.getElementsById("submitBtn").click

然后我收到一条错误消息,指出该对象不存在..

所以我尝试在之前添加:

' wait until IE and the page are ready
Do While .Busy Or Not .readyState = 4: DoEvents: Loop
' wait until the DOM is ready
Do Until .document.readyState = "complete": DoEvents: Loop

但是没有任何效果,我完全不明白,是否可以访问此 div 中的 HTML 元素?为什么我在调试器工具中看到 evthg?

有什么想法吗??


更新

我发现 div 的内容位于一个 .js 文件中,那里有数百万个东西但是有:

angular.module("cont").factory("applicationService",["$rootScope","ngDialog","webService",
function(a,b,c){
    "use strict";
     var d={},
     e="home";
     d.initApplication=function(){
          return c.initContact()
     }

还有:

angular.module("cont").run(["$templateCache",function(a){"use     strict";
a.put("Application",'ALL THE CONTENT IS HERE (with an HTLM element I would like to click)!!!!!'

【问题讨论】:

  • 您需要展示更多现有代码 - 这两行并没有告诉我们太多信息。如果元素出现在 Ceveloper 工具源中,那么您应该能够访问它。还要注意getElementsById 应该是getElementById(没有“s”)
  • 您的按钮在框架中吗?您是否在浏览器的控制台中得到document.getElementsById("submitBtn") 的结果?
  • 没有不在框架中,我在控制台中得到 null
  • @Julient And with document.getElementById("submitBtn") without an "s" or document.querySelector("#submitBtn")?

标签: javascript html angularjs vba automation


【解决方案1】:

源代码中不存在这些元素,因为它们尚未由 javascript 创建。您可以通过 F12 看到它们,因为当您在页面上使用调试器工具时,javascript 已经运行并创建了元素。

考虑一下这个javascript sn-p:

var btn = document.createElement("BUTTON");

在 javascript 运行之前,该页面不会有按钮。代码运行后,元素存在并且您将能够与其交互。我怀疑您的代码试图获取submitBtn 是在创建该按钮的javascript 运行之前运行的。

没有看到创建按钮的脚本,我最好的建议是像你已经做的那样Do While .Busy Or Not .readyState = 4: DoEvents: Loop,然后像这样开始测试按钮的存在(诚然不雅的方法):

'Declare Sleep at the top of you code module
Public Declare Sub Sleep Lib "kernel32" (ByVal dwMilliseconds as Long)

Sub mySub()
    Dim objButton as Object
    'Code creating nd automating IE here
    Do While .Busy Or Not .readyState = 4: DoEvents: Loop
    'May possibly need On Error Resume Next here
:TryAgain
    Set objButton = IE.document.getElementsById("submitBtn")
    If objButton Is Nothing Then 
        Sleep 1000 'Wait for 1 second
        GoTo TryAgain
    End If
    'On Error GoTo 0 if you needed resume next
    'At this point objButton is something, so let's try clicking it
    objButton.Click
End Sub

不幸的是,当 javascript 运行时没有触发事件,所以我们几乎必须等待它完成。

如果除非您执行某些操作(例如,单击、移动鼠标​​、按键等),否则 javascript 不会运行,您可以使用.execScript 强制脚本无规则运行。有关更多信息,请参阅此 SO 帖子:How to call javascript function in VBA

【讨论】:

  • 再次感谢蒂姆,是的,你是对的,它可能还不是由 javascript 创建的,所以我尝试进入睡眠状态,但在 Tryagain 之后出现“object require”错误,即按钮已设置..
  • 是的,抱歉,我没有测试代码。我不确定尝试使用不存在的元素设置对象是否会导致 Object Required 错误或空对象。添加(或编辑和取消注释)On Error 行,它应该继续。它仍然可能不起作用,因为我不确定是什么导致 javascript 运行并创建按钮(希望它的 OnLoad 事件!):D
  • 是的,不行,我也试过睡10秒,一样,grr
  • 只是为了验证一下,您创建的 IE 实例是可见的,对吗? IE 和 JS 以在窗口隐藏或最小化时不执行任何操作或触发事件而著称。您可能想要调查创建按钮的脚本并使用execScript 强制它运行。使用动态创建的元素自动化 IE 是一件痛苦的事情。 :P 给这只猫剥皮的另一种潜在方法是create your own POST 然后你就不必费力地点击一个不存在的按钮了。
  • 我觉得我觉得这很有趣,确实你是对的,div 内容是由 angular 加载的,我在一个 js 文件中找到了它,我用我在那里找到的内容更新了问题.. 确实所有这个 div 内容!
猜你喜欢
  • 2019-09-24
  • 1970-01-01
  • 2014-09-15
  • 1970-01-01
  • 2021-04-05
  • 2013-03-03
  • 2012-09-07
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多