JavaScript window.open 有时会返回 null

问题描述 投票:0回答:5

我正在尝试维护一个我没有编写的系统(我们不都是这样吗?)。它是用 C Sharp 和 JavaScript 编写的,带有 Telerik 报告。

它在 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 人,正如你们中的那些人现在可能会说的那样。如果我放在这里的代码有什么地方不对,那很好;我更希望有人能解释弹出式报告框架应该如何工作。希望我可以做到这一点,而不必替换太多我已有的代码,因为它很脆弱,而且我们应该说,在编写时并没有考虑到重构。

c# javascript window.open
5个回答
7
投票

据我所知,window.open 无法打开时将返回 null。有些东西可能会阻止浏览器多次打开其他窗口;也许它是一个弹出窗口拦截器。

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

https://developer.mozilla.org/zh-CN/docs/Web/API/Window.open


2
投票

弹出窗口拦截

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

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

例如:

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

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

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


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% 有效。

[编辑] 我发现 Stackoverflow 上的代码片段有某种安全功能可以防止

window.open
,但是这个 jsfiddle 显示上面的代码有效,并进行了调整以显示递增的计数器以证明内容更新正常工作故意的。 https://jsfiddle.net/neekfenwick/h8em5kn6/3/


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();
}

0
投票

您必须指定新窗口的宽度和高度。 所以

window.open("https://avangsoft.ir/", "MyWindowName","width=100,height=100");

有效但

window.open("https://avangsoft.ir/", "MyWindowName");

不工作

© www.soinside.com 2019 - 2024. All rights reserved.