【问题标题】:IE throws an "Object required" error when trying to use the Event Object from another window/frameIE 在尝试使用来自另一个窗口/框架的事件对象时抛出“需要对象”错误
【发布时间】:2010-08-25 22:33:04
【问题描述】:

我在正在开发的脚本中发现了一个 JavaScript 错误。我将它缩减为一对仍然会产生错误的相当简洁的页面:

如果您在 Internet Explorer 8(或者可能是 6 或 7,就此而言)加载第一页,请给它大约半秒钟的时间来运行脚本,然后单击 <iframe> 内的“Google”链接,您应该会看到一条错误消息:

http://skitch.com/troywarr/dui21/ie8-error

(您可能需要取消选中Tools > Internet Options > Advanced > "Disable script debugging (Internet Explorer)" 并选中"Display a notification about every script error" 下面两行才能看到错误消息。)

启动调试器会显示精美而富有洞察力的消息“需要对象”:

http://skitch.com/troywarr/dui26/ie8-debugging

罪魁祸首是这条线:

target = event_object.target || event_object.srcElement;

我认为这是有效的代码——至少它在 Firefox 中有效。我最好的猜测是,尝试从另一帧访问一帧的事件对象时存在问题 - 这与为什么您不能依靠 instanceof 来检测数组是否是在不同的窗口/帧中创建的(搜索对于http://javascript.crockford.com/remedial.html 的“上下文”,如果这没有意义)。

这听起来像是一个有效的理论吗?如果是这样,我该怎么做才能解决这个问题?如果可能的话,我需要保留相同的通用代码结构/功能:

  • 页面上的<iframe> 中有一个链接。
  • <iframe> 中的脚本调用父页面上的函数,该函数将事件处理程序附加到具有指定 id 属性的 <iframe> 中的元素。
  • 点击<iframe>d链接触发事件,该事件调用父页面上的函数,默认传递事件对象。
  • 父页面上的函数以跨浏览器兼容的方式从事件对象中确定有关单击元素(<a>)的信息。

我还想继续使用事件委托,并将所有函数保留在父文档中,只需使用 <iframe>d 文档中的参数调用它们。但是,如果您对替代方法有任何建议,我很乐意听取他们的意见。

提前感谢您的帮助!如果您需要更多关于我的要求或我正在尝试做的事情的解释,请告诉我——我希望有更好的方法来访问或传递我不知道的事件对象——“哦,是的,你只需要像这样”这样的解决方案。我希望这不是一厢情愿。 ;-)

【问题讨论】:

  • 毫无疑问,IE 对从一个页面迁移到另一个页面的对象非常敏感。我知道的最好的解决方案是将对象序列化为 JSON 并在页面之间移动一个简单的字符串。然后收件人页面可以重新创建对象的伪造版本。
  • 但是第一页在 IE8 中对我来说很好用。
  • 谢谢,Pointy - 当您单击第一页上的“Google”链接时,您没有看到 JavaScript 错误(需要等待大约半秒,脚本才能附加事件处理程序)?您确定您已将 IE 设置为显示所有 JavaScript 错误吗?
  • 不,我没有看到任何错误...我做 Web 开发,所以我的 IE better 会显示错误!不过,我现在会再次检查。
  • 哇,感谢您提醒我我的测试平台 IE 实例被搞砸了 :-) @Tim Down 已经发布了实际问题 - 您在 parentwindow.event /i> 窗口,当实际的事件对象将在 frame 窗口中时。

标签: javascript internet-explorer iframe event-handling dom-events


【解决方案1】:

很容易修复。您需要来自 iframe 的 window 的事件对象。将 iframe 的 window 对象存储在您存储其文档的位置旁边:

var iframe_win = document.getElementsByTagName('iframe')[0].contentWindow;

...并更新在事件处理函数中获取事件对象的行:

event_object = event_object || iframe_win.event;

【讨论】:

  • 是的。我没有看到错误,因为我的 IE 被欺骗了,但这就是问题所在。
  • 太棒了,谢谢蒂姆!那行得通。 contentWindow 属性是否跨浏览器兼容?
  • contentWindow 是非标准的,但至少在所有浏览器的最新版本中都受支持。 DOM 标准方式是contentDocument.defaultView。我决定不通过提及它来使事情复杂化,因为您已经在使用contentWindow :)
  • Earleir 版本的 Chrome 不支持contentWindow,因此您应该尽可能使用contentDocument
猜你喜欢
  • 1970-01-01
  • 2019-03-31
  • 2020-04-22
  • 2019-03-21
  • 2011-11-07
  • 2014-02-28
  • 1970-01-01
  • 2023-01-30
  • 1970-01-01
相关资源
最近更新 更多