IE ActvieX更新产生影响的解决办法

一、问题背景和影响范围

由于专利问题,Microsoft 将被迫更改 IE 处理 ActiveX 控件的交互方式。所以Microsoft 即将发布一个用于 Microsoft Windows XP Service Pack 2 (SP2) 和 Microsoft Windows Server 2003 Service Pack 1 (SP1) 的 Microsoft Internet Explorer 6 的软件更新。据悉该更新将于6月2日正式开始。此更新可更改 Internet Explorer 处理某些使用 ActiveX 控件的网页的方式。使用 ActiveX 控件的程序包括以下这些:

  • Adobe Reader
  • Apple QuickTime Player
  • Macromedia Flash
  • Microsoft Windows Media Player
  • Real Networks RealPlayer
  • Sun Java Virtual Machine

安装此更新后,在启用 ActiveX 控件之前,您无法从某些网页与这些控件交互。要启用 ActiveX 控件,请手动单击该控件。Web 开发人员还可以使用其他技术来更新他们的网页。有关这些技术的更多信息,请访问下面的 MSDN 网站:http://msdn.microsoft.com/ieupdate

作为此 Internet Explorer 更新的一部分,Microsoft 会将更新发布到 Windows XP 和 Windows Server 2003 的当前版本中。所有客户端操作系统都将得到更新。这些客户端操作系统包括:

  • Windows XP Starter Edition
  • Windows XP Home Edition
  • Windows XP Professional Edition
  • Windows XP Tablet PC Edition
  • Windows XP Media Center Edition
  • Windows XP Professional for Embedded Systems

目前,Microsoft 尚未发布针对早期版本的 Internet Explorer、Windows Server 2003 或 Windows XP 的更新。但 Microsoft 以后可能会发布针对这些早期版本的更新。

二、产生的问题和表现

当网页用APPLET、EMBED和OBJECT标签下载的activeX控件,在控件的用户接口在用户激活之前是被阻止的。如果一个页面用这些标签下载多个控件,每个控件都需要分别被激活。

ActiveX未被激活时Flash的显示的效果

当一个控件处于未激活状态,它不会响应用户的输入,它只会执行操作,但不包括交互部分。当一个未激活的控件被创建,IE会用不同的技术来阻止键盘和鼠标的触发。例如,打开一个包含Flash的页面,Flash开始播放,但是它不会相应用户的交互请求,比如点击这个Flash而跳转到相应的URL,而是出现一个“单击以激活并使用此控件”,只有点击出发该控件,再次单击才出发跳转。

注意,控件不响应用户的直接交互,但相应脚本的请求。

激活一个交互控件可以点击,也可以通过Tab键设定焦点后按回格(Backspace)键或回车(Enter)键。

一些独立窗口的控件在IE中运行之前,会出现一个提示。

一些独立窗口的控件在IE中运行之前,会出现一个提示。用户需要点击信息窗口中的按钮来运行这个控件。控件下载后,不在需要激活。

下面的控件具有这种行为:

  • Virtools™ Web Player from Virtools SA
  • Macromedia Shockwave Player™ from Adobe Systems Inc.
  • QuickTime™ from Apple Computer, Inc.

所以页面运行时可能出现的问题有:

滚动
当使用鼠标轮在包含交互式控件的页面中滚动时,该控件可能无法正确显示。
抽象窗口工具包
据报告,在用户界面中使用抽象窗口工具包 (AWT) 类的 Java 程序中存在访问冲
透明 Flash
整页广告虽然消失,但焦点框仍在。在这种情况下,控件仍在原位置,但却是透明的。因此,关联的覆盖窗口留 在页面上。
DHTML 菜单
当展开一个 DHTML 菜单时,该菜单可能出现在 ActiveX 控件的顶部。在这种情况下,如果单击该菜单,则会启用该控件而不是访问 DHTML 菜单。覆盖窗口具有最高的 Z 顺序。因此,此窗口收到鼠标单击消息。
在加载之前进行提示的控件
在将某些控件加载到网页时,此更新的功能不会正确屏蔽这些控件。Macromedia Shockwave Director、QuickTime Player 和 Virtools Web Player 中使用的控件都属于这类控件。当 Windows 确定某个控件处于非活动状态时,系统会在加载该控件之前提示用户。
控件上的 CSS 属性
对于隐藏的控件,或者显示模式虽然设置为“无”但却具有尺寸大小的控件,当您将指针在它们上面移动时,将显示焦点框。

三、解决办法

虽然activeX控件不响应用户的直接交互,但相应脚本的请求,所以目前看到的解决方案都是通过外部的脚本来实现的。

1、Microsoft的解决方案

MS建议用外部的JScript文件下载控件实现用户可以直接和控件交互的问题。这个JScritpt文件必须是外部文件,如果直接写入网页HTML文件中,将不起作用。不能用JScript函数或者服务端脚本控制控件是否激活。具体实现方法如下:

1)使用document.write下载控件。

注意,不能在外部脚本文件通过 writeln函数来实现,因为该函数是把脚本插入到原始的HTML文档中。

<!-- HTML File -->
<html>
  <body leftmargin=0 topmargin=0 scroll=no>
    <script src="Embed.js"></script>
  </body>
</html>
// embed.js
document.write(’<embed src=”examplecontrol”>’)

外部文件也可以通过修改一个标签的outerHTML的属性来实现。

<!-- HTML File -->
<html>
  <body>
    <div>
      <script src="embedControlOuterHTML.js"></script>
    </div>
  </body>
</html>
// embedControlOuterHTML.js
embedControlLocation.outerHTML = ‘<embed src=”examplecontrol”>’;
2)用 document.createElement创建Object标签下载activeX控件。

注意:当用document.createElement在一个页面创建Object和Embed标签,要仔细创建标签和初始化它的属性,在通过新标签下载activeX控件前加入页面的DOM中。详细信息可以查看MS的createElement文档

<!-- HTML File -->
<html>
  <body>
    <div id="DivID">
      <script src="createElementExplicit.js"></script>
  </body>
</html>
// createElementExplicit.js
var myObject = document.createElement(’object’);
DivID.appendChild(myObject);
myObject.width = “200″;
myObject.height = “100″;
myObject.classid= “clsid:6BF52A52-394A-11d3-B153-00C04F79FAA6″;
myObject.URL = “example.wmv”;
myObject.uiMode = “none” ;
3)当有特别参数时,用innerHTML和JScript来下载activeX控件。
<!-- HTML File -->
<html>
 <head>
   <script src="external_script.js" language="JScript"></script>
 </head>
 <body>
   <div id="EXAMPLE_DIV_ID">
      This text will be replaced by the control
   </div>
   <script language="JScript">
     CreateControl( "EXAMPLE_DIV_ID",
                    "clsid:6BF52A52-394A-11d3-B153-00C04F79FAA6",
                    "EXAMPLE_OBJECT_ID", "600", "400", "example.wmv",
                    "-1")
   </script>
 </body>
</html>
// external_script.js
function CreateControl(DivID, CLSID, ObjectID,
                       WIDTH, HEIGHT, URL, AUTOSTART)
{
  var d = document.getElementById(DivID);
  d.innerHTML =
    ‘<object classid=’ + CLSID + ‘ id=’ + ObjectID +
    ‘ width=’ + WIDTH + ‘ height=’ + HEIGHT +’>
    <param name=”URL” value=’ + URL + ‘>
    <param name=”autoStart” value=’ + AUTOSTART + ‘/>’;
}

2、Adobe的解决方案

针对其产品 Macromedia Flash, Shockwave, or Adobe Acrobat files的解决方法。

  1. 当只有一个嵌入内容或少量的嵌入内容时,直接用一个独立的外部JS文件来下载activeX控件。
    1. 创建外部文件 foo.js
      function RunFoo()
      {
          document.write('<object classid="clsid:D27CDB6E..." ...>\n');
          document.write('<param name="movie" value="foo.swf" />\n');
          document.write('</object>\n');
      }
      
    2. 把foo.js加入相关页面的head标签中
      <script src="[path]/foo.js” type=”text/javascript”></script>
    3. 用下面代码替换 <object> , <embed> 和 <applet>标签<script type=”text/javascript”>RunFoo();</script>
  2. 当嵌入大量的活动内容,且嵌入方式多样,下面是一种很好的解决方案。
    1. 下载Adobe提供的必须js文件。该文件包括三个部分:
    2. 把AC_RunActiveContent.js加入相关页面的head标签中<script src="[path]/AC_RunActiveContent.js” type=”text/javascript”></script>
    3. 用下列函数来表达Object和Embed标签中的内容,并取代相关标签。

      用于Flash

      AC_FL_RunContent(
          "att1Name","att1Value",
          "att2Name","att2Value",
          ...
          "attnName","attnValue"
      );
      

      用于 Shockwave

      AC_SW_RunContent(
          "att1Name","att1Value",
          "att2Name","att2Value",
          ...
          "attnName","attnValue"
      );

      例如:

      
      <object classid="clsid:d27cdb6e-ae6d-11cf-96b8-444553540000"
      codebase="http://download.macromedia.com/pub/shockwave/cabs/flash/swflash.cab#version=7,0,19,0"
      width="550" height="400" align="middle">
          <param name="allowScriptAccess" value="sameDomain" />
          <param name="movie" value="foo.swf" />
          <param name="quality" value="high" />
          <param name="bgcolor" value="#ffffff" />
      <embed src="foo.swf" quality="high" bgcolor="#ffffff" width="550" height="400" name="foo" align="middle"
      allowScriptAccess="sameDomain" type="application/x-shockwave-flash"
      pluginspage="http://www.macromedia.com/go/getflashplayer" />
      </object>
      <script type="text/javascript" >
      AC_FL_RunContent('codebase','http://download.macromedia.com/pub/shockwave/cabs/flash/swflash.cab#version=7,0,19,0',
      'width','550','height','400','align','middle','src','foo','quality','high','bgcolor','#ffffff','name','foo',
      'allowscriptaccess','sameDomain','pluginspage','http://www.macromedia.com/go/getflashplayer','movie','foo' );
      </script> 
    4. 针对不支持script的浏览器,标签表达内容可以放入<noscript>标签中。

    3、使用deconcept 的flashObject

    flashObject是一个探测和嵌入Flash的javascript脚本。它能够所有在PC和MAC上的主流Flash插件,为嵌入Flash Movie而设计。它有利于搜索引擎,且能通过HTML验证。

    1. 下载FlashObject 1.3
    2. 把flashobject.js加入页面的head标签中
    3. 具体代码如下:

      HTML代码

      <object classid="clsid:d27cdb6e-ae6d-11cf-96b8-444553540000"
      codebase="http://download.macromedia.com/pub/shockwave/cabs/flash/swflash.cab
      #version=7,0,19,0" width="550" height="400" align="middle" id="foo">
          <param name="allowScriptAccess" value="sameDomain" />
          <param name="movie" value="foo.swf" />
          <param name="quality" value="high" />
          <param name="bgcolor" value="#ffffff" />
      <param name="flashvars" value ="variable1=value1&variable2=value2" />
      <embed src="foo.swf" quality="high" bgcolor="#ffffff" width="550"
      height="400" name="foo" align="middle" flashvars="variable1=value1&variable2=value2" allowScriptAccess="sameDomain"
      type="application/x-shockwave-flash"
      pluginspage="http://www.macromedia.com/go/getflashplayer" />
      </object>
      

      flashObject代码:

      <div id="flashcontent" style="width: 550px; height: 400px"></div>
      <script type="text/javascript">
         var fo = new FlashObject("foo.swf", "foo", "550", "400", "7", "#ffffff");
         fo.addParam("allowScriptAccess", "low");
         fo.addParam("wmode", "sameDomain");
         fo.addParam("quality", "high");
         fo.addVariable("variable1", "value1");
         fo.addVariable("variable2", "value2");
         fo.write("flashcontent");
      </script>
      
    4. 更多内容可以查看flashObject文档

    四、总结

    依据微软的技术信息和上述解决方案来看,解决问题的核心法就是实现active控件下载和主页面分离。其主要办法有两个:

    1. 利用javascript的document.write或innerHTML把下载activeX控件的标签从页面分离出去。
    2. 利用javascript构造activeX控件下载函数,把需要下载的activeX标签属性写入函数。

    采用js和页面分离是最容易实现的办法。但是从长远和易用性角度来看,应用flashObject类似的方法,是一个很好的选择。

    Reference:

    五、更巧妙的方法[2005.05.29]

    今天又发现一种解决方案,;利用原理是一样的,但是解决方案另辟蹊径,显示出非常高的技巧,该方法对原有页面有大量的通过js直接写在主页面上情况提供了非常便捷的解决方案。

    使用方法如下:

    1、把下面代码放入一个js文件中。

    if(typeof(dclk_isDartRichMediaLoaded) == "undefined") {
     dclk_isDartRichMediaLoaded = true;
     function dclkWrite(str){
      if(dclk_shouldOverride) {
       dclk_original_documentWrite(str);
      }
      else{
       document.write(str);
      }
     }
     function dclkWriteln(str){
      if(dclk_shouldOverride) {
       dclk_original_documentWriteLn(str);
      }
      else{
       document.writeln(str);
      }
     }
     function dclk_isInternetExplorer() {
      return (navigator.appVersion.indexOf("MSIE") != -1
                           && navigator.userAgent.indexOf("Opera") < 0);
     }
     dclk_shouldOverride = dclk_isInternetExplorer();
     if(dclk_shouldOverride) {
      dclk_original_documentWrite = document.write;
      dclk_original_documentWriteLn = document.writeln;
      document.write = dclkWrite;
      document.writeln = dclkWriteln;
     }
    }
    

    2、通过js链接方式把改代码链入到主文件的头部即可。

    注意,该段代码不能直接写入主文件中,也不能跨域调用。

    改代码通过链接嵌入的js函数,实现了document.write&document.writeln方法&主页面的分离,从而实现了需要触发activeX控件的HTML代码&主页面分离,非常的精巧。

    此代码不能解决一种情况,就是通过innerHTML属性写入需要触发activeX的HTML代码,不过通过上面解决问题的思路,应该也有合适的方法巧妙的解决。

    六、又一个巧妙的解决方案,殊途同归2007.11.14

    
    if(window.ActiveXObject){
    	var _FLash_Objects=document.all.tags("object");
    	for(var i=0;i<_FLash_Objects.length;i++){
    		var _t_obj=_FLash_Objects[i];
    			_t_obj.outerHTML=_t_obj.outerHTML;
    	}
    }

    ps,来自IEBlog的一个好消息:IE计划从2008年4月起通过升级实现无需点击使用ActiveX控件。

标签:, , , , ,

作者:秦歌,时间:2006-04-20 2:15,归纳于:Javascript & DOM & AJAX,订阅:RSS 2.0,引用:Trackback

有评论 4 条,发表一条评论 »

草上飞工作室说:2006-09-06 12:18 #1

很感谢!太好了!激动!感谢!

电脑精品教程网说:2007-09-10 10:18 #2

“当击以激活此控件”现在也还有.不过现在好像有的程序员故意在广告造成这种情况,很多人都会去点击以激活,结果点了广告

火星人路人甲说:2007-09-20 10:07 #3

总结的不错!

re说:2007-09-20 17:01 #4

TO 电脑精品教程网: 不是有些程序员故意这么做,而是被指使这么做,哈哈。

发表一条评论

您可以在下面评论内容中使用下列XHTML标签:
<a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>

您或许也喜欢看:

  1. Javascript在页面加载时的执行顺序
  2. 微软的便便
  3. 从未出家门超过48小时说起
  4. Javascript的匿名函数
  5. IE对CSS样式表的限制和解决方案
  6. Javascript风格要素(2)
  7. Javascript风格要素(1)
  8. Javascript的一种模块模式
  9. Ajax的小贴士
  10. 让网页上传文件控件只能选择不能编辑
回到页眉