【学习笔记】在原生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然后回车,插件信息就会加载到浏览器中。
图中列出了浏览器安装的所有插件。我这里演示的是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>
确定插件/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控件,除非用户选择运行该控件。
可以通过两种方式避免这样的问题:
- 不访问任何外部数据,也不在定义中包含任何<param/>元素。如<object classid="CLSID:6BF52A52-394A-11d3-B153-00C04F79AA6"></object>
- 使用新的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控件都有自己的一些问题,如它们在编写脚本的方式不同,操作系统的差异,版本差异。