【学习笔记】在原生javascript中使用ActiveX和插件

什么是插件

现在的浏览器提供了大量的内置功能,但仍然有一些工作无法完成,如播放音频和视频。插件及其扩展浏览器功能就尤为重要。

插件是可下载的应用程序,可以插入到浏览器中,现在有很多不同的插件,常用的有Adobe Flash  Palyer ,Microsoft的Silverlinght和Apple的QuickTme播发器。

插件是封装了完成某项工作(播放音频文件)所需的所有功能的对象,对网站作者隐藏了复杂的细节,通常用C++或者JAVA等语言编写插件。

插件通常有某种用户界面,如QuickTme的用户界面可以显示播放/暂停的按钮,以及音量控件。

某些插件提供了对象的各种方法和属性,用户可以通过javascript访问,其方式与访问window对象的方法和属性一样。如QuickTme播放器插件提供的play()方法可以用于播放音频。

ActiveX控件

Microsoft与其他浏览器不同,它不支持插件,但它支持ActiveX控件,ActiveX控件提供了与插件相同的功能。

只需要进行几处修改,就可以通过几乎相同的代码使用ActiveX控件,其方式类似于在其他浏览器中使用插件。首先要确保ActiveX控件或插件可用,且可以运行在用户的浏览器中。在讨论如何使用插件和ActiveX控件之前,先详细介绍firefox和IE如何解决这个问题。

在非IE浏览器中检查并嵌入插件

通过创建脚本在网页上使用某个插件,除非网页访客在其计算机上安装了这个插件,否则访问该页面时就会得到一连串问题和错误信息。因此网页中正确添加使用插件所需的html,还要使用javascript检测用户的浏览器是否安装了页面要使用的插件。

在页面中添加插件

要使用安装在用户浏览器中的插件,必须使用html代码告诉浏览器,页面将在何时何处使用。这过程称为“嵌入(embedding)”插件。

<embed/>元素

在firefox中,嵌入插件的关键是非标准的<embed/>元素,该元素会在页面中指定位置嵌入插件的可视化界面。<embed/>元素支持很多可用于所有插件的通用属性,如height,width,src,pluginspage和type等。

绝大部分插件都显示保存在web服务器上的内容。如,处理音频的插件,如QuickTme播放器插件,可以播放带有各种扩展名的音乐文件,如.mp3和.mp4文件。flash插件可以播放flash动画(以.swf扩展名的文件)

<embed/>元素中的src属性指定插件要加载和播放的初始文件,这是一个指向文件的URL,利用该文件,浏览器会自己确定需要哪种插件。如src是http://www.xxx.swf浏览器通过检测该文件类型,就可以确定需要使用flash播放器插件。

但是并非所有的插件都需要通过src属性值来使用外部源中的数据,在这情况下,浏览器是如何确定应加载什么插件?可以使用<embed/>元素的type属性。type属性的值专用于某个插件。要找到这个信息,可以在浏览器地址栏中输入about:plugins然后回车,插件信息就会加载到浏览器中。

【学习笔记】在原生javascript中使用ActiveX和插件

图中列出了浏览器安装的所有插件。我这里演示的是360浏览器,点击页面右侧的详细信息按钮,就可以看到type属性需要的值MIME。

MIME

MIME值指定了内容类型,如网页,图片或flash文件。例如flash的MIME类型为application/x-shockwave-flash。

除了可用于所有插件的许多通用属性外,还可以使用<embed/>元素指定给某个插件的特有属性。如flash插件支持quality属性,用于flash动画的画面质量。

如代码:

<embed id="flashplugin" src="xx.swf" quality=hign height=100 width=100 type="application/x-shockwave-flash"/>

firefox不仅支持非标准的<embed/>元素,还支持使用html的标准<object/>元素在页面中嵌入插件,方式类似IE。

检查并安装插件

在页面中嵌入要添加的插件类型后,如果浏览器发现用户的计算机没有安装该插件,该怎么办呢?

<embed/>元素的pluginspage属性

可以使用<embed/>元素的pluginspage属性设置为执行插件创建者的页面的url.如果用户的计算机没有安装该插件,网页就显示pluginspage属性指定的URL连接。用户可以点击该连接,加载插件。

如flash的pluginspage属性值为:

http://www.adobe.com/shockwave/download/index.cgi?P1_Prod_Version=ShockwaveFlash

但是,如果用户并未安装插件,但想将用户重定向到一个不依赖该插件的网站版本上。那么该如何确定用户是否安装了某一个插件?

navigation对象有一个plugins属性,它是一个plugin对象的集合,每个plugin对象都表示浏览器安装的一个插件,要访问plugins数组中的plugin对象,可以使用索引值获得。

 注意:IE有一个navigation.plugins集合,但其总是为空。

每个plugin对象都有四个属性,description,filename,length和name。

length属性表示插件支持的MIME类型数量。

name属性可用于引用plugins数组中的plugin对象。

alert(navigator.plugins["Shockwave Flash"])

如果未安装flash,则返回的是undefined。

所以使用如下代码可以重定向浏览器未安装所需插件的用户:

if(navigator.plugins["Shockwave Flash"]){
window.location.replace("xx.html");
}else{
window.location.replace("xxx.html");
}

javascript把undefined视为false从而执行else语句,如果安装了flash,则navigator.plugins["Shockwave Flash"]返回flash的plugin对象,javascript把它视为true,从而执行if语句。

问题是:

同一插件在不同的操作系统中的名称可能不同,其中一些插件使用这中检测方法根本不可能可靠地工作。所以我们用遍历plugins[]数组的方法,检查每个name是否包含指定的关键字。

var plulength=navigator.plugins.length;
for (var i = 0; i < plulength; i++) {
var name=navigator.plugins[i].name.toLowerCase();
if(name.indexOf("quicktime")>-1){
alert("已经安装quicktime");
break;
}
}

for循环从0开始遍历navigator.pluginsk集合,直到最后一个元素。检查集合中每个插件的name属性是否包含quicktime,如果包含表示已经安装。

在IE中检查和嵌入ActiveX控件

尽管IE在一定程度上支持插件,但它对ActiveX控件的支持更加全面。ActiveX控件与插件的主要区别在于它们嵌入页面的方式和安装方式。一旦嵌入并安装了ActiveX控件,使用ActiveX控件和插件的脚本代码就是非常类似的。

ActiveX控件的创建者会为ActiveX控件分配一个唯一标识的字符串,我们可以使用该字符串精确地指定要在ie中嵌入哪个ActiveX控件。

在页面中添加ActiveX控件

需要是用<object/>元素。有两个重要属性classid和codebase可用于所有ActiveX控件。classid属性是ActiveX控件创建者为其分配的唯一ID。codebase属性是用于找到ActiveX控件的URL。

如何找到classid?

一种办法是检查ActiveX控件附带的文档说明,一钟是ActiveX控件创建者网站查找。

如果安装了ActiveX控件,也可以通过IE来查找。ie会说明计算机上安装了哪些可用于ie的ActiveX控件。尽管ie会提供ActiveX控件的相关信息,如classid,但不会提供安装在操作系统中的控件信息。

获得这类信息,只需打开IE,从菜单工具--》internet选项---》浏览历史记录中的设置---》查看对象---》打开即显示ie从internet上安装的所有ActiveX控件。

要在页面中插入flash ActiveX控件:

<object classid="clsid:D27CDB6E-AE6D-11cf-96B8-444553540000" id="falshp1" width="800"/>

还可以为该控件设置属性或参数值,如flash需要设置src属性,指向要加载的.swf文件。

设置ActiveX控件的参数

要设置ActiveX控件的参数与设置<object/>元素的属性不同,需要在<object>和</object>之间插入<param/>元素。在每个<param/>元素 中,需要指定要设置的参数名和参数值。如,要将src属性设置为xx.swf文件,则:

<object classid="clsid:D27CDB6E-AE6D-11cf-96B8-444553540000" id="falshp1" width="800">
<param name="src" value="xx.swf">
<param name="quality" value=""high>
</object>

安装ActiveX控件

前面介绍了怎么在页面中嵌入ActiveX控件,但是,如果用户没有在计算机中安装该控件,怎么办?

<object/>元素的codebase属性

<object/>元素的codebase,如果浏览器发现用户的计算机上没有安装ActiveX控件,就试图从codebase属性指定的URL中下载和安装该控件。

ActiveX控件的创建者提供了可用作codebase属性值的URL,可以通过前面介绍的internet选项中了解安装在计算机的控件的codebase(但这个URL不一定是最佳选择,因为该URL有可能还没有指向控件创建者的连接)。

对于flash其codebase是http://fpdownload.marcromedia.com/get/shockwave/cabs/flash/swflash.cab

<object classid="clsid:D27CDB6E-AE6D-11cf-96B8-444553540000" id="falshp1" width="800" codebase="http://fpdownload.marcromedia.com/get/shockwave/cabs/flash/swflash.cab">
<param name="src" value="xx.swf">
<param name="quality" value=""high>
</object>

如果有许可证,就可以把安装控件的.cab文件下载到自己的服务器中,并使用codebase属性指向该文件。

<object/>对象的readyState属性

表示对象的操作状态:

0:控件未初始化,还不能提供使用。

1:控件正在加载。

2:控件已经加载完数据。

3:尽管还未完全加载控件,但用户可以与控件进行交互。

4控件已经加载,可以使用。

控件必须有一定的时间来加载,所以,最好在窗口的onload事件处理程序中使用。

要将用户重定向到一个不需要该控件的页面:

function onload_win(){
var falshp1;
if(falshp1.readyState==0){
window.location.replace("xx.html");
}
}
onload=onload_win;

使用插件和ActiveX控件

将插件和ActiveX控件嵌入页面后,它们的实际用法就差不多。大部分插件和ActiveX控件的开发者使每个插件和ActiveX控件支持类似的属性,方法和事件,但一定要阅读说明文档,因为可能还是有一些不一致的特性。

在<embed/>或<object/>元素中,为插件或者控件设置唯一的Id值,就可以通过它访问相应对象的方法,属性和事件。

apple的QuickTime播放器:

它在非ie中使用的是插件,在ie中使用的ActiveX控件。

<object classid="clsid:02BF25D5-8C17-4B23-D3488ABDDC6B" codebase="http://www.apple.com/qtactivex/qtplugin.cab" id="atuopalyer" widht="0" height="0">
<param name="src" value="xx.mp3">
<embed height="0" width="0" src="xx.mp3" type="audio/mpeg" pluginspage="www.apple.com/quicktime/download" enablejavascript="true" name="atuopalyer"/>
</object>

用于非IE的<embed/>元素是<object/>元素的一个子元素,这些浏览器会忽略<object/>元素,仅显示由<embed/>元素定义的插件。而ie将忽略<embed/>元素,仅显示由<object/>元素定义的控件,尽管ie支持<embed/>.如果把<embed/>放在<object/>的外面,ie就会同时识别<embed/>和<object/>,但会混淆Id值,因为这两个元素的Id都为atuopalyer。

确定插件/ActiveX控件的可用性

我们想确保没有QuickTime的用户在尝试使用带有脚本的代码的控件时,看不到错误消息。

function win_onload(){
var pluginstalled=false;
if(!window.ActiveXObject){
var pluginslength=navigator.plugins.length;
for(var i=0;i<pluginslength;i++){
var pluginname=navigator.plugins[i].name.toLowerCase();
if(pluginname.indexOf("quicktime")>-1){
pluginstalled=true;
break;
}
}
}else{
if(document.audioPlayer.readyState==4){
pluginstalled=true;
}
}
if(!pluginstalled){//因为开始我们把pluginstalled定义为了false而if语句是true才能执行紧接if语句下面的代码,所以我们这里用了“非”。
alert("你需要安装quicktime");
}
}
onload=win_onload;
// 添加两个控制播放器播放和停止的按钮
function buttomplay_onclick(){
document.audioPlayer.Play();
}
function buttonstop_onclick(){
document.audioPlayer.Stop();
}

检查该插件或控件是否依赖浏览器,所以检查是否是Microsoft浏览器,如果不是ie浏览器,则使用for循环遍历navigator对象的plugins集合。如果找到QuickTime则将pluginstalled设置为true。如果检查ie则使用<object/>的readyState属性,如果为4表示可以使用,则将pluginstalled设置为true。

最后用if检查pluginstalled是true还是false,如果是false,就弹框他们需要quicKtime才能播放文件。

最后添加两个按钮功能,启动和停止音频文件的回放。

QuickTime插件和控件提供了Play()和Stop()方法,播放和暂停回放。这些函数中使用document访问了嵌入页面的QuickTime插件(控件),这两个脚本在所有浏览器中都会运行,但IE访问的是<object/>元素中定义的ActiveX控件,而非ie访问的是<embed/>元素中定义的插件。

潜在的问题

插件和ActiveX控件提供了一种扩展浏览器的功能的好方法,但其代价是由此带来的兼容性问题

1:相似但并不相同

尽管非ie浏览器中的插件和ie中对应的ActiveX控件所支持的属性和方法可能非常接近,但它们常常不尽相同。

2:插件的脚本编程有区别

在前面的QuickTime插件(控件)中我们直接使用使用该对象的Play()方法控制音频播放。但是如果为flash播放器编写脚本,则必须在html中给<embed/>定义如下属性

swliveconnect="ture"

否则,对该插件的任何访问都会造成错误。

<embed height="0" width="0" src="xx.mp3" type="audio/mpeg" pluginspage="www.apple.com/quicktime/download" enablejavascript="true" name="atuopalyer" swLiveConnect="true"/> 

3:操作系统之间的差异

不同的操作系统之间对ActiveX控件的支持存在较大的差异。要同时支持不同系统的用户,还需要编写更复杂的脚本。必须检查用户使用的是那种系统。

4:同一插件或ActiveX控件的不同版本之间的差异

ActiveX控件

可以在<object/>元素中的codebase属性中添加版本信息。

<object classid="clsid:AAA03-8BE4-11CF-B84B-0020AFBBCCFA" id="myconrol" codebase="http://myserver/mycontor.cab#version=3,0,0,0" ></object>

上面的代码不仅检查控件是否安装在用户的系统中,还检查安装的版本是否是3.0以上。

假定要检查某个控件的版本,如果该版本低于页面需要的版本,则将用户重定向到另一个页面。

对于ActiveX控件,没有一个简单的办法来使用javascript代码检查ActiveX控件的版本。一种办法是找到一个新控件支持而旧版本不支持的属性,检查它是否为null,ActiveX控件的创建者也有可能为其控件添加了某种version属性,以供检查控件的版本。

插件

对于插件,需要使用navigator对象的plugins[]数组属性包含的plugin对象,其中plugin对象的一个description属性可能包含了版本信息,但各个插件也有可能不同。

从字符串中提取版本号:

var myregexp=/\d{1,}.\d{1,}/;
var falshversion=navigator.plugins{"Shockwave Flash"}.description;
falshversion=parseFloat(falshversion.match(myregexp)[0]);

第一行代码定义了一个正则表达式,用来匹配一个或多个数字,后跟一句点和一个或多个数字。然后将该flash插件的description属性保存在变量falshversion中,最后,在字符串中查找与正则表达式匹配的字符串,并返回一个由于所有匹配组成的数组,然后在该数组中的第一个元素, 即索引为0的元素上使用parseFloat()函数。

5:ie6 server pack 1b和ActiveX控件的变化

Microsoft改变了ActiveX控件在ie中的运行方式,只要用户浏览了一个包含ActiveX控件的页面,就会显示该控件的一个警告,且默认禁止运行ActiveX控件,除非用户选择运行该控件。

可以通过两种方式避免这样的问题:

  1. 不访问任何外部数据,也不在定义中包含任何<param/>元素。如<object classid="CLSID:6BF52A52-394A-11d3-B153-00C04F79AA6"></object>
  2. 使用新的noexternaldata属性,指定不实用任何外部数据。如<object noexternaldata="true" classid="CLSID:6BF52A52-394A-11d3-B153-00C04F79AA6">

    <param name="URL" value="HTTP://msdn.microsoft.com/workshop/samples/author/dhtml/media/drums.wav">

    </object>这将忽略URL参数,不访问URL指定的外部数据(本例是.wav文件)

总结

  • 在window操作系统中,ie支持ActiveX控件以及部分扩展插件。非ie为插件支持大多插件,但不支持ActiveX控件。
  • 绝大部分插件的创建这也提供了等架到额ActiveX控件。
  • 使用<embed/>元素可以在网页中嵌入插件。使用<embed/>元素的src属性和type属性,指定源文件或MIME类型,就可以告诉非ie浏览器要嵌入哪个插件。如果定义了<embed/>元素的pluginspage属性的值,则未安装该插件的用户可以单击一个连接以安装插件。
  • 在地址栏中输入about:plugins回车,就可以找到非ie浏览器中安装的插件信息。
  • 要用脚本检查用户是否有某个插件,可以使用navigator对象的plugins集合,对于每个已经安装的插件,都在这个集合中定义了一个plugin对象。每个plugin对象都包含name,description,filename和length属性,可用于判断用户的计算机杀死功能是否存在某个插件。
  • ie支持ActiveX控件,作为插件的替代。ActiveX控件通过<object/>元素嵌入到页面中,通过classid属性指定需要的ActiveX控件。如果要为未安装某个控件的用户提供自动安装控件,需要指定codebase属性。
  • ActiveX控件的参数通过放在开闭<object/>标记之间的<param/>元素指定。
  • 通过<object/>对象的readyState属性,可以检查是否成功加载控件。返回值:0表示控件未安装,1表示控件在加载,2表示控件已经加载,3表示可以与控件交互,4表示控件已经加载完毕并可供使用。
  • 几乎每个不同类型的插件和ActiveX控件都提供了自己的界面,其文档提供了详细的说明。
  • 插件和ActiveX控件都有自己的一些问题,如它们在编写脚本的方式不同,操作系统的差异,版本差异。


上一篇:学习笔记——二叉树相关算法的实现(Java语言版)


下一篇:iOS 开发中使用到的小技巧汇总