События с пропущенными указателями во вложенных iframes в Chromium 78 - PullRequest
0 голосов
/ 06 ноября 2019

Во-первых, это похоже на ошибку хрома, и я уже отправил отчет об ошибке . Он движется медленно, поэтому я открываю здесь вопрос главным образом для обходного решения , если кто-то еще сталкивался с подобными или связанными проблемами.

Кроме того, примеры кода не совместимы с HTML5 по причинам читабельности,Я просто показываю уменьшенный пример.

Описание

В бета-версии Chrome 78 и Edge, когда есть 2+ вложенных фрейма с различным происхождением и существует перекрывающийся элемент, pointerout/ pointerover события пропускаются между каждым кликом внутри iframe - только когда между pointerdown и pointerup происходит перемещение не менее чем на 1 пиксель. В Chrome 77, Edge stable, Firefox и Safari эти события запускаются только тогда, когда указатель покидает iframe или вводит его соответственно, что является правильным и ожидаемым поведением.

При удалении перекрывающегося элемента Chrome 78 ведет себя так, как ожидаетсяно бета-версия Edge этого не делает (бета-версия Edge не зависит от случая с перекрывающимися элементами).

При установке одинаковых источников iframe (например, на localhost) он работает в обоих браузерах, как и ожидалось.

Воспроизведение

Запустите сервер (например, http-сервер для простоты) в папке, содержащей следующие файлы

a.html

<iframe src="http://127.0.0.1:[port]/b.html"></iframe>
<div style="height: 3px;
    width: 300px;
    position: absolute;
    top: 159px;
    left: 10px;
    right: 0px;
    background: green;"></div>

b.html

<iframe src="http://localhost:[port]/c.html"></iframe>

c.html

<button id="btn">Click</button>

<script type="text/javascript">
    var btn = document.getElementById('btn');

    btn.addEventListener('pointerdown', function() { console.log('down'); });
    btn.addEventListener('pointerup', function() { console.log('up'); });
    btn.addEventListener('pointerover', function() { console.log('over'); });
    btn.addEventListener('pointerout', function() { console.log('out'); });
    btn.addEventListener('pointerleave', function() { console.log('leave'); });
</script>

Перейдите к localhost / a.html нажмите кнопку и проверьте консоль на наличие журналов событий.

enter image description here

Обратите внимание, что источники iframe в a.html и b.html различаются. С этим параметром, если вы переходите к 127.0.0.1, он ведет себя корректно, но на локальном хосте - нет.

Если вы перемещаете div в .html за пределы фреймов, он работает. (Только Chrome 78)

Вопрос

Есть ли потенциальные обходные пути? В идеале, использование JS или CSS, так как не всегда возможно искажать происхождение и домены iframe.

Что касается перекрывающегося div, иногда работает с z-index, но, опять же, это не лучшее решение, которое может иметь iframe. перекрывающиеся элементы.

1 Ответ

0 голосов
/ 07 ноября 2019

Просто идея для обходного пути: вы могли бы сравнить координаты в событиях выхода / выхода с последней известной позицией внутри элемента кнопки. Если координаты совпадают, игнорируйте события выхода / выхода. Также вам может понадобиться обработать событие размытия.

Допустим, у вас есть обработчик вниз, который устанавливает некоторые переменные (например, текущая позиция, нажатое состояние), а также подписывается на событие перемещения.

Ваш обработчик перемещения только обновляет текущую позицию.

Ваш обработчик выхода / выхода сравнивает текущую позицию с позицией события. Если они равны и не было события размытия, игнорируйте это событие и возвращайтесь из обработчика. В противном случае отмените печать, сбросьте переменные, отмените подписку и т.д.

...