Обновление:
Похоже, это ошибка в Chrome (и, возможно, мой код), так как он работает в Firefox
| top window | iframe | Google Maps
--------+------------+----------+--------------
Firefox | Good | Good | Good
--------+------------+----------+--------------
Chrome | Good | Bad | Bad
--------+------------+----------+--------------
Safari | Good | Bad | Good
--------+------------+----------+--------------
Не уверен, как Google Maps решает эту проблемув Safari, что код в фрагменте ниже не делает.
Сообщение об ошибке в Chrome, игнорируется более года .Начните пытаться привлечь внимание (или опубликуйте решение ниже?)
Оригинальный вопрос
Есть ли конкретная причина, по которой браузеры не могут разрешить захват мыши в iframe.
Примечание. Под «захватить мышь» я имею в виду, в частности, когда пользователь щелкает (mousedown) на элементе, и вы хотите следовать за мышью, пока они не отпустят мышь.
В окне верхнего уровня (не в фрейме) вы можете просто сделать это
const elem = document.querySelector('#elem');
const info = document.querySelector('#info');
elem.addEventListener('mousedown', handleMouseDown, true);
function handleMouseDown(e) {
e.preventDefault();
e.stopPropagation();
document.addEventListener('mousemove', handleMouseMove, true);
document.addEventListener('mouseup', removeMouseListeners, true);
info.textContent = `listeners added`;
}
function handleMouseMove(e) {
e.preventDefault();
info.textContent = `${e.clientX},${e.clientY}`;
}
function removeMouseListeners(e) {
document.removeEventListener('mousemove', handleMouseMove, true);
document.removeEventListener('mouseup', removeMouseListeners, true);
info.textContent = 'listeners removed';
}
#elem { background: red; padding: 1em; }
<div id="elem">click and drag outside window</div>
<div id="info"></div>
И это работает. Вот ссылка на версию, которой нет в iframe .Если щелкнуть красную область и перетащить за пределы элемента и даже за пределы окна, страница продолжит получать события, которые являются хорошим UX.Это то, как почти все нативные приложения работают.
К сожалению, как только вы помещаете этот образец в iframe, он больше не работает.Запустите приведенный выше фрагмент, щелкните и перетащите на красную область, переместите мышь за пределы кадра и события прекратятся, отпустите мышь, находясь за пределами рамки, а затем переместите мышь назад над рамкой и обратите внимание, поскольку событие mouseup не было доставленоэлемент начинает получать события, даже если вы не нажимаете кнопку мыши.
Мой вопрос заключается в том, какая конкретная причина для браузеров не делатьисправить это поведение?Не кажется, что есть какие-то проблемы с безопасностью?Кажется, ничем не отличается от перетаскивания за пределы окна против рамки.Похоже, что с use capture = true
, переданным addEventListener
, браузер может просто обрабатывать iframe так же, как и окно, и никакие события не будут просачиваться к родителю до тех пор, пока не будет снят захват.
Есть ли какая-то конкретная причинабраузеры не могут это исправить?Это ужасно опасный для пользователя пользовательский интерфейс, когда нужно перетаскивать разрыв на iframes.
Примечание: если вы хотите увидеть пример этого взлома, вставьте карту Google iframe и обратите внимание, что вы не можете продолжать перетаскивать за пределы рамки ивыше, если пользователь отпускает мышь за пределы рамки, карты застряли на мыши.
<iframe src="https://www.google.com/maps/embed?pb=!1m18!1m12!1m3!1d6006.922801276857!2d139.6993325020719!3d35.66665455496913!2m3!1f0!2f0!3f0!3m2!1i1024!2i768!4f13.1!3m3!1m2!1s0x60188cb46a006057%3A0xc502008398a3c24f!2z44CSMTUxLTAwNTIgVMWNa3nFjS10bywgU2hpYnV5YS1rdSwgWW95b2dpa2FtaXpvbm9jaMWNLCAyLCDkuK3lpK7luoPloLQ!5e0!3m2!1sen!2sjp!4v1537347056446" width="600" height="450" frameborder="0" style="border:0" allowfullscreen></iframe>