Проверить, находится ли окно в фокусе, а также перевести внимание посетителя на него – сложно.
В первую очередь, это потому, что JavaScript не интегрирован с оконным менеджером ОС. Кроме того, браузер охраняет права посетителя: если он хочет скрыть окно, то JavaScript не может его остановить.
Но кое-что сделать, конечно, можно. Об этом и поговорим.
Метод window.focus
Метод window.focus
позволяет сфокусироваться на окне. Он работает по-разному в разных ОС и браузерах.
Проверьте, например:
setInterval(function() { window.focus() }, 1000);
Что будет, если запустить этот код, и затем переключиться в другое окно или вкладку?
Можно подумать, что окно будет оказываться в фокусе раз в секунду. Но это не так.
Произойдёт одно из трёх:
- Вообще никакого эффекта. Самый распространённый случай, если в окне много вкладок.
- Окно развернётся (при необходимости) и выйдет на передний план. Обычно это происходит, когда метод
window.focus()
вызывается для попапа, а активно сейчас – главное окно. То есть, в этом случае вызов сработает. - Заголовок окна начнёт мигать. Чтобы увидеть это в действии – откройте данную страницу в IE, запустите код и переключитесь на другое окно. Браузер попытается привлечь Ваше внимание миганием/мерцанием заголовка окна.
Мерцание заголовка
В дополнение к window.focus()
используют мерцание заголовка окна, как показано в примере ниже:
<script>
var win = open('/', 'test', 'width=300,height=300')
function getAttention(win) {
if (win.closed) {
alert( "Окно закрыто, привлечь внимание к нему нельзя" );
return;
}
win.focus();
var i = 0;
var show = ['************', win.document.title];
var focusTimer = setInterval(function() {
if (win.closed) {
clearInterval(focusTimer);
return;
}
win.document.title = show[i++ % 2];
}, 1000);
win.document.onmousemove = function() {
clearInterval(focusTimer);
win.document.title = show[1];
win.document.onmousemove = null;
}
}
</script>
<input type="button" onclick="getAttention(win)" value="getAttention(win)">
Запустите код и сверните всплывающее окно. А затем – нажмите кнопку с надписью «getAttention(win)». Браузер будет привлекать ваше внимание, как умеет ;)
Обратите внимание: в коде есть проверка на win.closed
. Попытка манипулирования закрытым окном вызовет исключение.
Как только посетитель сфокусировался на окне индикация прекращается. Для определения момента фокусировки в примере выше используется событие document.onmousemove
.
Можно было использовать событие window.onfocus
, но, оказывается, оно ненадёжно.
Событие window.onfocus
Вот переписанный вариант функции getAttention(win)
, с использованием события onfocus
:
<script>
var win = open('/', 'test', 'width=300,height=300')
function getAttention(win) {
if (win.closed) {
alert( "Окно закрыто, привлечь внимание к нему нельзя" );
return;
}
var i = 0;
var show = ['************', win.document.title];
function stop() {
clearInterval(focusTimer);
win.document.title = show[1];
}
win.onfocus = function() {
stop();
win.onfocus = null;
}
var focusTimer = setInterval(function() {
if (win.closed) {
clearInterval(focusTimer);
return;
}
win.document.title = show[i++ % 2];
}, 1000);
win.focus();
}
</script>
<input type="button" onclick="getAttention(win)" value="getAttention(win)">
Далее мы посмотрим случаи, когда он не срабатывает, и почему нам всё же нужно document.onmousemove
.
Когда событие onfocus не работает?
Возможно такое, что посетитель переключается на окно, а window.onfocus
не происходит.
Это потому, что переключение между окнами и фокусировка – это разные вещи. Например, если курсор находится в поле для ввода URL браузера, то считается, что окно не в фокусе, хотя посетитель переключился на это окно.
Попробуйте проделать следующее:
- Запустите пример с
getAttention
в Chrome или IE (кстати, в них нельзя отключить адресную панель). - Поместите курсор в панель адреса всплывающего окна.
- Перейдите обратно к главному окну и нажмите кнопку
getAttention(win)
Вы увидите, что несмотря на то, что вы переключились на окно, и оно сейчас на переднем плане, событие onfocus
не срабатывает.
Есть и другие случаи, когда переключение между окнами не вызывает window.onfocus
. Скажем, если окно сфокусировать щелчком в поле ввода формы, то в IE события window.onfocus
(а также window.onfocusin
) – не сработают!
Можно попробовать поймать момент фокусировки и по-другому, повесив дополнительные обработчики событий на document
. В главе Фокусировка: focus/blur описана техника делегирования для focus/blur
.
Но этот способ получает фокус только если посетитель сфокусируется где-то в документе: щёлкнет или сделает ещё какое-то действие в документе, а не просто посмотрит на него и проведёт над ним мышкой.
Впрочем, никто не мешает использовать сочетание всех описанных методов.
Итого
Фокусировка и привлечение внимания к окну:
-
Метод
focus
дляwindow
не надёжен. Окнами и вкладками браузера можно уверенно управлять только на уровне ОС.Поэтому для привлечения внимания посетителя к окну стоит также использовать мерцающий заголовок окна.
Обнаружение переключения на окно:
-
У
window
есть событиеonfocus
, но оно также ненадёжно.Поэтому для определения переключения на окно – используйте его вместе с делегируемым
focus
на документе, а такжеdocument.onmousemove
.