JavaScript window.open有时会返回null

时间:2014-04-11 18:02:51

标签: c# javascript window.open

我正在尝试维护一个我没写过的系统(而不是我们都写的?)。 Telerik报道,它是用C Sharp和JavaScript编写的。

JavaScript中包含以下代码,当用户单击按钮以在单独的窗口中显示报表时,该代码将运行:

var oIframe = $("iframe id='idReportFrame' style='display:none' name='idReportFrame' src=''>");
oIframe.load(function() { parent.ViewReports(); });

oIframe.appendTo('body');

try
{
  $('#idReportForm').attr('target', 'idReportFrame');
  $('#idReportForm').submit();
}
catch (err) { // I did NOT write this
            }

然后加载功能:

function ViewReports()
{
  var rptName = $("#ReportNameField").val();

  if (rptName == '') { return false; }

  var winOption = "fullscreen=no,height=" + $(window).height() + "left=0,directories=yes,titlebar=yes,toolbar=yes,location=yes,status=no,menubar=yes,scrollbars=no,resizable=no, top=0, width=" + $(window).width();
  var win = window.open('@Url.Action("ReportView", "MyController")?pReportName=' + rptNameCode, 'Report', winOption);
  win.focus();
  return false;
}

当我执行此操作时(至少在Chrome中),它会弹出窗口并将报告放入其中。但是,c#代码中的断点表示它被调用了2到3次。 JavaScript中的断点和Chrome中JavaScript调试环境中的小日志检查表明,对win.focus()的调用在成功之前失败一次或两次。它返回一个未定义的值,然后看起来上面的第一个例程再次执行。

我倾向于认为这是一种时间问题,除了window.open()调用应该是同步的,据我所知,我不知道为什么它有时会成功而不是其他人。有一个例程在窗口加载时执行,也许这会以某种方式搞砸open()返回的值。

我不是一个很多的JavaScript人,就像你们那些可能在这个时候所说的那样。如果我在这里放了一些代码,你可以告诉我这是不正确的,这很好;我更有希望的是能够解释弹出框架报告应该如何工作的人。希望我能够做到这一点,而不必替换我已经获得的太多代码,因为它很脆弱,而且,我们不会说,写的是重构的。

4 个答案:

答案 0 :(得分:0)

我发现window.open无法打开时会返回null。有些事情可能会阻止浏览器多次打开其他窗口;也许它是一个弹出窗口拦截器。

url的实际加载和窗口的创建是异步完成的。

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

答案 1 :(得分:0)

我只是碰到了这个问题,这似乎是因为我在Chrome开发人员工具中的一个叫window.open的行上有一个断点,并且正在逐步执行代码。这是一次反复无常的尝试,并且似乎多次失败(返回null,不打开窗口,无论是否已经存在)。

我阅读了@Joshua的评论,说创建是异步完成的,所以我发现强迫我每次执行步骤都使代码“停止”可能会以某种方式搞砸(尽管像var w = window.open(...)这样的单行没有这样做)。似乎不可能发生)。

所以,我取出了断点..,一切开始正常运行!

我还注意到了https://developer.mozilla.org/en-US/docs/Web/API/Window/open,其中他们指定如果您要重新使用窗口变量和名称(window.open的第二个参数),则建议使用某种代码模式。就我而言,我想为其编写HTML内容,而不是给它提供URL并让它异步地通过网络加载内容,并且我可能会反复调用整个函数,而无需考虑用户关闭弹出的窗口。所以现在我有了这样的东西:

var win; // initialises to undefined
function openWindow() {
    var head = '<html><head>...blahblah..</head>';
    var content = '<h1>Amazing content<h1><p>Isn\'t it, though?</p>';
    var footer = '</body></html>';

    if (!win || win.closed) {
        // window either never opened, or was open and has been closed.
        win = window.open('about:blank', 'MyWindowName', 'width=100,height=100');
        win.document.write(head + content + footer);
    } else {
        // window still exists from last time and has not been closed.
        win.document.body.innerHTML = content;
    }
}

我不认为应该为write调用提供完整的<html>标头,但这似乎对我来说是100%有效的。

[edit]我发现Stackoverflow上的代码段具有某种安全功能,可防止window.open,但此jsfiddle演示了上面的代码,并进行了调整以显示一个递增计数器以证明内容更新正在按预期进行。 https://jsfiddle.net/neekfenwick/h8em5kn6/3/

答案 2 :(得分:0)

迟到了,但是我认为这是由于窗口实际上没有在js中关闭或者内存指针未取消引用。 我遇到了同样的问题,我通过将调用括在try finally块中来解决了这个问题。

   try {
    if (!winRef || winRef.closed) {
        winRef = window.open('', '', 'left=0,top=0,width=300,height=400,toolbar=0,scrollbars=0,status=0,dir=ltr');
    } else {
        winRef.focus();
    }

    winRef.document.open();
    winRef.document.write(`
        <html>
            <head>
                <link rel="stylesheet" href="/lib/bootstrap/dist/css/bootstrap.min.css">
            </head>
            <body>
                ${$(id).remove('.print-exclude').html()}
            </body>
        </html>
    `);


    winRef.document.close();
    winRef.focus();
    winRef.print();
} catch { }
finally {
    if (winRef && !winRef.closed) winRef.close();
}

答案 3 :(得分:0)

<块引用>

弹出窗口阻止

过去,恶意网站经常滥用弹出窗口。可能会打开错误页面 大量带有广告的弹出窗口。所以现在大多数浏览器都试图阻止 弹出窗口并保护用户。

如果在外部调用大多数浏览器会阻止弹出窗口 用户触发的事件处理程序,如 onclick。

例如:

// popup blocked
window.open('https://javascript.info');

// popup allowed
button.onclick = () => {  
window.open('https://javascript.info');
};

来源:https://javascript.info/popup-windows