在 IE6/7 中使用 IHTMLElement5/6(对于 IE8/9)会发生啥?它会转向 IHTMLElement 行为吗?

Posted

技术标签:

【中文标题】在 IE6/7 中使用 IHTMLElement5/6(对于 IE8/9)会发生啥?它会转向 IHTMLElement 行为吗?【英文标题】:What happens when using IHTMLElement5/6 (for IE8/9) in IE6/7? Does it divert to IHTMLElement behaviour?在 IE6/7 中使用 IHTMLElement5/6(对于 IE8/9)会发生什么?它会转向 IHTMLElement 行为吗? 【发布时间】:2012-03-26 01:04:28 【问题描述】:

基本上,根据以下版本控制规则,IhtmlElement5 和 IHTMLElement6 都是主 IHTMLElement 的扩展接口:

IHTMLElement    IE4
IHTMLElement2   IE5
IHTMLElement3   IE5.5
IHTMLElement4   IE6
IHTMLElement5   IE8
IHTMLElement6   IE9

当然,每个新的扩展接口中都有旧成员+它自己的新成员、属性等。但是,有些成员(例如,.getAttribute)名称相同但已更新。所以,我的问题是,如果我使用(比如说)IHTMLElement6 来声明我的 HTML 元素并在只安装了 IE6 的客户端上运行代码,我的对象什么时候会失败并在我设置它时保持为 Null/Nothing,或者是mshtml.dll 足够聪明,可以意识到发生了什么并且默认为 IHTMLElement4(实际上是 IHTMLElement)行为?

为了澄清括号中的最后一条语句,.getAttribute 已添加到 IHTMLElement 中,并在 IHTMLElement5 和 IHTMLElement6 中进行了更新-因此,如果有人仅安装了 IE6,那么我希望该行为默认/恢复为 IHTMLElement(不是 IHTMLElement4 ) - 如果它不这样做,那么我希望我的代码会崩溃。基本上,我的问题是,究竟会发生什么?

现在,因为我害怕得发疯,我只是将所有内容都声明为 IHTMLElement,有什么想法吗?

谢谢。

问题摘要(如果您认为有必要,请阅读,仅供需要的人使用): 基本上,我希望能够将某些东西声明为 IHTMLElement6,这样我就可以使用在 IHTMLElement 和 IHTMLElement6 之间具有相同名称的更新方法(例如 .getAttribute)。这样,在 IE9 用户上,IHTMLElement6 的 .getAttribute 版本将被利用,同时 IHTMLElement 的 .getAttribute 版本仍然适用于(比如说)IE6 用户而不会破坏我的代码 - 这就是我的问题所在,当使用 IHTMLElement6 对象时,即使它是 IE9 接口,IHTMLElement 的(IE4 接口)版本的 .getAttribute 是否会启动/工作,还是会出现空引用异常或其他运行时错误?谢谢大家。

回复越多越好,即使这是您的意见并且您不知道这是事实,我鼓励您仍然发表评论,同时让我们知道您是否知道这是事实只是意见/猜测等。谢谢。

【问题讨论】:

【参考方案1】:

如果你支持像 IE6 这样的旧浏览器,那么根据规范 .getAttribute 将失败并会在 IE6 上的 js 中弹出错误。为了避免这种情况发生,您必须以这样一种方式处理,即如果代码失败,那么它应该静默失败。

因此,无论您使用过 .getAttribut,只要设置一个 if 条件检查此属性是否存在,如果不存在则使用较旧的属性,即 .getAttributeNode 否则使用 .getAttribute

例如

if(obj.getAttribute)
   return obj.getAttribute;
else
   return obj.getAttributeNode;

【讨论】:

谢谢,我为我的问题添加了一个摘要,供任何需要它的人使用,基本上,我的问题更多的是关于我是否可以使用 IHTMLElement6 接口/对象并且仍然拥有 IE4 的 .getAttribute 版本IE6 用户,既然 .getAttribute 是在 IE4 中添加并在 IE8 和 IE9 中更新的,这有意义吗?希望我不需要进行版本检查并为 IE6 和 7 用户声明 IHTMLElement,然后为 IE8 用户声明 IHTMLElement5,为 IE9 用户声明 IHTMLElement6,只是想使用 IHTMLElement6 并让它适用于所有版本,现在我正在使用IHTMLElement 只是为了安全。【参考方案2】:

我怀疑在不支持 IHTMLElement6 的旧版 IE 中,将 DOM 元素强制转换为 IHTMLElement6 会失败并返回 InvalidCastException。您将没有机会致电IHTMLElement6.getAttribute(),因为您一开始就无法获得有效的IHTMLElement6 引用。

如果这是正确的,那么您已经在做的事情(使用IHTMLElement)似乎是正确的做法。

更新:我的怀疑是正确的。我编写了一个 WinForms 应用程序,它引用了 IE9 附带的 mshtml.dll 版本。在使用 IE9 的系统上,应用程序成功地将 <img> 元素转换为 IHTMLElement6。但在 IE8 系统上,同样的转换失败:

System.InvalidCastException:无法将“mshtml.HTMLImgClass”类型的 COM 对象转换为接口类型“mshtml.IHTMLElement6”。此操作失败,因为 IID 为“305106F8-98B5-11CF-BB82-00AA00BDCE0B”的接口的 COM 组件上的 QueryInterface 调用因以下错误而失败:不支持此类接口(HRESULT 异常:0x80004002 (E_NOINTERFACE)) .

【讨论】:

非常感谢您的cmets,我只是想问一下您对此的确定程度,也想邀请其他人评论他们所知道的,即使这只是他们的猜测,那也很好。我希望情况并非如此,但如果是这样,我很高兴知道,因为我不知道我应该以哪种方式做事(即:这个问题的最佳编程实践是什么)。再次感谢您的 cmets,投了赞成票,但将保持问题开放,以收集任何愿意参与的人的更多意见。干杯伙伴。 你太棒了!感谢您的测试,它现在澄清了我们的问题:)

以上是关于在 IE6/7 中使用 IHTMLElement5/6(对于 IE8/9)会发生啥?它会转向 IHTMLElement 行为吗?的主要内容,如果未能解决你的问题,请参考以下文章

为啥 videojs 不能在 IE6/7/8 中播放我的 Flash 视频?

IE6/7 和类名 (JS/HTML)

在 IE6 和 IE7 中将宽度正确拉伸到内联块元素的 100%

jQuery解决IE6、7、8不能使用 JSON.stringify 函数的问题

img标签中的alt属性在IE6/7/8中的兼容问题

IE6 支持jquery么