代码之家  ›  专栏  ›  技术社区  ›  Ross Presser

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

  •  6
  • Ross Presser  · 技术社区  · 6 年前

    一些javascript如何告诉窗口鼠标按钮已被释放?mouseup事件由于跨域iframe而丢失。我能察觉到问题已经发生了,但我不知道该怎么办才能治好它。如果我可以强制鼠标指针的位置,问题就会消失;但是不允许javascript更改鼠标指针的位置。如果我可以“启动一个mouseup”,那么问题就会消失,因为它将替换丢失的mouseup事件;但是在一个新的mouseup事件上使用dispatchEvent不会起任何作用。

    情况:

    • 外部文档和内部iframe文档托管在不同的域上,都是https。不是相同基域的不同子域,而是不同的域。我的例子使用 www.pressero.com
    • iframe中的文本框输入,位于或靠近左边缘。标准LTR文本方向。
    • 几乎最小的例子: Demo1 为了方便修改iframe src,在外部文档中有一小块javascript。删除这个javascript根本没有效果。
    重要限制:
    • 发生 只有 使用Chrome和基于Chrome的浏览器;而不是Firefox、Safari、Edge或IE。
    • 对于是否所有Chrome客户端都会发生相同的情况,存在歧义。我个人在运行Chrome68或69的五台不同的Windows PC上复制了相同的行为。一位同事在运行chrome69的Mac上得到的结果与在同一台Mac上运行的Windows虚拟机上得到的结果略有不同。

    引发问题:

    • 试图选择文本框输入中所有文本的用户,使用鼠标,将鼠标从文本框的末尾移向开头。
    • 不经意间,用户将鼠标指针移过左边缘,从而从iframe移到外部文档中。
    • 在鼠标指针离开iframe后,用户释放鼠标左键。
    • 发生 只有
    • ctrl-A全选
    • 跳进田野
    • 使用鼠标从左到右选择文本
    • 使用鼠标选择文本,但要注意,释放鼠标按钮时,指针位于iframe内

    • 将鼠标指针放在文本框的左上角。
    • 按住鼠标左键。
    • 键入文本。它是反向插入的,因为每次击键后插入点都会重新定位到刚键入的字符之前。

    感知症状:

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

    相关症状:

    • 如果javascript正在使用中,例如用于调整对象大小的功能,或者在画布上拖动对象,那么即使在iframe外部释放左按钮之后,拖动仍将继续。即使将指针移回iframe内部,仍会继续拖动。
    • 事实上 mouseup alert() 把鼠标放在桌子上 body

    我再次强调这一点 只有铬 有这种行为。在Firefox、Edge或IE中执行完全相同的操作时,无论鼠标指针在何处,都会立即检测到鼠标按钮的释放。

    尝试的解决方法:

    • 建议用户小心鼠标位置。不是一个流行的解决方案。
    • 当文本框聚焦时,应用于文本框的Javascript选择all。这样就不需要使用鼠标进行选择,从而防止用户遇到问题。然而,这使得它不可能选择文本的小部分,而不是整个事情。

    通过将事件处理程序附加到 <body> 在外部文档中,我可以捕捉到鼠标。然后,我可以使用标准的postMessage技术告诉内部iframe窗口发生了mouseup。内部iframe知道拖动过程中哪个元素处于活动状态,所以这很好。然而,我在模拟mouseup事件时却一点运气都没有。我试过了 triggerMouseEvent here . 它运行正常,但显然什么也没做。 这里的演示有上面的最小示例,以及捕获外部文档中的mouseup、将消息发布到内部文档并调用 Demo2

    另一种奇怪的可能性

    Demo1a 链接不再有效 与上面的demo1相同,只是iframe元素的高度是710px而不是700px。 在我的测试机器上 这消除了错误。在我同事的测试机上,错误仍然存在。

    编辑2018-09-25

    我已提交 Chromium issue #882491 . 它还没有看到任何真正的活动。

    编辑2020-08-31

    因为我已经离开了我工作的公司,演示链接不再有效。

    1 回复  |  直到 4 年前
        1
  •  4
  •   Ross Presser    6 年前

    Chrome70已经修复了这个错误,并宣布将于2018年10月16日发布。我已经测试了Chrome70的测试版,我确认它确实被修复了。