HTML頁(yè)面嵌入視頻與JS控制切換視頻示例詳解

字號(hào):


    首先,在頁(yè)面中嵌入視頻的HTML代碼為: 
    代碼如下:
    <div id="youku"> 
    <object id="obx" name="obx" width="290" height="260"> 
    <param name="movie" value="http://pic02.newdu.com/uploads/202504/02/3913 name="allowFullScreen" value="true"></param> 
    <param name="allowscriptaccess" value="always"></param> 
    <param name="wmode" value="opaque"></param> 
    <embed src="http://pic02.newdu.com/uploads/202504/02/3913" type="application/x-shockwave-flash" allowscriptaccess="always" allowfullscreen="true" wmode="opaque" width="290" height="260"></embed> 
    </object> 
    </div> 
    其中,同時(shí)使用object和embed標(biāo)簽是為了兼容更多的瀏覽器,但請(qǐng)注意保持兩種標(biāo)簽下相同屬性值的一致。 
    PS:<object>和<embed>標(biāo)簽及其屬性的介紹和使用方法請(qǐng)參考OBJECT和EMBED標(biāo)簽一文。 
    然后,再說說如何用JS來(lái)動(dòng)態(tài)改變嵌入視頻的地址從而達(dá)到播放下一個(gè)視頻的目的。 
    這時(shí)好多人立刻就能想到用標(biāo)簽名或者DOM方式來(lái)找到上述param結(jié)點(diǎn)的value屬性和embed結(jié)點(diǎn)的src屬性,用JS動(dòng)態(tài)賦值來(lái)改變地址。但是測(cè)試發(fā)現(xiàn)視頻地址雖然被替換了,頁(yè)面上顯示的視頻卻還是原來(lái)的沒有改變,百思不得其解。 
    原來(lái),嵌入的這個(gè)object對(duì)象的所有參數(shù)是在頁(yè)面加載的時(shí)候初始化的,只有使其重新加載才能實(shí)現(xiàn)切換到下一個(gè)視頻進(jìn)行播放,單純改變它的地址屬性值是不起作用的。就像公司的某個(gè)員工,他的地址變了(搬家了),他還是原來(lái)的那個(gè)員工而不是其他人。 
    我經(jīng)常使用的使其重新加載的方法有兩種(以上述代碼為例): 
    ①用JS的obj.innerHTML方法將object對(duì)象整體進(jìn)行重置。 
    代碼如下:
    /*功能:動(dòng)態(tài)切換視頻*/ 
    function setvideo(url){ 
    var youku = document.getElementById("youku"); 
    var htmlstr = "<object id='obx' name='obx' width='290' height='260'>"; 
    htmlstr += "<param name='movie' value='"+url+"'></param>"; 
    htmlstr += "<param name='allowFullScreen' value='true'></param>"; 
    htmlstr += "<param name='allowscriptaccess' value='always'></param>"; 
    htmlstr += "<param name='wmode' value='opaque'></param>"; 
    htmlstr += "<embed src='"+url+"' type='application/x-shockwave-flash' allowscriptaccess='always' allowfullscreen='true' wmode='opaque' width='290' height='260'></embed>"; 
    htmlstr += "</object>"; 
    youku.innerHTML = htmlstr; 
    } 
    ②在div容器內(nèi)放置一個(gè)iframe,這樣可以動(dòng)態(tài)刷新iframe內(nèi)的頁(yè)面而不影響當(dāng)前父頁(yè)面。 
    具體的代碼就不寫了,大體的思路有: 
    1.采用url傳值。 
    2.父頁(yè)面或子頁(yè)面弄個(gè)隱藏域動(dòng)態(tài)存放地址供子頁(yè)面獲取。 
    3.采用①方法重置子頁(yè)面中object對(duì)象。 
    4.其他諸如window.open方法就繞遠(yuǎn)了,不推薦。 
    至此,嵌入和控制視頻切換都成功實(shí)現(xiàn)了。但是無(wú)意間,我發(fā)現(xiàn)一個(gè)問題: 
    切換到新的視頻之后,點(diǎn)刷新或按F5等任何方式的刷新頁(yè)面,都會(huì)彈出一個(gè)“缺少對(duì)象”的腳本錯(cuò)誤。找到錯(cuò)誤代碼,發(fā)現(xiàn)是Flash的內(nèi)部腳本錯(cuò)誤: 
    function __flash__removeCallback(instance, name) { 
    instance[name] = null; 
    } 
    如果頁(yè)面里使用了flash,并且flash里使用了flash.external.ExternalInterface.addCallback 方法,刷新網(wǎng)頁(yè)時(shí)就會(huì)報(bào)__flash__removeCallback的js錯(cuò)誤:缺少對(duì)象(Line 53),(Jscript-scriptblock)。此函數(shù)的調(diào)用處為: 
    __flash__removeCallback(document.getElementById(""), "dewprev"); 
    很顯然,這里document.getElementById("")返回的是null,才會(huì)導(dǎo)致__flash__removeCallback報(bào)錯(cuò),個(gè)人認(rèn)為這個(gè)flash的內(nèi)置方法或許應(yīng)該這么寫: 
    function __flash__removeCallback(instance, name) { 
    if (instance != null) { instance[name] = null; } 
    } 
    有人測(cè)試發(fā)現(xiàn),document.getElementById("")這里是獲取flash控件Object對(duì)象的id/name屬性的,之所以出現(xiàn)這個(gè)錯(cuò)誤,是因?yàn)闆]給Object設(shè)置id/name屬性,設(shè)置后就不會(huì)出錯(cuò)了??墒聦?shí)上我的object都是帶著id/name屬性的,因此不敢茍同此原因。由此看來(lái),這個(gè)加id/name的方法可以解決部分人的問題,引起此問題的原因并非僅此一種。 
    爾后,我苦苦找尋了好久,終于在一個(gè)外國(guó)網(wǎng)站上找到了解決的辦法,是一個(gè)叫Dave Smith的人寫的,我在他代碼的基礎(chǔ)上做了點(diǎn)改進(jìn),減少了頁(yè)面不斷執(zhí)行代碼的壓力。他提供的代碼如下: 
    代碼如下:
    <script type="text/javascript"> 
    (function(){ 
    var setRemoveCallback = function(){ 
    __flash__removeCallback = function(instance, name){ 
     if (instance){ 
    instance[name] =null; 
    } 
    }; 
    window.setTimeout(setRemoveCallback, 10); 
    }; 
    setRemoveCallback(); 
    })(); 
    </script> 
    他的意思大體就是:重寫flash內(nèi)部的這個(gè)腳本可以解決當(dāng)前的問題,但是當(dāng)object對(duì)象加載后某個(gè)時(shí)間,flash內(nèi)部的這個(gè)腳本又會(huì)覆蓋你重寫的這個(gè)函數(shù)。因此不能保證播放器到時(shí)會(huì)調(diào)用你重寫的函數(shù)。為了達(dá)到這個(gè)目的,他將函數(shù)設(shè)為每10毫秒覆蓋一下flash內(nèi)部提供的這個(gè)函數(shù)。這樣問題就解決了。同時(shí)他將這段代碼加以簡(jiǎn)化形成了以下兩個(gè)“版本”: 
    簡(jiǎn)化版本一:稍簡(jiǎn) 
    代碼如下:
    <script type="text/javascript"> 
    var setRemoveCallback = function() { 
    __flash__removeCallback = function(instance, name) { 
      if(instance) { 
    instance[name] = null; 
    } 
    }; 
    window.setTimeout(setRemoveCallback, 10); 
    }; 
    setRemoveCallback(); 
    </script> 
    簡(jiǎn)化版本二:超簡(jiǎn) 
    代碼如下:
    <script type="text/javascript">(function(){var s=function(){__flash__removeCallback=function(i,n){if(i)i[n]=null;};window.setTimeout(s,10);};s();})();</script> 
    我想了會(huì),理理思路: 
    這錯(cuò)誤是在刷新頁(yè)面時(shí)產(chǎn)生的,頁(yè)面刷新的過程就是舊頁(yè)面的消亡和新頁(yè)面的重載。理論上重載新頁(yè)面不會(huì)有什么問題,那么錯(cuò)誤就是產(chǎn)生在舊頁(yè)面消亡前的“善后”工作中。我只要在頁(yè)面消亡前將flash內(nèi)部這個(gè)回調(diào)函數(shù)重寫,就能達(dá)到同樣的目的,代碼如下,測(cè)試通過。 
    代碼如下:
    /*解決視頻切換內(nèi)部腳本錯(cuò)誤*/ 
    <script type="text/javascript"> 
    function endcall(){var s=function(){__flash__removeCallback=function(i,n){if(i)i[n]=null;};window.setTimeout(s,10);};s();} 
    window.onbeforeunload = endcall; 
    </script>