Использование modernizr, чтобы определить, поддерживается ли открытие нескольких окон
Проблема, с которой я столкнулся, описана здесь.
Поведение window.open в chrome tabs / windows
где вы не можете открыть несколько окон с помощью JavaScript в Chrome.
Я хотел бы открыть несколько окон, если это поддерживается, если это не поддерживается, я просто верну список ссылок.
Есть ли способ, используя Modernizr или что-то еще, кроме браузера, я могу определить, поддерживается ли поведение?
2 ответа
Это возможность открывать несколько окон, различных между браузером и даже с помощью конфигурации браузера. Поэтому никогда не думайте, что вы сможете открывать несколько всплывающих окон, но, возможно, вы сможете это сделать, но вы можете узнать только по тестированию, это очень легко проверить.
Чтобы проверить, удалось ли открыть всплывающее окно, проверьте возвращаемое значение.
var popupWindow = window.open('http://www.google.com/');
if (!popupWindow) {
console.log('the window did not open');
// do other stuff
}
Если открытое окно, возвращаемое значение будет Window
объект. Если окно не открылось, возвращаемое значение будет ложным, это точное возвращаемое значение может варьироваться от блокировщика всплывающих окон до блокировщика всплывающих окон, но обычно вы можете считать значение ложным, если окно не открывалось; имея в виду undefined
или же null
,
Таким образом, очень легко вызвать альтернативный метод в случае, если окно не открывается.
Для этого вам не нужны modernizr или какие-либо плагины, это поведение возврата объекта Window одинаково во всех браузерах.
Ссылка MDN:
https://developer.mozilla.org/en-US/docs/Web/API/Window/open
Firefox и Safari, по-видимому, поддерживают открытие нескольких окон по умолчанию. Chrome, однако, заблокирует второе окно и покажет маленькое "всплывающее" заблокированное сообщение. Кроме того, Chrome также блокирует открытие окон, которые не были созданы в результате действий прямого пользователя; что означает щелчок или нажатие клавиши.
Ничто, кроме modernizr или какого-либо другого пользовательского кода, не даст вам никакого типа обнаружения функций. Основная причина заключается в том, что все основные браузеры требуют каких-то действий пользователя, чтобы открыть новое окно программным способом - обычно одним щелчком мыши. Так что о создании функции обнаружения не может быть и речи.
Это интересный вопрос, в котором мышление в терминах "прогрессивного улучшения" может помочь вам найти хорошее решение.
Во-первых, давайте предположим, что вы не можете открыть несколько окон в любом браузере. Чтобы ты делал? Показать список ссылок, как вы предложили. Добавив что-то вроде target="_blank"
к каждой ссылке теперь у нас есть работающее приложение без JavaScript (или если у пользователя отключен JavaScript):
<section id="links-wrap">
<a href="/page-A.html" target="_blank" />
<a href="/page-B.html" target="_blank" />
</section>
Эта базовая функциональность будет работать на всех когда-либо созданных браузерах - ваши посетители Treo будут любить вас. Однако этот опыт не идеален, поскольку ссылки могут открывать новые вкладки вместо новых окон. Итак, давайте используем JavaScript, чтобы открывать новое окно при каждом нажатии на ссылку. Позволяет также скрыть каждую ссылку после щелчка и расположить каждое окно так, чтобы оно не перекрывалось:
function openWindowFromLink (link, idx) {
var top = idx % 2 * 600;
var left = Math.floor(idx/2) * 600;
var win = window.open(link.href, 'Window '+ top +'x'+ left, 'width=600,height=600,top='+ top +',left='+ left);
if (win) {
link.style.display = "none";
}
return win;
}
function handleLinkClick(ev) {
ev.preventDefault();
var link = ev.target;
var idx = 0;
var prev = link.previousSibling;
while (prev) {
if (prev.nodeType === 1) {
idx++;
}
prev = prev.previousSibling;
}
openWindowFromLink(link, idx);
}
document.getElementById('links-wrap').addEventListener('click', handleLinkClick);
Теперь самое сложное: как мы можем открыть много окон одновременно. Как мы знаем, Chrome будет разрешать открывать только одно окно за клик пользователя. Хотя другие браузеры могут не иметь такого же ограничения, они могут добавить его в будущем (на самом деле я удивлен, что они не все имеют это ограничение прямо сейчас). Итак, давайте предположим, что все браузеры имеют то же ограничение, что и Chrome. Пользователи не хотят нажимать каждую ссылку каждый раз - поэтому давайте дадим им цель щелчка, чтобы они могли нажимать очень быстро, чтобы открыть все окна. Творческая формулировка уменьшит раздражение этой задачи.
<div id="rapid-click-box">
Click me really fast and see what happens!
</div>
... и немного JavaScript:
var clickBox = document.getElementById('rapid-click-box');
var clickCount = 0;
clickBox.addEventListener('click', function handleRapidClick (ev) {
var link = links[clickCount];
if (link.style.display !== 'none') {
openWindowFromLink(link, clickCount);
}
if (++clickCount === links.length) {
clickBox.removeEventListener('click', handleRapidClick);
clickBox.style.display = 'none';
}
});
Наконец, давайте позаботимся о браузере, который позволяет открывать несколько окон одновременно. Нам все еще нужно, чтобы пользователь нажал, чтобы позвонить window.open
- так давайте проявим творческий подход и посмотрим, как мы можем заставить пользователя что-то щелкать. Должно хватить умного приветствия:
<div id="welcome-message" style="display:none">
<h1>Hey, welcome to my site. Are you a human?</h1>
<button>Yes</button>
</div>
<script>
// show the welcome message immediately if JS is enabled
document.getElementById('welcome-message').style.display = 'block';
</script>
... и еще раз, немного JavaScript:
var button = document.getElementsByTagName('button')[0];
button.addEventListener('click', function handleYesClick (ev) {
ev.preventDefault();
button.removeEventListener('click', handleYesClick);
document.getElementById('welcome-message').style.display = 'none';
for (var i = 0, l = links.length; i < l; i++) {
if ( !openWindowFromLink(links[i], i) ) {
break;
}
}
if (i === links.length) {
clickBox.style.display = 'none';
}
});
И скрипка, чтобы показать все это в действии: