【问题标题】:window.open blocked if performed in ajax completed如果在 ajax 中执行完成,window.open 会被阻止
【发布时间】:2013-12-27 06:44:53
【问题描述】:

我有这个由点击事件触发的 JS 函数。它应该存储一些数据,然后打开一个带有输入表单的窗口。原始代码是这样的:

function myClickFunction(){
    $('html').mask('Loading...');
    SaveData( function(){ //callback function
        window.open(...);
        $('html').unmask();
    });
}

问题是 window.open 被弹出窗口阻止程序阻止。如果我这样做:

function myClickFunction(){
    $('html').mask('Loading...');
    SaveData();
    $('html').unmask();
    window.open(...);
}

它工作得很好,但我当然只想在 SaveData() 完成时打开窗口。

SaveData() 执行 ajax 调用,并试图使解决方案 #2 工作,我尝试在 ajax 调用中设置 async: false 但这只会阻止我的 $('html').mask('Loading... ') 调用。

我的设置类似于https://stackoverflow.com/a/11670238/1480182,但另一个问题是它必须在 iPad 上的 Safari 上运行。在这个特定的浏览器中,无法与窗口/选项卡进行通信,这意味着当我打开新窗口时,我会在打开的选项卡上停止任何 js 执行:-(

我应该如何处理这个问题?

【问题讨论】:

  • 你需要一个真正的弹出窗口吗?你也许可以覆盖一个全尺寸的 iframe?
  • 请参阅下面的评论以回答
  • 你能打开一个新窗口来处理myClickFunction的所有功能吗?即显示加载屏幕,保存数据,然后设置位置。 (您也许可以使用 localStorage 来传输数据。)
  • 嗯...这可能是一种方式,但是...弹出窗口内容会有所不同,因为这是与多个弹出窗口一起使用的动态解决方案。重写代码以使用 jqueryui 可能更容易。什么是本地存储?这适用于旧版浏览器吗?
  • localStorage 是一个可以持久存储 Web 应用程序数据的地方(所有同源页面都可以访问它)。 cookie 的一个重要区别是它不会在每个请求(或永远)都发送到服务器。它是pretty well supported,但您可以随时使用不支持的 cookie(或使用 polyfill)。

标签: javascript window.open popup-blocker


【解决方案1】:

如果弹出窗口不是直接响应用户操作而打开的,则弹出窗口阻止程序通常会阻止这些窗口。因为 ajax 调用是异步的,所以它的完成功能是在用户操作之后的某个时间,并且就浏览器所知,它不会直接响应用户操作,因此它可能会被阻止。除了仅在直接响应用户操作时打开弹出窗口外,没有简单的方法可以解决此问题。

下一个明显的问题/解决方法是您是否真的需要单独的浏览器窗口/选项卡?您可以通过在原始窗口中使用叠加层来使您的应用程序正常工作吗?叠加层的限制为零,您可以用它做任何您想做的事情。

【讨论】:

  • 我尝试过使用 jqueryui 对话框,但这里的问题是弹出窗口的内容是从假设存在于它自己的窗口中的 url 加载的。这是一个现有的解决方案,所以我不能轻易重写。
  • @CJe - 您可以在对话框中放置一个 iframe 并将内容加载到 iframe 中。
【解决方案2】:

您可以打开一个新窗口并让它处理保存和重定向,而不是在myClickFunction 中进行。数据可以通过localstorage在页面之间传输。

例如,类似

function myClickFunction(){
    window.localStorage.tmpData = JSON.stringify(getData());
    window.localStorage.tmpRedirecturl = '...';
    window.open('saveandredirect.html);
}

在 saveandredirect.html 中

$(function(){
    $('html').mask('Loading...');
    var data = JSON.parse(window.localStorage.tmpData);
    var redirecturl = localStorage.tmpRedirecturl;

    delete window.localStorage.tmpData; // clear storage
    delete localStorage.tmpRedirecturl;

    SaveData(data, function(){
        window.location = redirectUrl;
        $('html').unmask();
    });
})

【讨论】:

    【解决方案3】:

    通过使用弹出窗口,您可以触发对客户端计算机的操作。您无法控制客户端计算机上的操作。用户可以随时禁用弹出窗口...我建议考虑使用jquery overlay 工具,它会将您的目标页面放在叠加层上...

    希望我能帮上忙!

    【讨论】:

      猜你喜欢
      • 2014-01-16
      • 2012-07-25
      • 1970-01-01
      • 2014-05-18
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多