Я хочу иметь возможность определять, когда мышь покидает окно, чтобы я мог остановить запуск событий, пока мышь пользователя находится в другом месте.
Есть идеи, как это сделать?
Я хочу иметь возможность определять, когда мышь покидает окно, чтобы я мог остановить запуск событий, пока мышь пользователя находится в другом месте.
Есть идеи, как это сделать?
Ответы:
Этот тип поведения обычно желателен при реализации поведения перетаскивания на html-странице. Приведенное ниже решение было протестировано в IE 8.0.6, FireFox 3.6.6, Opera 10.53 и Safari 4 на компьютере с MS Windows XP.
Сначала небольшая функция от Peter-Paul Koch; кроссбраузерный обработчик событий:
function addEvent(obj, evt, fn) {
if (obj.addEventListener) {
obj.addEventListener(evt, fn, false);
}
else if (obj.attachEvent) {
obj.attachEvent("on" + evt, fn);
}
}
А затем используйте этот метод для присоединения обработчика событий к событию mouseout объектов документа:
addEvent(document, "mouseout", function(e) {
e = e ? e : window.event;
var from = e.relatedTarget || e.toElement;
if (!from || from.nodeName == "HTML") {
// stop your drag event here
// for now we can just use an alert
alert("left window");
}
});
Наконец, вот html-страница со встроенным скриптом для отладки:
<html>
<head>
<script type="text/javascript">
function addEvent(obj, evt, fn) {
if (obj.addEventListener) {
obj.addEventListener(evt, fn, false);
}
else if (obj.attachEvent) {
obj.attachEvent("on" + evt, fn);
}
}
addEvent(window,"load",function(e) {
addEvent(document, "mouseout", function(e) {
e = e ? e : window.event;
var from = e.relatedTarget || e.toElement;
if (!from || from.nodeName == "HTML") {
// stop your drag event here
// for now we can just use an alert
alert("left window");
}
});
});
</script>
</head>
<body></body>
</html>
Если вы используете jQuery, то как насчет этого короткого и приятного кода -
$(document).mouseleave(function () {
console.log('out');
});
Это событие будет срабатывать всякий раз, когда указатель мыши не находится на вашей странице, как вы хотите. Просто измените функцию на то, что хотите.
И вы также можете использовать:
$(document).mouseenter(function () {
console.log('in');
});
Срабатывать, когда мышь снова возвращается на страницу.
Это работает для меня:
addEvent(document, 'mouseout', function(evt) {
if (evt.toElement == null && evt.relatedTarget == null) {
alert("left window");
}
});
addEvent
?
if (!evt.toElement && !evt.relatedTarget)
Чтобы обнаружить оставление мыши без учета полосы прокрутки и поля автозаполнения или проверьте:
document.addEventListener("mouseleave", function(event){
if(event.clientY <= 0 || event.clientX <= 0 || (event.clientX >= window.innerWidth || event.clientY >= window.innerHeight))
{
console.log("I'm out");
}
});
Пояснения к условиям:
event.clientY <= 0 is when the mouse leave from the top
event.clientX <= 0 is when the mouse leave from the left
event.clientX >= window.innerWidth is when the mouse leave from the right
event.clientY >= window.innerHeight is when the mouse leave from the bottom
======================== РЕДАКТИРОВАТЬ ========================= ======
document.addEventListener ("mouseleave"), похоже, не запускается в новой версии Firefox, mouseleave необходимо прикрепить к такому элементу, как body, или дочернему элементу.
Я предлагаю вместо этого использовать
document.body.addEventListener("mouseleave")
Или
window.addEventListener("mouseout")
Использование события onMouseLeave предотвращает всплытие и позволяет легко определять, когда мышь покидает окно браузера.
<html onmouseleave="alert('You left!')"></html>
document.onmouseleave = function() { alert('You left!') };
используйте не document.body, которое запускает полосы прокрутки, которые сжимают тело! Код для предотвращения возгорания элементов не требуется. Хорошее объяснение: developer.mozilla.org/en-US/docs/Web/API/Element/…
Ни один из этих ответов не помог мне. Сейчас я использую:
document.addEventListener('dragleave', function(e){
var top = e.pageY;
var right = document.body.clientWidth - e.pageX;
var bottom = document.body.clientHeight - e.pageY;
var left = e.pageX;
if(top < 10 || right < 20 || bottom < 10 || left < 10){
console.log('Mouse has moved out of window');
}
});
Я использую это для виджета загрузки файлов методом перетаскивания. Это не совсем точно, срабатывает, когда мышь приближается к определенному расстоянию от края окна.
Я пробовал все вышеперечисленное, но ничего не работает, как ожидалось. После небольшого исследования я обнаружил, что e.relatedTarget - это html непосредственно перед тем, как мышь покинет окно .
Итак ... В итоге я получил следующее:
document.body.addEventListener('mouseout', function(e) {
if (e.relatedTarget === document.querySelector('html')) {
console.log('We\'re OUT !');
}
});
Пожалуйста, дайте мне знать, если вы обнаружите какие-либо проблемы или улучшения!
Обновление 2019
(как выяснил user1084282)
document.body.addEventListener('mouseout', function(e) {
if (!e.relatedTarget && !e.toElement) {
console.log('We\'re OUT !');
}
});
relatedTarget
имеет значение null, когда мышь покидает окно. Вдохновленный ответом @ user1084282, измените его на это: if(!e.relatedTarget && !e.toElement) { ... }
и он работает
if(!e.relatedTarget && !e.toElement)
вместо условия в фактическом ответе. Он обнаруживает, что мышь покидает тело документа.
Я беру то, что сказал. Это возможно. Я написал этот код, работает отлично.
window.onload = function() {
$span = document.getElementById('text');
window.onmouseout = function() {
$span.innerHTML = "mouse out";
}
window.onmousemove = function() {
$span.innerHTML = "mouse in";
}
}
работает в chrome, firefox, opera. Не тестировался в IE, но предполагаю, что он работает.
редактировать. IE как всегда доставляет неприятности. Чтобы он работал в IE, замените события из окна на документ:
window.onload = function() {
$span = document.getElementById('text');
document.onmousemove = function() {
$span.innerHTML = "mouse move";
}
document.onmouseout = function() {
$span.innerHTML = "mouse out";
}
}
объедините их для обнаружения курсора в кроссбраузере o0: P
примените этот css:
html
{
height:100%;
}
Это гарантирует, что элемент html займет всю высоту окна.
примените этот jquery:
$("html").mouseleave(function(){
alert('mouse out');
});
Проблема с наведением указателя мыши и наведением указателя мыши заключается в том, что если вы наведете указатель мыши на дочерний элемент или выйдете из него, это вызовет событие. Функция, которую я дал , не активируется при наведении указателя мыши на дочерний элемент. Он срабатывает только при выходе / вхождении курсора мыши в окно
просто чтобы вы знали, что вы можете это сделать, когда пользователь наводит курсор мыши в окне:
$("html").mouseenter(function(){
alert('mouse enter');
});
Я пробовал один за другим и нашел лучший ответ на тот момент:
https://stackoverflow.com/a/3187524/985399
Я не использую старые браузеры, поэтому сделал код короче для работы в современных браузерах (IE9 +)
document.addEventListener("mouseout", function(e) {
let t = e.relatedTarget || e.toElement;
if (!t || t.nodeName == "HTML") {
console.log("left window");
}
});
document.write("<br><br>PROBLEM<br><br><div>Mouseout trigg on HTML elements</div>")
Здесь вы видите поддержку браузера
Это было довольно коротко, я думал
Но проблема все еще оставалась, потому что «mouseout» срабатывает для всех элементов в документе .
Чтобы этого не произошло, используйте mouseleave (IE5.5 +). См. Хорошее объяснение по ссылке.
Следующий код работает без срабатывания по элементам внутри элемента, которые должны быть внутри или снаружи. Попробуйте также перетащить за пределы документа.
var x = 0
document.addEventListener("mouseleave", function(e) { console.log(x++)
})
document.write("<br><br>SOLUTION<br><br><div>Mouseleave do not trigg on HTML elements</div>")
Вы можете установить событие для любого HTML-элемента. Однако не document.body
включайте событие , потому что полоса прокрутки Windows может сжимать тело и срабатывать, когда указатель мыши находится над полосой прокрутки, когда вы хотите прокручивать, но не хотите запускать событие mouseLeave над ней. document
Вместо этого установите его , как в примере.
Может быть, если вы постоянно слушаете OnMouseOver в теге body, а затем обратный вызов, когда событие не происходит, но, как утверждает Зак, это может быть очень уродливым, потому что не все браузеры обрабатывают события одинаково, есть даже некоторые возможность того, что вы потеряете MouseOver, даже если окажетесь над div на той же странице.
Может быть, это поможет некоторым из тех, кто придет сюда позже.
window.onblur
и document.mouseout
.
window.onblur
срабатывает, когда:
Ctrl+Tab
или Cmd+Tab
.Практически всегда, когда ТАКАЯ вкладка браузера теряет фокус.
window.onblur = function(){
console.log("Focus Out!")
}
document.mouseout
срабатывает, когда:
Ctrl+Tab
или Cmd+Tab
.Практически в любом случае, когда ваш курсор покидает документ.
document.onmouseleave = function(){
console.log("Mouse Out!")
}
window.onblur
тоже. +1
$(window).mouseleave(function() {
alert('mouse leave');
});
Это сработало для меня. Комбинация некоторых ответов здесь. И я включил код, показывающий модель, только один раз. И модель уходит, если щелкнуть где-нибудь еще.
<script>
var leave = 0
//show modal when mouse off of page
$("html").mouseleave(function() {
//check for first time
if (leave < 1) {
modal.style.display = "block";
leave = leave + 1;
}
});
// Get the modal with id="id01"
var modal = document.getElementById('id01');
// When the user clicks anywhere outside of the modal, close it
window.onclick = function(event) {
if (event.target == modal) {
modal.style.display = "none";
}
}
</script>
var demo = document.getElementById('demo');
document.addEventListener("mouseout", function(e){demo.innerHTML="😞";});
document.addEventListener("mouseover", function(e){demo.innerHTML="😊";});
div { font-size:80vmin; position:absolute;
left:50%; top:50%; transform:translate(-50%,-50%); }
<div id='demo'>😐</div>