在页面加载前使用Firebug调试DOM变化

6
我在运行JavaScript代码时遇到了问题,需要调试引入的DOM更改。代码中某个元素的类被更改,我正在尝试准确定位更改发生的位置。不幸的是,新类名太通用了,搜索所有JS代码会给出太多结果,不可行。
我已经尝试使用Firebug进行调试,但尽管有很好的“{{link1:“断点属性更改”功能}}”,但我无法以我想要的方式使其工作。Firebug演示可以正常工作,但这是一个后加载的情况。
问题似乎是我想要在页面完全加载之前监视变化。我假设更改发生在 $(document).ready()的某个地方,因此它在DOM中,但我不能像演示那样选择元素进行UI断点。
除了手动检查代码或使用grep之外,是否有其他调试这种情况的方法?

2
使用脚本选项卡并设置断点。如果您正在使用大量的jQuery闭包,您可能需要探索模块化方法,以便您可以准确地描述您的代码并检测获取或设置。 - rxgx
1
我担心手动设置代码断点并不比逻辑浏览整个代码库更好。我希望的是在DOM准备就绪之后,但在完全加载页面之前应用“属性更改时中断”功能。但我还没有找到在Firebug中实现它的方法。即使我在$(document).ready()中手动中断,我也无法自由地检查文档。我不知道这是限制/错误/设计问题。在完整的页面加载后,进一步调试可以正常工作,但已经为时已晚,更改已经生效。 - Karol J. Piczak
1
整个问题如果您更多或少了解代码库,那么是可以承受的。但是,如果您潜入没有经验的开源项目,则会导致令人痛苦的缓慢调试过程。所以这就是为什么我正在寻找一种加快速度的方法。 - Karol J. Piczak
1
感谢您的所有答案,选择哪个回答获得奖励很困难,但最终我决定授予 @jsgoupil 的答案是第一个且有帮助的。对于更复杂的非jQuery变异,我可能会选择这里介绍的其他技巧。谢谢! - Karol J. Piczak
4个回答

4
我建议您删除目标元素,其中类名已更改。有些运气的话,您可能能够在JavaScript代码中生成错误,以便找到问题所在。
否则,如果是由JQuery(addClass)完成的,则可能需要修改JQuery代码本身,以便找出调用堆栈。
代码应如下所示(确保此代码是在JQuery包含后第一个被调用的代码):
(function () {
    var addClass = jQuery.fn.addClass;
    jQuery.fn.addClass = function (value) {
        for (var i = 0, l = this.length; i < l; i++) {
            // Here you put your method to start the debugger if you get your right element
            if (this[i].id === "abc") {
                debugger;
            }
        }
        addClass(value);
    }
})();

希望能够帮到你。

嘿,谢谢。尽管第二部分是特定于jQuery的,但到目前为止它可能是最有用的提示。 - Karol J. Piczak
@Karol 我不知道你现在是否解决了你的问题,但你考虑用Chrome试试了吗?他们的DevTool也有“Break on *”功能。 - jsgoupil
是的,我很久以前就修复了它。只是需要再花费几个小时。不幸的是,在我的情况下,Chrome的行为与Firefox相同。它无法捕获页面加载前发生的变化。 - Karol J. Piczak

1

如果您想使用“属性更改时中断”功能进行调试,可以执行以下操作:

  1. 注释掉页面中的所有JS(希望都在标签中),除了基本的jQuery加载。

  2. 加载页面并设置您的监视点。

  3. 向HTML添加一个按钮,该按钮触发JS。或者,可以选择从控制台触发它。

  4. 触发JS加载/触发。希望您的监视和断点按预期触发。

例如,假设您的页面加载/具有以下内容:

<script src="http://ajax.googleapis.com/ajax/libs/jquery/1.5.2/jquery.min.js" type="text/javascript"></script>
<script src="/Library_X.js" type="text/javascript"></script>
<script src="/MyJS.js" type="text/javascript"></script>

在设置监视点后,您可以在控制台中运行此代码:

function addJS_Node (text, s_URL)
{
    var scriptNode                      = document.createElement ('script');
    scriptNode.type                     = "text/javascript";

    if (text)  scriptNode.textContent   = text;
    if (s_URL) scriptNode.src           = s_URL;

    document.head.appendChild (scriptNode);
}

addJS_Node (null, '/Library_X.js');
//-- Possible pause here.
addJS_Node (null, '/MyJS.js');
// etc.

或者暂时在页面的HTML中编写一个触发相同JS的按钮代码。

1

这个答案可能听起来相当无聊,但我真的认为解决这种错误的最佳方法是“拆解”你的程序。只需复制整个项目,然后将其分解。逐个删除代码块。将函数调用转换为存根函数或其他内容以保持运行。找到触发错误的最小代码量。然后解决方案应该很明显。


这大概就是我一直在做的事情。我不停地思考,穿越代码,尽可能找到问题所在。大多数时候(实际上我认为一直如此),我最终能找到问题所在。但有时候,一个本应只需要2个点击的问题却要花费我半天时间。这就是让我感到痛苦的原因。我知道所有的信息都在我的掌握之中,但我就是无法使用它(页面还没有准备好,但是服务器生成的DOM已经可以用了,所以我应该能够监听客户端的进一步变化)。 - Karol J. Piczak

1

你有没有考虑添加变异事件?我认为你想要的事件DOMAttrModified在Webkit中不受支持,所以你可能需要使用Firefox或Opera进行测试。实际上,在DOM level 3中已被弃用。

有两个jQuery插件可以用于变异事件这里文档)和这里,但由于你想在页面加载之前完成此操作,它们可能不是答案。

你最好自己编写JavaScript绑定此事件 - 在是否有适用于Webkit的DOMAttrModified替代品的答案中有一个例子。

希望这能帮到你。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接