Flash教程:网页中嵌入flash的最佳方案
小标 2018-05-29 来源 : 阅读 678 评论 0

摘要:在Flash教程中,各种浏览器差异悬殊,开发者应如何在网页中嵌入flash才是最佳方案?本文介绍的原理亦被应用在swfobject2.0中。“怎样才是最佳的flash嵌入方式呢?”希望本文对大家学习Flash教程有所帮助。

在Flash教程中,各种浏览器差异悬殊,开发者应如何在网页中嵌入flash才是最佳方案?本文介绍的原理亦被应用在swfobject2.0中。“怎样才是最佳的flash嵌入方式呢?”希望本文对大家学习Flash教程有所帮助。

本来应该是一个简单的问题,但是应该会引起很多不同的看法和争论,因为可用的嵌入技术很多,而每种都有其支持和反对者。这篇文章里,我将详述嵌入flash的复杂性和技巧性,并且对最流行的嵌入方法加以考察,看看它们到底好不好。 
好的flash嵌入方法的关键 
在进入本质性讨论之前,让我们先定义一下理想的flash嵌入方法。在我看来,下面这些因素是最重要的: 
遵循标准 
web标准为浏览器厂商、工具软件程序员以及网页作者提供了一种易于理解的通用语言,使得所有的用户都得以避免兼容性、垄断和专利侵权的问题。他们也让你——开发者——能够创建出项目所需的正确的网页。 
跨浏览器支持 
支持所有主流浏览器和常见操作系统是很关键的需求。为了支持我进行的研究,我创建了一个flash嵌入测试套件来评估浏览器对于各种嵌入方法的支持。该套件对各种不同的flash发布设置、流加载和脚本类型作了相应测试。 
对替换内容的支持 
无论何时你想要创建对搜索引擎和对未安装插件的浏览者友好的网页时,替换内容都是你最好的朋友。 
避免flash和播放器的不匹配 
不幸的是,对所有人来说,flash播放器总是试图去播放flash内容,不管flash播放器的版本和flash内容发布时的版本是什么。如 果使用老版本播放器的flash没有用到新版本播放器才支持的功能的话还好,否则你的用户将会看到不完整的内容或者完全就没有内容。 
对活动内容的自动激活[1] 
由于Eolas专利侵权问题,微软更新了它的浏览器,以至于浏览者再也不能直接与“活动内容”,也就是用object和embed标签嵌入的ActiveX控件进行交互。 
简而言之,微软浏览器要求用户先点击才能跟活动内容交互。为了避免被起诉,Opera也引入了类似的点击激活机制。这些机制就像公路上的减速带,你需要刹个车,慢慢开过去。它会让一般用户搞不清状况,让有经验的用户感到恼火。 
容易实现 
简单就是胜利。轻松就能做到的事情为什么要去费尽力气?

Flash嵌入基础:embed和object 
有两个标签可以让你在网页上嵌入flash。一个是已有的embed,所有的浏览器都支持它。(» 表示连接换行  -Ed) 

<embed type="application/x-shockwave-flash" » 
src="myContent.swf" width="300" height="120"  » 
pluginspage="//www.adobe.com/go/getflashplayer" /> 
<noembed>Alternative content</noembed>


另一个是W3C建议的object. 因为W3C规范给如何实现插件内容留了相当大的空间,结果出现了两种不同的object实现方式。 
大多数现代浏览器实现了遵循标准的方式,将embed标签替换为object的MIME类型,以此来确定插件的类型。 

<object type="application/x-shockwave-flash" » 
data="myContent.swf" width="300" height="120"> 
    <p>Alternative content</p> 
</object>

 
这种方式是各种浏览器通用的,所以是比较好的实现。

第二种实现来自Windows的IE,其中需要定义object的classid属性,这样浏览器才能正确载入Flash播放器的ActiveX控件。这种实现是有效的,但不是浏览器通用的。 

<object classid="clsid:D27CDB6E-AE6D-11cf-96B8- » 
444553540000" width="300" height="120"> 
    <param name="movie" value="myContent.swf" />     
    <p>Alternative content</p> 
</object>


注意:这两个例子中我都故意省略了codebase参数,这个参数通常指向Adobe的Flash插件安装包位置,用来在浏览器没有安装插件的时候自动下载。但这是和标准中禁止文档访问跨域资源的精神相违背的,而且有些现代浏览器并不支持。 
为什么还有embed 
从web标准的观点来看,可能会觉得直接砍掉embed标签就可以了,但这从来没有也永远不会成为一个W3C建议,因为专利问题。但是实际上它 确实比单独的object标签拥有更好的跨浏览器支持。所以它现在成了许多流行的站点诸如Google Video和Brightcove的选择。 
尽管web标准是为了避免兼容性问题而建立的,但embed却比W3C支持的object更为明确。embed的严格实现规范和良好支持已经把 它变成了一项事实上的标准,它会一直阴魂不散,直到object标签得到广泛并且足够长时间支持,长到已经可以忽略那些不喜欢它的浏览器版本。 
那么现在所谓的浏览器支持性的问题到底是什么? 
web标准不被支持的地方 
object的两种实现并没有摧毁web标准,但它是很多问题的根源。后果之一是,我们需要找一个方法去把两种object实现联合在一起构成一个统一的技术。更糟糕的是,我们不得不处理那些(曾经)对object不完全支持的浏览器。来看下这些问题: 
    * 一般的object实现在Windows IE下是不行的,IE加载了插件和swf文件,但却根本不显示flash内容。 
    * 我们加入movie参数,以部分地联合这两种方案的时候,IE可以显示flash内容了,但却不进行流加载。 
    * 当我们完全把两种方案联合在一起的时候,IE正常了,但是Gecko核心的浏览器忽略了Flash内容并且显示替换内容。 
object的一个特性是,你可以把不同的实现方案嵌套放在一起: 

<object classid="clsid:D27CDB6E-AE6D-11cf-96B8- » 
444553540000" width="300" height="120"> 
    <param name="movie" value="myContent.swf" /> 
    <object type="application/x-shockwave-flash" » 
data="myContent.swf" width="300" height="120"> 
        <p>Alternative content</p> 
    </object> 
</object>


不幸的是,老版本的IE在处理嵌套的object的时候存在bug:试图去渲染两个flash。 
更糟的是,Mac OS 10.3上,版本在1.2.2以下(含1.2.2)的Safari会忽略object里面嵌套的param标签,虽然他们支持embed标签的同样属性。 
注意:你可能会问你自己,上面的方法里把同样的内容、参数、属性写两遍到底有多大意义。比如说,这种联合方法让JavaScript跟Flash内容通信更困难,因为你要先测试你到底在跟哪个object通信。

我们朝着一个更好的世界缓慢的进步:这些bug中有的正在被逐渐解决,但是bug到无以复加的IE的object实现仍然使得object的采用困难重重。我们只能将解决的希望寄予在不久的将来了。

为什么object比embed更好 
尽管object缺乏跨浏览器的支持,但是object仍然比embed提供了更多的东西,为了跟进标准,它还提供了对于替换内容的良好支持。

object标签允许你在它里面包含替换内容,如果这种实现不被支持,或者插件没有安装,那么替换内容将被显示。这个内容还将被搜索引擎收录,使得它成为创建对搜索引擎友好内容的好帮手。

embed标签支持noebmed标签所提供的替换内容,但是它只被那些连embed标签都不支持的浏览器支持,例如Windows Mobile上的IE。不像object,当embed被支持但是却没有安装flash插件的时候,它并不支持替换内容。它依赖于pluginurl和 pluginspage属性来显示一个谜一样的破烂图片,点一下可以去安装插件。非常的90年代。

我相信提供一个关于插件内容的替换内容,并且同时给出巧妙的提示,让用户知道下载flash插件会获得更好的体验,这样的解决方案是更好的。(还有一个原因就是我们不是那么需要这个经常被用错的codebase属性) 
纯标签方法的局限性 
考虑一下我们之前定义的原则——顺应标准,跨浏览器支持,支持替换内容,避免播放器与内容不匹配,自动激活活动内容,和便于实现——显而易见的是仅靠标签能做到的太有限了。 
虽然标签表示了flash内容或替换内容的意义,但它没法给我们提供一种解决方案来避免flash内容和播放器不匹配或者一种变通方法来避免点击激活,而且它也并不总是最简单的实现方法。 
不过,还是简单的看一下现在最流行的标签“联合”方法吧。 
两次烹饪法 

<object classid="clsid:d27cdb6e-ae6d-11cf-96b8- » 
444553540000" codebase="//fpdownload.macromedia.com » 
/pub/shockwave/cabs/flash/swflash.cab#version=8,0,0,0" » 
width="300" height="120"> 
    <param name="movie" value="myContent.swf" /> 
    <embed type="application/x-shockwave-flash" » 
src="myContent.swf" width="300" height="120" » 
pluginspage="//www.macromedia.com/go » 
/getflashplayer" /> 
</object>


如你所见,这个办法仅仅把通用的和专用的标签弄在一起,显然是只为了解决跨浏览器支持问题,并不和标准兼容。 
两次烹饪法显得冗余,并且使你的网页不标准,还没有提供一种显示替换内容的机制。它易用的唯一原因是Flash IDE生成了它:所以,别再让任何人就凭着记忆像这样写了。 
嵌套object法 

嵌套object法是两次烹饪法的一个不错的替代品,因为它遵循标准并且支持替换内容。我们看下: 

<object classid="clsid:D27CDB6E-AE6D-11cf-96B8- » 
444553540000" width="300" height="120"> 
    <param name="movie" value="myContent.swf" /> 
    <object type="application/x-shockwave-flash" » 
data="myContent.swf" width="300" height="120"> 
        <p>Alternative content</p> 
    </object> 
</object>


不幸的是,它支持仍然缺乏跨浏览器的支持,对于IE的嵌套object bug和Safari的嵌套param bug仍然无能为力。一个常用的方法是利用IE的条件注释来避免这个浏览器的陷阱。 

<object classid="clsid:D27CDB6E-AE6D-11cf-96B8-» 
444553540000" width="300" height="120"> 
    <param name="movie" value="myContent.swf" /> 
    <!–[if !IE]>–>     
    <object type="application/x-shockwave-flash" » 
data="myContent.swf" width="300" height="120"> 
    <!–<![endif]–> 
        <p>Alternative content</p> 
    <!–[if !IE]>–>     
    </object> 
    <!–<![endif]–> 
</object>


除了前面提到的冗余问题,这个方法还更麻烦,因为它使用了一个丑陋的权宜方式,会使得用来生成页面的服务器端代码更加复杂。

Flash Satay 
另外还有个选择是Flash Satay方法,它用了传统的object方式,并且增加了额外的movie param来避免IE中不显示的bug。它还包括了一个容器flash来处理IE流加载bug。 

<object type="application/x-shockwave-flash" » 
data="c.swf? path=myContent.swf" width="300" height="120"> 
    <param name="movie" value="c.swf?path= » 
myContent.swf" /> 
    <p>Alternative content</p> 
</object>


虽然它很接近“理想的”object实现,但Flash Satay包含了一个使它的结构无法普适的权宜方案,并且它还不支持老Safari中的嵌套param。 
DOM脚本的方案 
在考虑纯标签方式的时候,也许你已经在想,为什么我们不用DOM脚本来替代呢。通过脚本,我们可以为每个浏览器提供所需的标签: 
    * IE专用的object标签 
    * 老版本的safari用的embed标签 
    * 所有其他的浏览器用的普通object 
DOM 脚本也具有足够灵活性来解决我们的其他问题:初始化的时候,我们可以用它来解决flash内容和播放器不匹配的问题。只需要对每个flash逐一检测插件 版本,并决定显示Flash还是显示替换内容。当需要的插件版本不足的时候,我们可以触发Adobe快速安装,一种可以在flash播放器内部下载安装控 件的简单机制。

DOM方案也让我们以动态写入的方式避免了点击激活机制。 
用Javascript的时候要考虑的事情 
因为不是每个人都是javascript专家——即使是专家,也没有必要重新去发明轮子——去用已有的javascript库嵌入flash是很明智的。让我们考虑一下选择一个值得信任的库所依据的原则。 
写库的人通常都不考虑遵循标准,因为这些库要么在javascript里面生成flash内容,要么在开发工具里面帮你做这个工作,大多数库生产的都是不标准的代码,而且由于是动态生成的,W3C验证器也没法检查你的标签。 
另外要考虑的是,当javascript被禁用,不支持,或者不被完全支持的时候,能否做到良好的退化。为了帮一小部分人提升用户体验而采用javascript,结果却弄得另一小部分人没法体验了,这样做的意义在哪里? 
带着这些问题,我们来看看现在流行的库能做到多好。 
Adobe Flash player detection kit 
除了在flash IDE里面生成标签代码以外,Adobe还提供了Flash播放器侦测套件。使用这个套件有三种方法: 
   1. 在flash8 IDE中勾上检测flash版本的多选框(在文件>发布设置>HTML)。 
   2. 下载侦测套件zip,然后手动加入。 
   3. 用Flex Builder2发布,默认就带。 
虽然侦测套件包含了我们想要的所有特性,像版本检测,快速安装,自动激活,但它仍然有改进的空间。如果考虑遵循标准的话,它就显然失败了:它仍 然基于两次烹调法,所以它要么生成微软的独门object,要么生成通用的不标准embed。它也支持替换内容但是以一种古怪的不统一的方式。你需要两次定义你的替换内容:在javascript里和在一个noscript标签里。然而一方面Flash IDE和侦测套件把设置替换内容的工作流给你,另一方面Flex Builder 2却默认会把整个两次烹调代码贴在noscript标签里面,用以在不支持javascript或者禁用了javascript的时候显示flash。 
总的来说,侦测套件在如何选择正确退化或者使flash内容对搜索引擎友好可访问这一点上,缺乏一种良好的策略和可以自圆其说的最佳方法。而且如果你需要自定义的话,它也并不是最简单的解决方法。 
UFO和SWFObject 
流行的开源替代品,例如我的UFO和Geoff Stearns的SWFObject,则可能是现在最完整和易用的库了。 
虽然他们表面上看起来很像,但是两个库在底层是非常不一样的。比如说,SWFObject使用Adobe的两次烹调法,而UFO则生成了最标准的标 签。另一方面,他们都遵循了相同的构架原则:当所需的flash和javascript存在时,使用DOM脚本重写网页上的替换内容。 
虽然他们都有对替换内容的支持,但是两个库都有一个共同的弱点,他们依赖javascript去插入flash,所以一小撮只有flash插件而没有javascript支持的用户就只能看见替换内容。 
低调的DOM脚本 

为了解决退化问题,使用一种低调脚本的嵌入方法会比较有效:这种混合方法使用Flash Satay那样的标准标签来嵌入Flash内容和替换内容,同时并不太显眼地调用DOM脚本,作为一种扩展来为浏览器解决问题和增加功能。 
ObjectSwap就是基于这样的原则,并且我认为将会是未来flash嵌入库的榜样架构。不幸的是,ObjectSwap注意力主要集中在解决自动激活上,所以在解决版本检测和诸如IE上的流bug和老Safari的param bug这样的标签支持问题上,就没有多大作用。另一个可以提高的地方在于——所有低调库都应该加以注意的是——性能。使用onload事件的话,你的 DOM相关代码只会在你整个页面,包括页面上的元素都加载完成后才执行。用DOMContentLoade事件来代替会更好,那就会在DOM加载完后立即触发。但是DOMContentLoade并没有被所有浏览器支持,你也许可以用这个方案代替。 
flash嵌入的未来 
虽然完美的方案也许还没有被写出来,但我确实觉得我们已经在正确的方向上走了很远。如果我们把不同库的好特性组合在一起,我们应该能够实现我们在文章开头定义的那些原则。为了研究这样的解决方案,Geoff Stearns和我已经共同工作,我们正在努力写一个新的标准的并且低调的解决方案,而不是重写UFO和SWFObject。它会最终替代这两个库。合作的成果是 SWFFix项目,现在是alpha阶段。[2] 
动作快点,软件老大们! 

虽然web开发者可以想出创新的变通方案来,但是只有浏览器和插件厂商可以做出真正实质性的进步。改掉那些明显的bug,采用支持web标准和替换内容的嵌入方法,他们可以让开发者得以用正确的方式来进行日常工作。所以软件老大们,觉得如何? 
by Kevin Cornell

译注:

[1]微软新的补丁已经在浏览器中取消了这个特性。

[2]UFO和swfobject1.5的升级替代品目前是swfobject2.0,实际使用的html是上面讲的条件注释方式。


网页中嵌入Flash的方法讨论

Flash 嵌入的问题论坛中有人问了好多次,到底应该怎么用,为什么通不过验证,要通过验证怎么办等等。 
讨论中也出现了不少的误解,所以我单开一个帖总结一下我所知道的东西,不想看我罗嗦的直接跳到最后看结论就可以了。

一、传统方法

 

<object classid="clsid:d27cdb6e-ae6d-11cf-96b8-444553540000" width="550" height="400">
   codebase="//fpdownload.macromedia.com/pub/shockwave/cabs/flash/
 
swflash.cab#version=7,0,0,0"
 
   width="550" height="400" id="Untitled-1"><param name="allowScriptAccess" value="sameDomain" /><param name="movie" value="mymovie.swf" /><param name="quality" value="high" /><param name="bgcolor" value="#ffffff" /><embed src="mymovie.swf" quality="high" bgcolor="#ffffff" width="550" height="400" name="mymovie" allowscriptaccess="sameDomain" type="application/x-shockwave-flash" pluginspage="//www.macromedia.com/go/getflashplayer">
 
</embed></object>

这方法是使用 object 和 embed 标签来嵌入,细心的会发现,object 的很多参数和 embed 里面的很多属性是重复的,为什么这样做?为了浏览器兼容性,有的浏览器支持 object,有的支持 embed,这也是为什么要修改 Flash 的参数时两个地方都要改的原因。这种方法是 Macromedia 一直以来的官方方法,最大限度的保证了 Flash 的功能,没有兼容性问题。但是它现在不那么好用了:

无法通过验证,由于为了兼容性而嵌入的 embed 标签是不符合 W3C 的规范的。当然,如果你不在乎什么规范不规范,另当别论。

微软由于种种原因,在 sp2 后限制了 IE 的 ActiveX 的使用模式,就是在页面中的 ActiveX 有一个虚框,需要用户点击一次才能正常交互。Flash是作为一个 ActiveX 嵌入到网页中的,所以它也会受牵连,只有通过 JS 嵌入 Flash 才能解决这个问题。

没有 Flash 版本检测,如果版本浏览器的flash插件版本不够,或者不能正常显示你的 swf 文件,或者会弹出一个 ActiveX 的确认安装的框——这个框对很多用户来说是很恐怖的。

二、只用 object 的方法

这种方法的名字叫做 Flash satay,最早是2002年由 Drew McLellan 发表在 A List Apart 上,后来又经过了几次完善:

 

<object type="application/x-shockwave-flash<br />
data="c.swf?path=movie.swf"<br />
width="400" height="300"><param name="movie" value="c.swf?path=movie.swf" /><img src="noflash.gif" width="200" height="100" alt="" /><br />
</object>

这方法没 embed 了,可以通过验证,是标准的嵌入 Flash 的方法,浏览器兼容性也不错,看起来几乎完美,不过还是有问题的:

需要一个 holder swf 来加载你的目标 swf 以保证 IE 中的 stream 能力,如果你需要通过 flashvars 来传参,或者和页面的 JS 交互,会很麻烦。

同上面第二点,ActiveX的虚框问题。

继续同上没有版本检测

还是有少数用户代理(比如一些版本的 safari 和一些屏幕阅读器)不认这种方式,有bug。

三、用JS嵌入的方法

用JS嵌入就是各有各的嵌入方法了,有嵌得好的有嵌得不好的。有人用 document.write 直接写,这法子说实话不大好,感觉 hack 成分多了,有点为了验证而验证的意思,而且没有体现出什么 JS 的优势。我觉得一个好的 JS 嵌入脚本,在保证 Flash 应有功能的基础上,⒒?JS 的优势应该要有版本检测,要能很好解决可访问性问题(也就是用户在无法浏览 Flash 内容或禁用 JS 的时候应该如何处理的问题),要易于重复使用。

我知道的比较常见的 JS 嵌入方法有以下几个:

SWFObject

UFO – Unobtrusive Flash Objects

Macomedia(现在是Adobe了..)提供的脚本[这里]和[这里]。

我 用SWFObject比较多,就挑它来说一些这种方法的优点:

IE中没有讨厌的虚框问题了。

提供了完善的版本检测功能,如果版本不够则显示其他东西,比如图片或文字。

易于使用,只要在页面头加载一个 .js 文件,然后 HTML 写一个容器,里面放普通的文本或图片(用于无法显示 Flash 时显示),最后用脚本来替换这个元素里面的内容为 Flash。

可以通过验证——当然这个不是重点,只是顺带效果罢了。

四、我的结论

现阶段用 JS 嵌入 Flash 是最完美的方法,虽然这法子这也是由于浏览器的种种问题而作出的妥协。

但它在保证 Flash 功能的前提下还利用 JS 提供了额外的好处,再者又已经有人写了很完善的嵌入脚本可以方面地下载使用(推荐 SWFObject),我们还有什么理由不用它呢?

SWFObject 那网页是英文的,这里写个简单的用法教程:

下载它的.js文件,在这里: //blog.deconcept.com/swfobject/swfobject1-4.zip (如果链接失效可能是版本有更新,请用上面给出的地址去主页下载最新版本)

在你的 HTML 页面头部<head>区嵌入这个脚本文件:<script type="text/javascript" src="swfobject.js"></script>

在你的 HTML 中写一个用来放 Flash 的容器,比如<div>,并随便给一个 id 比如 flashcontent。然后在里面放上你的替换内容。

<div id="flashcontent">

这里放替换内容,用来在 Flash 无法显示时显示。

</div>

使用脚本替换这个内容:

<script type="text/javascript">

   var so = new SWFObject("movie.swf", "mymovie", "200", "100", "7", "#336699");

//参数意思: 地址,Flash 的 id(不是容器的 id),宽,高,版本需求,背景颜色

//这是最基本的,如果你要高级的设置,就仔细翻翻说明吧。

   so.write("flashcontent");

</script>

这个脚本可以写在 HTML 中也可以写在外部 .js 文件中。

本文由职坐标整理并发布,了解更多内容,请关注职坐标常用软件Flash频道!

本文由 @小标 发布于职坐标。未经许可,禁止转载。
喜欢 | 0 不喜欢 | 0
看完这篇文章有何感觉?已经有0人表态,0%的人喜欢 快给朋友分享吧~
评论(0)
后参与评论

您输入的评论内容中包含违禁敏感词

我知道了

助您圆梦职场 匹配合适岗位
验证码手机号,获得海同独家IT培训资料
选择就业方向:
人工智能物联网
大数据开发/分析
人工智能Python
Java全栈开发
WEB前端+H5

请输入正确的手机号码

请输入正确的验证码

获取验证码

您今天的短信下发次数太多了,明天再试试吧!

提交

我们会在第一时间安排职业规划师联系您!

您也可以联系我们的职业规划师咨询:

小职老师的微信号:z_zhizuobiao
小职老师的微信号:z_zhizuobiao

版权所有 职坐标-一站式IT培训就业服务领导者 沪ICP备13042190号-4
上海海同信息科技有限公司 Copyright ©2015 www.zhizuobiao.com,All Rights Reserved.
 沪公网安备 31011502005948号    

©2015 www.zhizuobiao.com All Rights Reserved

208小时内训课程