1. 程式人生 > >【學習筆記】在原生javascript中使用ActiveX和外掛

【學習筆記】在原生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>
用於非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控制元件都有自己的一些問題,如它們在編寫指令碼的方式不同,作業系統的差異,版本差異。