使用modernizr确定是否支持多个窗口打开

时间:2016-06-07 17:41:35

标签: javascript google-chrome modernizr browser-detection

我遇到的问题记录在这里 window.open behaviour in chrome tabs/windows

你无法通过Chrome中的javascript打开多个窗口。

如果支持,我想打开多个窗口,如果不支持,我只返回一个链接列表。

有没有办法使用modernizr或浏览器嗅探以外的东西,我可以确定是否支持这种行为?

2 个答案:

答案 0 :(得分:1)

这种能够在浏览器甚至浏览器配置之间广泛打开多个窗口。 所以永远不要假设你能够打开多个弹出窗口,你可能会,但你只能通过测试知道,它很容易测试很难。

要测试是否打开弹出窗口,请检查返回值。

var popupWindow = window.open('http://www.google.com/');
if (!popupWindow) {
    console.log('the window did not open');
    // do other stuff
} 

如果窗口打开,返回值将是Window对象。 如果窗口没有打开,返回值将是假的,这个确切的返回值可以从弹出窗口阻止程序到弹出窗口阻止程序不同,但一般来说,如果窗口没有打开,你可以假设值是假的;意思是undefinednull 因此,如果窗口无法打开,则很容易触发替代方法。

您不需要modernizr或任何插件,返回Window对象的这种行为在所有浏览器中都是相同的。

MDN参考:
https://developer.mozilla.org/en-US/docs/Web/API/Window/open

Firefox和Safari似乎支持默认打开多个窗口。但是Chrome会阻止第二个窗口显示“弹出”阻止消息。 此外,Chrome还会阻止打开不是来自直接用户操作的窗口;意思是点击或按键。

答案 1 :(得分:1)

没有像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';
    }
});

这是一个表现出一切行动的小提琴:

https://jsfiddle.net/q8x5pqsw/