在IE中调试 JavaScript

作者: admin 分类: javascript 发布时间: 2012-06-07 12:41

简介

虽然越来越多的用户转向使用 FireFox 等非 IE 内核浏览器,但是 Internet Explorer(IE, 6 以及后续版本 ) 仍然有着超过 50% 的市场占有率,大部分产品产品都需要支持 IE。不过 IE 缺少像 FireFox 上那么多调试 JavaScript 代码的插件,使得在 IE 上调试 JavaScript 代码比较困难,很多开发人员喜欢通过加入 alert 语句来进行调试,很大程度上降低了开发效率。 本文详细介绍了在 IE 中进行 JavaScript 调试所用到的工具,并通过一个例子演示了如何使用这些工具, 可以让读者掌握在 IE 上调试 JavaScript 的方法和技巧,加快他们在 IE 上开发 Web 应用的速度。

IE 上的调试工具

IE 上可选择的 JavaScript 调试工具不多,主要是 Microsoft 脚本编辑器 (Microsoft Script Editor) 以及 IE Developer Toolbar。

Microsoft 脚本编辑器

Microsoft 脚本编辑器是 Microsoft Office 中的一个小组件,它是一个很完备的 JavaScript 编辑和调试工具, 提供了丰富的调试功能。如果没有安装的话,可以运行 Office 的安装程序,选择”自定义安装”类型,然后 在自定义安装向导页面,选中“选择应用程序的高级自定义”, 在接下来的高级自定义页面,依次定位到 Microsoft Office->Office 工具 ->HTML 源文件编辑 ->Web 脚本创作 -> 站点调试,选择“从本机运行全部程序”, 如下图所示。然后按照向导,完成安装即可。
图 1. 安装 Microsoft 脚本编辑器
安装 Microsoft 脚本编辑器

如果没有购买 Office 套件,可以从 参考资料列表中下载安装 Microsoft Script Debugger。它是免费的, 比 Microsoft Script Editor 更轻量级,缺点是调试功能,特别是跟踪变量的功能还比较原始。 所以在这里我们还是推荐使用 Microsoft 脚本编辑器。

IE Developer Toolbar

IE Developer Toolbar ,是 IE 上的一个插件,用来探究和理解 Web 页面的便捷工具,最主要的功能包括: 查看并修改页面的 DOM 对象;查看选中元素或者标签的各种属性,包括 HTML 和 CSS 属性以及 JavaScript 事件等。 之所以这里要用到它,是因为在一个设计完备的产品中,页面上的很多元素,包括附加在这些元素上的各种事件, 都是在运行时动态创建的,单纯通过查看源代码,很难找到我们要调试的 JavaScript 函数。在这种情况下, 使用 IE Developer Toolbar,只需要通过鼠标选中目标元素,就可以立即帮助我们找到那些在运行时附加在它上面 的 JavaSscript 函数或者事件。

可以从 参考资料列表中下载安装 IE Developer Toolbar。安装成功后,会看到它的图标 被加到了 IE 的标准按钮栏上,如下图所示。
图 2. IE Developer Toolbar 图标
IE Developer Toolbar 图标

在 IE 中启用脚本调试功能

在我们能够进行 JavaScript 代码调试之前,需要先启用 IE 的脚本调试功能。

在 IE 菜单的工具菜单中,依次点击:Internet 选项 -> 高级 -> 浏览,取消选中”禁用脚本调试 (Internet Explorer)”和 “禁用脚本调试 ( 其他 )”,如下图所示 .
图 3. 启用脚本调试功能
启用脚本调试功能

调试方法

被动调试

被动调试,也可以称为自动调试,当 IE 碰到 JavaScript 语法及运行时错误,或者选中了查看 -> 脚本调试器 -> 在下一条语句中断, IE 会自动弹出一个”实时调试”窗口,让你选择调试器进行调试,我们选择”新实例 Microsoft Script Editor”,然后点击”是”按钮, 就可以进行调试了,如下图所示。不过这种被动调试方式没有可控性,而且我们平时多是调试逻辑而不是语法错误, 这里就不做详细介绍了。
图 4. 实时调试对话框
实时调试对话框

主动调试 – 使用 debugger 语句

我们可以在所要调试的某条语句或者函数中,加入 debugger 语句,这样当 IE 执行到这个 debugger; 语句时,就会弹出实时调试窗口, 让我们进行调试。使用这种调试方法,需要我们知道要在什么地方加入 debugger 语句。我们上面提到,有时候并不是很好确定应该 在哪个函数中加入,这就需要使用 IE Developer Toolbar 来帮助我们进行定位。

下面我们将以一个例子来说明如何使用 IE Developer Toolbar 来定位目标函数,进而使用 MS Script Editor 进行调试。

应用示例

如下图所示,main.htm是一个用来显示个人信息的页面。 这些信息存储在一个 XML 文件 (data.xml) 中, 使用 JavaScript(main.js) 进行 XSLT 转换 (data.xsl),来生成页面内容 .
图 5. 应用示例
应用示例

在“年龄”字段的输入框里面,我们只允许输入 0-9 的数字。但是我们可以发现,如果输入 025,在焦点从输入框移出后, 数字会变成 21,这种行为是不正确的,我们可以想到问题应该出在该输入框的 onblur 事件的代码里面。

那么 onblur 事件对应到哪个函数里面呢?页面上的大部分元素,包括年龄输入框,都是在页面加载后,由 JavaScript 动态生成的, 查看页面的源文件并不能帮我们找到这个函数。这时候就用到 IE Developer Toolbar 了。

定位目标函数

点击 IE 标准按钮工具栏上 IE Developer Toolbar 的图标,IE Developer Toolbar 的界面就出现在页面的底部。 点击 IE Developer Toolbar 界面左上角的“单击选择元素”图标 , 然后点击年龄输入框, 在 IE Developer Toolbar 的属性 (Attribute) 面板,就可以看到 onblur 对应的函数了,如下图所示。
图 6. 使用 IE Developer Toolbar 定位目标函数
使用 IE Developer Toolbar 定位目标函数

调试代码

通过查找,我们在 main.js 里面找到 fieldBlur 函数,在这个函数的第一行,我们加入 debugger; 语句。然后刷新页面,在年龄输入框输入 025, 然后用鼠标点击输入框以外的页面,IE 会弹出“实时调试”对话框,选择“新实例 Microsoft Script Editor”。在打开的窗口中,我们可以看到 脚本在 debugger; 语句处暂停执行,如下图所示。
图 7. 使用 Microsoft Script Editor 进行调试
使用 Microsoft Script Editor 进行调试

按两次 F10 键 ( 逐过程单步执行 ),代码将执行到 element.value = parseInt(element.value); 语句。分别选中 element.value 和 parseInt(element.value), 然后点击右键菜单中的“添加监视”项,通过对比它们的值,可以看到问题出在 parseInt 函数:字符串“025”被转换成了 21。通过查询函数手册, 发现我们没有给 parseInt 函数指定转换的基数 10,这样“025”被当作八进制数处理了。为了验证,我们可以在“监视 %1”面板, 手动加入 parsetInt(element.value, 10),可以看到转换后是正确的了。
图 8. 变量监视窗口
变量监视窗口

这样我们就很顺利地找到了问题的原因和解决办法。

在 IE8 中进行调试

随着在 Web 开发中 JavaScript 重要性的日益增加,微软在 IE8 中直接内置了“开发人员工具”(Developer Tools)。 我们可以把它看作是 IE Developer Toolbar 的加强版,除了我们上面介绍到的 IE Developer Toolbar 的功能, 它还内置了脚本调试和探查器 (Profiler,性能监控器 ) 的功能。所以如果你的产品只需要在 IE8 上进行调试, 那么就不需要在额外安装其他插件和工具了。下面我们就简单介绍一下调试过程。

定位目标函数

在用 IE8 打开 main.htm 页面后,选择“工具”菜单中的“开发人员工具”,或者直接按 F12 键,将弹出“开发人员工具”的窗口。 为了方便选取页面上的元素,可以点击窗口右上角的“固定”图标,来让 “开发人员工具”嵌入到页面的下部。然后点击 左上角的“单击选择元素”图标,接着点击年龄输入框,同使用 IE Developer Toolbar 一样,在“开发人员工具”的属性面板, 就可以看到 onblur 对应的函数了,如下图所示。
图 9. 在 IE8 中定位目标函数
在 IE8 中定位目标函数

调试代码

与使用“Microsoft Script Editor”一样,我们找到 fieldBlur 函数,在这个函数的第一行,加入 debugger; 语句。然后点击 “开发人员工具”窗口的“脚本”标签,切换到调试面板,点击“启动调试”按钮,在弹出的对话框选择 “确定”后,“开发人员工具” 窗口会自动弹出,变成独立的窗口。切换到 main.htm 页面,在年龄输入框输入 025,然后用鼠标点击输入框以外的页面, “开发人员工具”窗口会自动跳出,我们同样可以监视 element.value 和 parseInt(element.value) 的值,以及手动把 parseInt(element.value,10) 加入监视列表,如下图所示。
图 10. 在 IE8 中使用 debugger 语句调试
在 IE8 中使用 debugger 语句调试

另外我们可以通过设置断点,而不加入 debugger; 语句来进行调试。在“脚本”面板上“开始调试”按钮右边的文件下拉框, 选择“main.js”,然后第 83 行代码前面单击鼠标,就在 fieldBlur 函数的第一行设置了断点,然后点击“开始调试”按钮, 如下图所示。当我们把鼠标移出年龄输入框后, JavaScript 代码会自动在我们设置的断点处停止执行。
图 11. 在 IE8 中使用断点调试
在 IE8 中使用断点调试

总结

本文以 IE6 为主,介绍了 IE 浏览器上调试 JavaScript 所用到的工具以及调试方法,并在最后介绍了 IE8 在调试脚本方面的改进。 通过阅读本文,读者可以掌握在 IE 上调试 JavaScript 的方法和技巧,提高他们在 IE 上开发 Web 应用的效率。
main.html

IE中调试JavaScript

 

 

main.js

/**
*The XMLDOM class
* Note, it can only work in IE.
*/
function XMLDOM() {
	this.DOM = new ActiveXObject("Microsoft.XMLDOM");
}

XMLDOM.prototype.loadFromFile = function (/*string*/fileURL) {
	this.DOM.load(fileURL);
};

XMLDOM.prototype.loadFromString = function (/*string*/xml) {
	this.DOM.loadXML(xml);
};

XMLDOM.prototype.transform = function (/*string*/xslFileURL) {
	var oXSL = new XMLDOM();
	oXSL.loadFromFile(xslFileURL);
	var stylesheetNode = oXSL.DOM.documentElement;
	var scriptNodes = stylesheetNode.selectNodes( "xsl:script" );
	var stylesheetText = stylesheetNode.xml;
	stylesheetText = stylesheetText.replace( /[\b\f\n\r\t]/g, "" );
	stylesheetText = stylesheetText.replace( new RegExp( ".*" ), "" );
	oXSL.loadFromString( stylesheetText );

	for(var node = scriptNodes.nextNode(); node != null; node = scriptNodes.nextNode()) {
		oXSL.DOM.documentElement.appendChild(node);
	}

	var xml = this.DOM.documentElement.transformNode(oXSL.DOM);

	scriptNodes = null;
	oXSL = null;

	var parseError = this.DOM.parseError;
	if (parseError.errorCode != 0) {
		alert("transform failed:
"+parseError.reason);
		return null;
	}

	return xml;
};

function initPage() {
	var fileURL = "data.xml";
	var xslfileURL = "data.xsl";
	var oDOM = new XMLDOM();
	oDOM.loadFromFile(fileURL);
	var strData = oDOM.transform(xslfileURL);
	document.getElementById("contentDiv").innerHTML = strData;
}

function keyPress(/*string*/datatype) {
	var keyPressed = event.keyCode;
	var keyOK = true;
	if(datatype == "int") {
		if (keyPressed >= 48 && keyPressed = 48 && keyPressed