- c - 在位数组中找到第一个零
- linux - Unix 显示有关匹配两种模式之一的文件的信息
- 正则表达式替换多个文件
- linux - 隐藏来自 xtrace 的命令
我正在尝试为我的程序找到一种方法来了解 WebBrowser 何时在导航,何时不导航。这是因为程序将通过将注入(inject)到文档中的 JavaScript 与加载的文档进行交互。除了处理 Navigating 之外,我没有其他方法知道它何时开始导航。事件不是我的程序,而是将通过与文档交互来导航的用户。但是,当 DocumentCompleted
发生时并不一定意味着它已经完成导航。我一直在谷歌搜索,发现了两个伪解决方案:
检查 WebBrowser 的 ReadyState DocumentCompleted
事件中的属性。这样做的问题是,如果加载的不是文档而是文档中的框架,即使主文档未完成,ReadyState
也将是Completed
。
为了防止这种情况,他们建议查看 Url传递给 DocumentCompleted
的参数与 Url 匹配WebBrowser
的。这样我就知道 DocumentCompleted
没有被文档中的其他框架调用。
问题 2 是,正如我所说,我必须知道页面何时导航的唯一方法是处理 Navigating
(或 Navigated
)事件.因此,例如,如果我在 Google map 中并单击搜索,将调用 Navigating
,但只有一个框架正在导航;不是整个页面(在特定的 Google 案例中,我可以使用 WebBrowserNavigatingEventArgs
的 TargetFrameName
属性来检查它是否是正在导航的框架,但框架不是总是有名字)。所以在那之后,将调用 DocumentCompleted
,但不会使用与我的 WebBrowser
的 Url
属性相同的 Url
因为它只是一个导航的框架,所以我的程序会认为它仍在导航,永远。
添加对 Navigating
的调用和减去对 DocumentCompleted
的调用也不会起作用。它们并不总是相同的。我已经几个月没有找到解决这个问题的办法了;我一直在使用解决方案 1 和 2,希望它们适用于大多数情况。我的计划是使用计时器以防某些网页出现错误或其他问题,但我认为 Google map 没有任何错误。我仍然可以使用它,但唯一更丑陋的解决方案是烧掉我的电脑。
编辑:到目前为止,这是我最接近的解决方案:
partial class SafeWebBrowser
{
private class SafeNavigationManager : INotifyPropertyChanged
{
private SafeWebBrowser Parent;
private bool _IsSafeNavigating = false;
private int AccumulatedNavigations = 0;
private bool NavigatingCalled = false;
public event PropertyChangedEventHandler PropertyChanged;
public bool IsSafeNavigating
{
get { return _IsSafeNavigating; }
private set { SetIsSafeNavigating(value); }
}
public SafeNavigationManager(SafeWebBrowser parent)
{
Parent = parent;
}
private void SetIsSafeNavigating(bool value)
{
if (_IsSafeNavigating != value)
{
_IsSafeNavigating = value;
OnPropertyChanged(new PropertyChangedEventArgs("IsSafeNavigating"));
}
}
private void UpdateIsSafeNavigating()
{
IsSafeNavigating = (AccumulatedNavigations != 0) || (NavigatingCalled == true);
}
private bool IsMainFrameCompleted(WebBrowserDocumentCompletedEventArgs e)
{
return Parent.ReadyState == WebBrowserReadyState.Complete && e.Url == Parent.Url;
}
protected void OnPropertyChanged(PropertyChangedEventArgs e)
{
if (PropertyChanged != null) PropertyChanged(this, e);
}
public void OnNavigating(WebBrowserNavigatingEventArgs e)
{
if (!e.Cancel) NavigatingCalled = true;
UpdateIsSafeNavigating();
}
public void OnNavigated(WebBrowserNavigatedEventArgs e)
{
NavigatingCalled = false;
AccumulatedNavigations++;
UpdateIsSafeNavigating();
}
public void OnDocumentCompleted(WebBrowserDocumentCompletedEventArgs e)
{
NavigatingCalled = false;
AccumulatedNavigations--;
if (AccumulatedNavigations < 0) AccumulatedNavigations = 0;
if (IsMainFrameCompleted(e)) AccumulatedNavigations = 0;
UpdateIsSafeNavigating();
}
}
}
SafeWebBrowser
继承WebBrowser
。 OnNavigating
、OnNavigated
和 OnDocumentCompleted
方法在相应的 WebBrowser
覆盖方法上调用。 IsSafeNavigating
属性会让我知道它是否正在导航。
最佳答案
等待文档加载是一个难题,但您希望不断检查 .ReadyState 和 .Busy(不要忘记这一点)。我会给你一些你需要的一般信息,然后我会在最后回答你的具体问题。
顺便说一句,NC = NavigateComplete 和 DC = DocumentComplete。
此外,如果您正在等待的页面有框架,您需要获取它们的引用并检查它们的 .busy 和 .readystate,如果框架是嵌套的,则嵌套的框架 .readystate 和 .busy 为好吧,所以你需要编写一个函数来递归地检索这些引用。
现在,无论它有多少帧,首先触发的 NC 事件始终是顶级文档,最后触发的 DC 事件也始终是顶级(父)文档的事件。
所以你应该检查它是否是第一个调用和 pDisp 是 WebBrowser1.object
(字面上就是你在 if 语句中键入的内容)那么你就知道它是顶级文档的 NC,然后等待同一对象出现在 DC 事件中,因此将 pDisp 保存到全局变量,并等待 DC 运行并且该 DC 的 pDisp 等于您在第一个 NC 事件期间保存的全局 pDisp(例如,您在触发的第一个 NC 事件中全局保存的 pDisp)。因此,一旦您知道 pDisp 已在 DC 中返回,您就知道整个文档已完成加载。
这将改进您当前的方法,但是,为了使其更加可靠,您还需要进行帧检查,因为即使您执行了上述所有操作,它也有 90% 以上的好,但不是 100% 的可靠,需要为此做更多。
为了以有意义的方式成功进行 NC/DC 计数(这是可能的,相信我),您需要将每个 NC 的 pDisp 保存在数组或集合中,当且仅当它不存在时在那个数组/集合中。完成这项工作的关键是检查重复的 NC pDisp,如果存在则不添加它。因为发生的事情是,NC 使用特定 URL 触发,然后发生服务器端重定向或 URL 更改,当发生这种情况时,NC 再次触发,但它发生在用于旧 URL 的相同 pDisp 对象上。因此,同一个 pDisp 对象被发送到现在第二次使用新 URL 发生的第二个 NC 事件,但仍然使用完全相同的 pDisp 对象完成所有操作。
现在,因为您有所有唯一的 NC pDisp 对象的计数,您可以在每个 DC 事件发生时(一个接一个地)删除它们,方法是执行典型的 If pDisp Is pDispArray(i) Then
(这是在 VB 中)包裹在 For 循环中的比较,并且对于每一个被取消,您的数组计数将接近 0。这是执行此操作的准确方法,但是,仅此是不够的,因为另一个 NC/DC 对可以在您的计数达到 0 后发生。此外,您必须记住在 NavigateError 事件中执行与在 DC 事件中所做的完全相同的 For Loop pDisp 检查,因为当发生导航错误时,将触发 NavigateError 事件代替 DC 事件。
我知道这需要付出很多努力,但我花了很多年时间来处理这个可怕的控制来弄清楚这些事情,如果你需要的话,我还有其他代码和方法,但我提到的一些东西这里是关于 WB Navigation 真正准备就绪的,以前没有在线发布过,所以我真的希望你觉得它们有用,并让我知道你的进展情况。另外,如果您想要/需要澄清其中的一些内容,请告诉我,不幸的是,如果您想 100% 确定网页已完成加载,以上内容还不是全部,干杯。
PS:另外,忘记提及,依靠 URL 进行任何类型的计数是不准确的,也是一个非常糟糕的主意,因为多个框架可能具有相同的 URL - 例如,www.microsoft.com 网站就是这样做的,您在地址栏中看到大约有 3 个框架调用 MS 的主站点。不要将 URL 用于任何计数方法。
关于c# - 是否可以确定 WebBrowser 是否正在导航?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/4127383/
我有一个 if 语句,如下所示 if (not(fullpath.lower().endswith(".pdf")) or not (fullpath.lower().endswith(tup
然而,在 PHP 中,可以: only appears if $foo is true. only appears if $foo is false. 在 Javascript 中,能否在一个脚
XML有很多好处。它既是机器可读的,也是人类可读的,它具有标准化的格式,并且用途广泛。 它也有一些缺点。它是冗长的,不是传输大量数据的非常有效的方法。 XML最有用的方面之一是模式语言。使用模式,您可
由于长期使用 SQL2000,我并没有真正深入了解公用表表达式。 我给出的答案here (#4025380)和 here (#4018793)违背了潮流,因为他们没有使用 CTE。 我很欣赏它们对于递
我有一个应用程序: void deleteObj(id){ MyObj obj = getObjById(id); if (obj == null) { throw n
我的代码如下。可能我以类似的方式多次使用它,即简单地说,我正在以这种方式管理 session 和事务: List users= null; try{ sess
在开发J2EE Web应用程序时,我通常会按以下方式组织我的包结构 com.jameselsey.. 控制器-控制器/操作转到此处 服务-事务服务类,由控制器调用 域-应用程序使用的我的域类/对象 D
这更多是出于好奇而不是任何重要问题,但我只是想知道 memmove 中的以下片段文档: Copying takes place as if an intermediate buffer were us
路径压缩涉及将根指定为路径上每个节点的新父节点——这可能会降低根的等级,并可能降低路径上所有节点的等级。有办法解决这个问题吗?有必要处理这个吗?或者,也许可以将等级视为树高的上限而不是确切的高度? 谢
我有两个类,A 和 B。A 是 B 的父类,我有一个函数接收指向 A 类型类的指针,检查它是否也是 B 类型,如果是将调用另一个函数,该函数接受一个指向类型 B 的类的指针。当函数调用另一个函数时,我
有没有办法让 valgrind 使用多个处理器? 我正在使用 valgrind 的 callgrind 进行一些瓶颈分析,并注意到我的应用程序中的资源使用行为与在 valgrind/callgrind
假设我们要使用 ReaderT [(a,b)]超过 Maybe monad,然后我们想在列表中进行查找。 现在,一个简单且不常见的方法是: 第一种可能性 find a = ReaderT (looku
我的代码似乎有问题。我需要说的是: if ( $('html').attr('lang').val() == 'fr-FR' ) { // do this } else { // do
根据this文章(2018 年 4 月)AKS 在可用性集中运行时能够跨故障域智能放置 Pod,但尚不考虑更新域。很快就会使用更新域将 Pod 放入 AKS 中吗? 最佳答案 当您设置集群时,它已经自
course | section | type comart2 : bsit201 : lec comart2 :
我正在开发自己的 SDK,而这又依赖于某些第 3 方 SDK。例如 - OkHttp。 我应该将 OkHttp 添加到我的 build.gradle 中,还是让我的 SDK 用户包含它?在这种情况下,
随着 Rust 越来越充实,我对它的兴趣开始激起。我喜欢它支持代数数据类型,尤其是那些匹配的事实,但是对其他功能习语有什么想法吗? 例如标准库中是否有标准过滤器/映射/归约函数的集合,更重要的是,您能
关闭。这个问题不符合Stack Overflow guidelines .它目前不接受答案。 这个问题似乎与 help center 中定义的范围内的编程无关。 . 关闭 9 年前。 Improve
我一直在研究 PHP 中的对象。我见过的所有示例甚至在它们自己的对象上都使用了对象构造函数。 PHP 会强制您这样做吗?如果是,为什么? 例如: firstname = $firstname;
...比关联数组? 关联数组会占用更多内存吗? $arr = array(1, 1, 1); $arr[10] = 1; $arr[] = 1; // <- index is 11; does the
我是一名优秀的程序员,十分优秀!