【问题标题】:How to pause JavaScript execution in Internet Explorer?如何在 Internet Explorer 中暂停 JavaScript 执行?
【发布时间】:2012-05-17 01:00:24
【问题描述】:

我有以下场景:

  • 主页
  • 嵌套页面
  • 通用 JS 文件(包含在两个页面中)

嵌套页面随后被加载到主页面的 iframe 中。两个页面都在页面加载时从公共 JS 文件中调用一个函数。

现场演示:
http://www.ecmazing.com/misc/pause-execution/mainpage.html
http://www.ecmazing.com/misc/pause-execution/nestedpage.html
http://www.ecmazing.com/misc/pause-execution/common.js

通用 JS 文件包含一个将 H1 元素涂成红色的全局函数。我想在该函数的开头暂停执行,以便在 H1 元素仍为黑色时暂停执行。

在主页上怎么做:

这是微不足道的。只需加载页面,打开浏览器的开发工具,选择common.js文件,在函数的第一行设置断点即可。现在,重新加载页面。断点将持续重新加载,并暂停执行。

嵌套页面怎么做:

现在,在 Chrome 和 Firefox (Firebug) 中,上面设置的断点(用于主页)也适用于嵌套页面。两个页面使用相同的 JS 文件,在该文件中设置断点将自动适用于两个页面。不幸的是,这条规则不适用于 IE。

更糟糕的是,即使我随后设置了断点,然后仅重新加载 iframe,断点也将不会持续存在。

所以,我不知道如何在 IE 中暂停执行嵌套页面。可以做到吗? (我通过在函数开头手动设置debugger; 来处理这个问题,但如果可能的话,我希望能够通过 IE 中的开发工具设置断点。)

【问题讨论】:

  • Visual Studio 非常擅长调试 ie,但我不知道它是否可以处理这种情况......如果我需要它,我会尝试它
  • @MartinJespersen 我在 PHP 阵营 :-|。仅仅为此安装 VS 将是大材小用。
  • 你用的是什么版本的ie?
  • @MartinJespersen IE9,当然。我什至不确定以前版本的 IE 是否有可用的开发工具。
  • @ŠimeVidas IE8 是第一个拥有开发工具的版本,微软发布了 IE7 插件microsoft.com/en-us/download/details.aspx?id=18359

标签: javascript internet-explorer debugging iframe browser


【解决方案1】:

我能找到的最接近的解决方案是在主页的 loadIFrame() 函数中设置断点,然后“介入”直到加载嵌套页面的 Common.js 文件。在一个更复杂的示例中,您将能够在新的 Common.js 文件中设置断点,并且它们会正常工作,直到下次加载 iframe 时,它​​们将再次丢失。

【讨论】:

  • 您的第一段没有意义。 iframe 元素的“加载”事件在嵌套页面和脚本加载后 触发。 *** 至于你的第二段,那是不可能的。我的代码正在设置 iframe 元素的 src 属性。无法从这里进入嵌套页面的 JS 代码。
  • 让我澄清一下我的意思。加载您的示例页面并打开 IE 的 F12 开发人员工具并导航到 Script 选项卡,然后在第 26 行放置一个断点 [document.getElementById('IFrame').src = 'nestedpage.html';] 现在你只会看到MainPage.html 和 Common.js 已加载。点击“Step In”,直到到达 NestedPage.html。现在您看到 NestedPage.html 和另一个 Common.js 已加载。通过将断点放在第 26 行,它将始终保持不变,并且您将始终拥有加载 NestedPage 及其 Common.js 文件的入口点。
  • 哇!它确实有效。 (我之前尝试从.src 赋值语句介入,但我无法让它工作。)此外,这种方法在 Chrome 中不起作用。但是,它在 IE :) 中确实有效
  • @ŠimeVidas,请将我收到的赏金转给应得的 paulH,因为他的答案在赏金期内。我很高兴能提供帮助,但会更高兴看到合适的人因有效解决这个问题而获得奖励。 +1 为保罗。
  • 乐于助人!不用担心赏金,在你提到它之前,我已经忘记了这个问题有赏金! :-)
【解决方案2】:

我没有要测试的 IE9,但也许您可以将 common.js 文件视为 iframe 页面的单独资产?我相信这就是它在其他浏览器中工作的原因,因为这些文件必须由浏览器以某种方式标记或标记

例如,在 iframe 页面上将 ?iframePage 附加到 common.js 的末尾。至少在 Firefox 中是显示加载为common.js?iframePage 的资产。浏览器会忽略查询字符串之后的所有内容,否则将使用该 exact 名称加载 JavaScript。

另一个示例是复制common.js 并将其重命名为commonClone.js,然后将其用于iframe 页面。

这两个示例都可能允许您在 IE9 中设置断点两次,每个资产一个。

也就是说,没有什么可以阻止您创建 iframe only 断点,这些断点独立于 父页面 正在使用的 common.js 文件。这个方法,让我们调用它并行断点,允许对 JavaScript 进行异步调试,因为 iframe 页面父页面 正在独立处理 JavaScript,但可能正在运行串联。

此方法的参考来自 官方来源 MSDN 库:Using the F12 Developer Tools to Debug JavaScript Errors 部分 Managing Breakpoints 显示如何对多个 JavaScript 文件执行断点。

根据 IE9 开发者论坛上的recent forum post,在用于调试时防止重新加载 JavaScript 文件的解决方案是使用 内联事件处理程序 而不是 attachEvent 如本例所示:

replace (or comment it out)

$(document).onload(function(){ mycustomonload functions});

with

<body onload="mycustomonload functions">

【讨论】:

  • 我不明白。 “仅限 IE9 断点”是什么意思?
  • @ŠimeVidas,澄清:“IE9 仅断点”是指在使用该浏览器进行调试时在 iframe 页面中创建断点。例如,您可能希望在父页面中有一个非特定于浏览器的断点,但 iframe 页面可能包含一个特定于浏览器的断点(例如,IE9)。我将更新上述答案以反映 iframe only 断点,因为这样更清楚。
  • 但问题是代码在页面加载时执行,所以无法按时手动设置断点。如果我随后设置断点,然后重新加载 iframe,则断点不会持续存在。 (我在我的问题中解释了这一点。)
  • 我阅读的Managing Breakpoints 部分没有提到它不会持续存在,所以我期待它会持续存在,特别是对于应该在缓存中然后允许此类断点的多个 JavaScript 文件重置。也许可以更改始终从服务器刷新浏览器设置,以便使用缓存中的文件?除此之外,我对持久断点没有想法。
  • 不,不是这样。我检查了 IE9 工具中的“网络”选项卡。重新加载 iframe 时,IE 会收到来自服务器的 304-Not-Modified-responses,因此它会从其缓存中加载文件。
【解决方案3】:

如果您这样做只是为了进行兼容性测试,那么您是否尝试过为 Chrome 使用 IETab plugin

这模拟了 IE 的渲染引擎,同时允许您使用 Chrome 调试器。

如果这还不够好,那么我认为你已经陷入僵局,IE 开发工具还不够复杂。

【讨论】:

  • 不幸的是,那个 IETab 插件并没有解决我的问题。在我的应用程序中,IE9 中存在不需要的垂直滚动条。但是,如果我使用 IETab 加载页面,则该滚动条不存在,即使我在 IETab 的设置中设置了“IE9 模式”。这意味着 IETab 不能可靠地模拟 IE,因此,我不能将其用作解决方案。
  • 嗯。我担心它可能无法模拟 IE 的 JavaScript 引擎。但是你是说页面样式也不一样吗?
  • 嗯,外观上的差异是我正在执行的一些 JavaScript 代码的结果。 (我正在设置页面上某些元素的尺寸。)因此,很可能是布局引擎模拟得很好,但 JavaScript 引擎是导致外观差异的原因。无论如何,我需要一个 100% 可靠的解决方案,而 IETab 似乎并非如此。
  • @ŠimeVidas 够公平的。抱歉,我帮不上忙。
  • 我真的认为没有必要投反对票,不管是谁。
【解决方案4】:

也许,如果您可以重构您的 Html 和 JavaScript 代码,您只能从父页面引用 common.js,并使主页面和嵌套页面使用相同的 JavaScript 函数。

这样一个断点就可以满足两种情况。

【讨论】:

  • 嗯,这当然是一个有趣的想法。但是,关于这个线程,您的回答实际上只是一个评论,因为它没有为我当前的状态提供解决方案。不过谢谢你的建议。 :)
【解决方案5】:

要在 IE 中调试 iframe,并能够设置和保留断点,您可以在其自己的 ie 选项卡/窗口中打开 iframe 地址。但是,如果 iframe 与其父级通信,这是不可能的/直截了当的。

【讨论】:

  • 是的,iframe中加载的页面的JS代码确实需要访问父窗口:(。此外,在我目前的情况下,我正在设置 iframe 的尺寸,并且其中加载的页面取决于此。不过,这是个好主意,将来可能会派上用场。
【解决方案6】:

我希望你至少在使用 IE Debuggy Bar。使用此代码更新您的 common.js 文件

function func () {
    if(typeof window.parent.debug !== "undefined"){
        window.parent.debug();
    }
    document.getElementsByTagName( 'h1')[0].style.color = 'red';
}


function debug(){
    var a = "break here";
}

在主页加载后将断点设置为var a = "break here";。当您点击 Load Iframe 按钮时,js 将在该行停止。使用调用堆栈导航到上一个 javascript 指令(行),该指令应位于 nestedpage.html 中的 common.js 文件中。现在设置另一个断点,然后在调试器中点击继续,或使用 STEP 功能

== 更新 ===

顺便说一句,要回答您的问题,为什么断点不能在 iframe 中保留,请这样想。每次单击“加载 IFrame”按钮时,window 对象的旧实例将被放置在内存中,并且所有断点和新实例都会使用新的 common.js 实例创建。如果你打电话给windows.open("http://......");,也会发生同样的情况

还要记住,即使您在两个window(s) 中加载了相同的文件,它也会在浏览器的两个不同执行框架中加载。您可以运行同一浏览器的两个浏览器实例,但它们不会在窗口中显示相同的页面。但是,有些东西是共享的,比如 cookie,但这超出了本主题的范围。

【讨论】:

  • 这一切都不需要。为此目的有一个debugger; 声明 - 我已经在我原来的问题中提到了这一点。我想知道如何暂停执行 而不必手动编辑 JavaScript 文件。
  • 如果您不使用高级 IDE,就没有办法 :) 我正在使用 PHPStorm 和 WebStorm。他们有优秀的浏览器集成调试插件。这里的问题是您的 common.js 文件没有加载到 IFrame 中,您希望将它放在内置浏览器调试器中。
  • 如果您不想下载任何 IDE,这里建议您的唯一选择是我建议您的示例。
  • 不,这不是问题所在。代码确实执行。问题是断点不会持续存在。重新加载最顶层的窗口时,断点仍然存在,但重新加载 iframe 时,断点不存在 - 这就是问题所在。
  • 太棒了!然后您可以设置设置远程服务器调试,只需转到调试配置。创建新的JavaScript Debug &gt; Remote 配置,并在浏览器中设置哪个源文件具有哪个URL。还要指定当您开始调试会话时应在浏览器中打开哪个远程 URL...我相信您会设法设置它。
【解决方案7】:

您可以使用 setTimeout() 暂停 javascript 特定时间...

【讨论】:

  • 在我的问题中,我提到我已经使用debugger; 作为解决方案。但是,理想情况下,我想暂停执行,而不必手动编辑 JavaScript 文件。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-12-09
  • 2012-10-13
  • 1970-01-01
  • 1970-01-01
  • 2019-02-01
  • 1970-01-01
相关资源
最近更新 更多