离开iframe时Mouseup丢失:导致输入反向

时间:2018-09-06 16:36:38

标签: google-chrome iframe chromium mouseup

TL; DR问题:

一些JavaScript如何告诉窗口释放了鼠标键?由于跨域iframe,mouseup事件丢失了。我可以检测到问题已经发生,但是我不知道该怎么办。如果我可以强制鼠标指针定位,问题将消失。但不允许使用javascript更改鼠标指针的位置。如果我可以“触发mouseup”,那么问题就会消失,因为它将替换丢失的mouseup事件。但是在新的mouseup事件上使用dispatchEvent则无济于事。

情况:

  • 任何最新版本的Chrome,任何操作系统。
  • 外部文档,其中包含位于其中的iframe。完全不需要JavaScript。
  • 托管在不同域(均为https)上的外部文档和内部iframe文档。同一基本域的子域没有区别,但实际上是不同的域。我的示例使用www.pressero.com和client-prototype.dev2.edocbuilder.com。证书是否有效(我的证书)仍然存在问题。
  • iframe中的文本框输入,位于左边缘处或附近。标准LTR文字方向。
  • 几乎是最小的示例:Demo1此文件的外部文档中只有一点点JavaScript,以便于更改iframe src。删除此javascript完全没有效果。

重要限制:

  • 在基于Chrome和Chromium的浏览器中 发生;而不是Firefox,Safari,Edge或IE。
  • 对于所有Chrome客户端是否相同,存在 一些 的歧义。我已经在大约五台不同的运行Chrome 68或69的Windows PC上重现了相同的行为。一位同事在运行Chrome 69的Mac上以及运行在同一Mac上的Windows VM的Chrome 69上得到了略有不同的结果。

触发问题:

  • 用户试图使用鼠标在文本框输入中选择所有文本,将鼠标从文本框的末尾移到开头。
  • 用户不经意间将鼠标指针移过了左边缘,因此从iframe中移到了外部文档中。
  • 用户在鼠标指针离开iframe后释放鼠标左键。
  • 仅当使用鼠标选择文本并且仅当鼠标左键释放时指针停留在iframe外部时,才会发生 。选择文本的其他方法不会导致症状:
    • ctrl-A全选
    • 进入该字段
    • 使用移位箭头选择文本
    • 使用鼠标从左到右选择文本
    • 使用鼠标选择文本,但请注意,释放鼠标按钮时,指针应位于iframe内

发生反向插入文本的另一种方法:

  • 将鼠标指针放在文本框的左上方。
  • 按住鼠标左键。
  • 输入文字。它是反向插入的,因为在每次击键之后,插入点都会重新定位到刚刚键入的字符之前。
  • 这仅是为了说明不良行为。显然这不是错误,因为它是人为显示的方式。

可察觉的症状:

  • 松开向左按钮后键入的文本以相反的顺序插入:即,键入“ abcde”将显示为“ edcba”,插入点位于第一个字符的左侧。

相关症状:

  • 如果使用的是javascript,例如用于调整对象大小或将其拖动到画布周围的功能,则即使在iframe外部释放左键后,拖动仍将继续。即使将指针移回iframe内,拖动仍会继续。
  • 通过将mouseup附加到iframe文档中alert()的mouseup上,可以证明确实丢失了body事件。如果在iframe内释放指针时释放了鼠标按钮,则会发生警报;如果指针在iframe之外而释放鼠标按钮,则不会发生这种情况。

再次,我强调 ONLY CHROME 具有此行为。在Firefox,Edge或IE中执行完全相同的操作,无论鼠标指针在何处,都将立即检测到鼠标按钮释放。

已尝试解决方法:

  • 建议用户注意其鼠标位置。不是一个流行的解决方案。
  • 已将Javascript应用于文本框,以便在文本框处于焦点状态时将其全部选中。这样就不必使用鼠标进行选择,因此可以防止用户遇到问题。但是,这使得无法选择文本的一小部分而不是全部内容。
  • 移动文本框,使其不紧靠左边缘。这样一来,当指针位于iframe外部时,用户放手的可能性就会降低。

捕获丢失的mouseup事件:

通过将事件处理程序附加到外部文档中的<body>,我可以抓住mouseup。然后,我可以使用标准的postMessage技术来告诉内部iframe窗口发生了mouseup。内部iframe知道在拖动过程中哪个元素处于活动状态,所以很好。但是,我在实际模拟mouseup事件方面没有任何运气。我已经尝试过triggerMouseEvent技术here。它运行无误,但显然没有任何作用。 这里的演示是上面的最小示例,另外还有管道来捕获外部文档中的mouseup,向内部文档中发布一条消息并调用triggerMouseEventDemo2

另一种奇怪的可能性

在尝试创建最少的示例时,我发现也许以某种方式涉及了盒模型。 Demo1a与上面的demo1相同,除了iframe元素的高度为710px而不是700px。 在我的测试机上,这消除了该错误。在我同事的测试机上,该错误仍然存​​在。

可能的相关跟踪的Chromium问题:

编辑2018-09-25

我已提交Chromium issue #882491。它尚未看到任何实际活动。

1 个答案:

答案 0 :(得分:4)

Chrome 70已修复了该错误,Chrome 70已宣布将于2018年10月16日发布。我已经在Beta通道中对Chrome 70进行了测试,并且确认确实已修复。