IE中JScript的条件编译技术详解
本文介绍Internet Explorer中鲜为人知的条件编译功能,通过@cc_on指令激活。详细解析@if、@else等语法及@_jscript_version等预定义变量,并提供利用该特性实现真正跨浏览器Ajax请求对象的完整代码示例,解决传统try/catch在旧版IE中的兼容问题。
IE中JScript的条件编译技术详解
- 作者:JavaScript Kit
- 译者:子乌(Sheneyan)
- 翻译日期:2006-02-12
- 英文原文:Conditional Compilation of JScript/ JavaScript in IE
- 版权:翻译未经过javascript kit同意,我只对我所翻译的中文部分负责。版权归原作者所有。
条件编译概述
在Internet Explorer浏览器中,存在一项较少被提及的功能,即条件编译。自IE4版本起,该功能便已得到支持,并因在一些Ajax相关的JavaScript脚本中的应用而逐渐受到关注。作为一种独立的对象判断机制,条件编译允许IE根据预定义或用户自定义的条件,决定JScript或JavaScript代码的特定部分是否被编译执行。此外,它也可被视为代码的条件注释,有助于确保代码在非IE浏览器中也能正常运行。
语法概述
要在脚本中激活条件编译,需使用@cc_on指令,或者直接以@if、@set等作为条件编译逻辑的一部分来激活。以下是一个示例代码:
Language:javascript, parsed in: 0.007 seconds, using GeSHi 1.0.7.12
-
<script type=
"text/javascript"> -
-
/*@cc_on
-
document.write("JScript 版本: " + @_jscript_version + ".<br>");
-
/*@if (@_jscript_version >= 5)
-
document.write("JScript 版本 5.0+.<br \/>");
-
document.write("只有当浏览器支持JScript5+的时候你才能看到这些文字.<br>");
-
@else @*/
-
document.
write("当你使用其他浏览器(比如: Firefox, IE 4.x 之类)的时候看到这行文字<br>"); -
/*@end
-
@*/
-
-
</script>
-
示例展示:
JScript 版本: 5.6.
JScript 版本 5.0+.
仅当浏览器支持JScript 5及以上版本时,您才能看到这些文字。
如果您使用的是IE(任何版本),应当能够看到第一个document.write()的输出;如果是IE5及以上版本,接下来的两个document.write()您也能看见(因为从IE5开始支持JScript 5)。最后一个document.write()方法则是为了兼容其他非IE5+浏览器而设计的,无论是Firefox、Opera还是IE4等其他浏览器。条件编译依赖于类似条件注释中使用的注释标签,以确保其在所有浏览器中都能顺畅工作。
使用条件编译时,建议先通过@cc_on语句来激活它。只有这样,您才能在脚本中包含注释标签以保证浏览器兼容性,正如上述示例所示。(译者注:这句英文我翻译的不是很顺...看起来似乎与上面的句子矛盾)
@if, @elif, @else, @end 语句
在简要介绍之后,这里列出了一些用于条件编译的控制语句:
- @if
- @elif
- @else
- @end
现在让我们看一些“特殊”的示例。
if-else 逻辑 (排除IE外的浏览器)
Language:javascript, parsed in: 0.001 seconds, using GeSHi 1.0.7.12
-
/*@cc_on
-
@if (@_win32)
-
document.write("操作系统是32位windows。浏览器是IE。");
-
@else
-
document.write("操作系统不是32位windows。浏览器是IE。");
-
@end
-
@*/
-
这是一段完整的脚本,仅被IE浏览器识别并忽略其他所有浏览器,该脚本在不同操作系统上将显示不同的内容。请对比下面的另一个示例……
if-else 逻辑2 (包含其他浏览器)
Language:javascript, parsed in: 0.004 seconds, using GeSHi 1.0.7.12
-
/*@cc_on
-
/*@if (@_win32)
-
document.write("操作系统是32位windows。浏览器是IE。");
-
@else @*/
-
document.
write("浏览器不是IE (如: Firefox)或者浏览器不是在32位windows下的IE。"); -
/*@end
-
@*/
-
熟练运用注释标签,此示例中的else部分能够包含所有非IE浏览器(如Firefox),以及非32位Windows下的IE。仔细研究这段注释,直到您完全理解其逻辑为止。
if, elseif, else逻辑 (排除IE外的浏览器)
继续深入,您可以查看完整内容:
Language:javascript, parsed in: 0.001 seconds, using GeSHi 1.0.7.12
-
/*@cc_on
-
@if (@_jscript_version >= 5)
-
document.write("IE Browser that supports JScript 5+");
-
@elif (@_jscript_version >= 4)
-
document.write("IE Browser that supports JScript 4+");
-
@else
-
document.write("Very old IE Browser");
-
@end
-
@*/
-
if, elseif, else 逻辑2 (包含其他浏览器)
Language:javascript, parsed in: 0.004 seconds, using GeSHi 1.0.7.12
-
/*@cc_on
-
/*@if (@_jscript_version >= 5)
-
document.write("IE Browser that supports JScript 5+");
-
@elif (@_jscript_version >= 4)
-
document.write("IE Browser that supports JScript 4+");
-
@else @*/
-
document.
write("Non IE Browser (one that doesn't support JScript)"); -
/*@end
-
@*/
-
全面处理。在最后一个示例中,最后的else语句包含了所有非IE浏览器。
条件编译变量
在前一部分中,您看到了一些奇怪的变量,例如@_win32。以下是一些可用于判断IE或计算机大致环境的预定义条件编译变量:
| 变量 | 描述 |
|---|---|
| @_win32 | 当运行在一个win32系统中时返回true, 否则返回 NaN. |
| @_win16 | 当运行在一个win16系统中时返回true , 否则返回 NaN. |
| @_mac | 当运行在一个Apple的Macintosh系统中时返回 true , 否则返回 NaN. |
| @_alpha | 当运行于DEC aplha处理器上时返回true ,否则返回 NaN. |
| @_x86 | 当运行于一个Intel处理上时返回true ,否则返回 NaN. |
| @_mc680x0 | 运行于Motorola 680x0处理器上时 true , 否则返回 NaN. |
| @_PowerPC | 运行于Motorola PowerPC处理器上时 true , 否则返回 NaN. |
| @_jscript | 永远返回 true. |
| @_jscript_build | JScript脚本引擎编译次数. |
| @_jscript_version | Jscript版本,以主要版本.次要版本格式展现.
IE4 支持JScript 3.x |
| @_debug | 如果编译于debug模式则返回 true ,否则返回false. |
| @_fast | 如果编译于fast模式则返回 true ,否则返回false. |
在大多数情况下,您也许只需要使用@_win和@jscript_build:
Language:javascript, parsed in: 0.001 seconds, using GeSHi 1.0.7.12
-
/*@cc_on
-
@if (@_win32)
-
document.write("OS is 32-bit. Browser is IE.");
-
@else
-
document.write("OS is NOT 32-bit. Browser is IE.");
-
@end
-
@*/
-
用户自定义变量
您还可以在条件编译块中定义自己的变量,语法如下:
Language:javascript, parsed in: 0.001 seconds, using GeSHi 1.0.7.12
-
@set @varname = term
-
在条件编译中,可以使用数字与布尔类型的变量,但字符型无法使用。例如:
Language:javascript, parsed in: 0.002 seconds, using GeSHi 1.0.7.12
-
@set @myvar1 =
35 -
@set @myvar3 = @_jscript_version
-
在条件编译逻辑中,可以使用标准的运算符:
- ! ~
- * / %
- + -
- << >> >>>
- < <= > >=
- == != === !==
- & ^ |
- && |
您可以通过判断是否返回NaN来确定是否定义了一个用户自定义变量:
Language:javascript, parsed in: 0.002 seconds, using GeSHi 1.0.7.12
-
@if (
@newVar != @newVar
) -
//该变量未定义
-
由于NaN是唯一一个不等于其自身的值,因此这段脚本能够正常运行。
条件编译示例--try-catch语句
在教程开始时,我曾提及条件编译如何因在一些Ajax的JavaScript中的出现而显示出其价值。现在我要说明我所指的内容。一个典型的Ajax脚本通常包含一个中心函数,用于判断浏览器(如IE、Firefox等)对生成异步请求对象的支持情况:
典型的ajax函数:
Language:javascript, parsed in: 0.020 seconds, using GeSHi 1.0.7.12
-
function
HttpRequest
(url, parameters
){ -
var
pageRequest =
false //variable to hold ajax object -
if (
window.
XMLHttpRequest) // if Mozilla, Safari etc -
pageRequest =
newXMLHttpRequest
() -
else if (
window.
ActiveXObject){ // if IE -
try {
-
pageRequest =
newActiveXObject
("Msxml2.XMLHTTP") -
}
-
catch (
e
){ -
try{
-
pageRequest =
newActiveXObject
("Microsoft.XMLHTTP") -
}
-
catch (
e
){} -
}
-
}
-
else
-
return false
-
}
-
许多人认为try/catch语句能够顺利测试Ajax支持,但不幸的是,事实并非如此。那些不支持throw/catch的浏览器(例如IE 4.x)实际上会阻塞上述代码并返回错误。为了克服这一问题,条件编译可用于粗略构建一个真正跨浏览器的友好Ajax处理函数:
真正的跨浏览器函数:
Language:javascript, parsed in: 0.008 seconds, using GeSHi 1.0.7.12
-
function
HttpRequest
(url, parameters
){ -
var
pageRequest =
false //variable to hold ajax object -
/*@cc_on
-
@if (@_jscript_version >= 5)
-
try {
-
pageRequest = new ActiveXObject("Msxml2.XMLHTTP")
-
}
-
catch (e){
-
try {
-
pageRequest = new ActiveXObject("Microsoft.XMLHTTP")
-
}
-
catch (e2){
-
pageRequest = false
-
}
-
}
-
@end
-
@*/
-
-
if (
!pageRequest &&
typeofXMLHttpRequest !=
'undefined') -
pageRequest =
newXMLHttpRequest
() -
}
-
使用条件编译,完整的try/catch块仅用于IE5及以上版本;其余浏览器(如IE4或非IE浏览器)则尝试解析它(dicipher it...这个dicipher是什么?“破译”这个解释是google到的,个人感觉翻译成“忽略”似乎更好?)。显然,Firefox会继续并使用XMLHttpRequest代替。现在您得到了它——一个真正跨浏览器的Ajax函数!(译者注:在我翻译的另外一篇文章中,可以看到这个函数更全面的写法。)
JavaScript闭包与类(Class)的区别及适用场景对比
2026-11-05 15:48:57
JavaScript入门要学ES6吗?let与箭头函数等新特性解析
2026-11-05 14:49:16
JavaScript 8种数据类型详解:基本类型与引用类型的区别
2026-11-05 14:25:15
怎么在JavaScript中使用async/await优化Ajax异步流程
2026-11-05 13:56:15
JavaScript replace回调函数实现动态正则替换逻辑
2026-11-05 13:52:13
