如何在不被浏览器阻止的情况下使用JSF打开弹出窗口 [英] How to open a pop-up using JSF without it being blocked by the browser

查看:65
本文介绍了如何在不被浏览器阻止的情况下使用JSF打开弹出窗口的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在开发PrimeFaces 6.0,JSF 2.2(Mojarra 2.2.7)应用程序.

I'm working on a PrimeFaces 6.0, JSF 2.2 (Mojarra 2.2.7) application.

我需要从外部站点加载网页并突出显示DOM节点.我的方法是创建一个JavaScript函数来打开一个弹出窗口,通过servlet加载网页(以避免跨域问题)并突出显示该节点.我发送给函数的参数是在托管bean中生成的.

I need to load a web page from an external site and highlight a DOM node. My approach is to create a JavaScript function to open a pop-up window, load the web page through a servlet (to avoid cross domain issues) and highlight the node. The parameters I send to my function are generated in a managed bean.

我试图通过两种不同的方式来做到这一点:

I tried to do so in two different ways:

  1. 在操作中使用 RequestContext.getCurrentInstance().execute("myFunction(...)")(是的,我正在使用PrimeFaces).
  2. 在命令按钮上使用 oncomplete =#{myBean.myJsCall}" .
  1. Using RequestContext.getCurrentInstance().execute("myFunction(...)") in my action (yes, I'm using PrimeFaces).
  2. Using oncomplete="#{myBean.myJsCall}" on my command button.

执行调用和调用正确的两种方式,但是我遇到了浏览器的(Chromium)弹出窗口阻止程序:

Both ways the call is executed and the call is correct, but I run into my browser's (Chromium) pop-up blocker:

有没有一种方法可以在JSF或PrimeFaces中打开弹出窗口而不会被阻止?

Is there a way to open pop-ups in JSF or specifically in PrimeFaces without them being blocked?

这并不是很重要,但这是我的JavaScript函数的简化版本.

This is not really relevant, but this is the simplified version of my JavaScript function.

我使用纯HTML和JS开发了此脚本.在那里,它打开了弹出窗口,而没有阻止程序进行干预.另外,在运行JSF应用程序时将呼叫粘贴到控制台中时,将弹出窗口.

I developed this script using plain HTML and JS. There it was opening the pop-up without the blocker interfering. Also, when pasting the call into the console when running the JSF application, the pop-up is opened.

function myFunction(url, selector) {
    var popup = window.open("", "popup", "height=500,width=700");
    var req = new XMLHttpRequest();
    req.open("GET", url, true);
    req.onreadystatechange = function() {
        if (req.readyState === XMLHttpRequest.DONE) {
            popup.document.open();
            popup.document.write(req.responseText);
            popup.document.close();
            popup.document.addEventListener(
                "DOMContentLoaded",
                function() { /* Some code highlighting the selector */ },
                false
            );
        }
    }
    req.send();
}

推荐答案

当您尝试在JavaScript中打开新窗口时,该窗口不是由用户操作(例如点击)直接触发的,而是例如由回调触发的执行JSF ajax请求后,浏览器将阻止它.

When you try to open a new window in JavaScript, which is not directly triggered by a user action (like a click), but in for example a callback triggered after executing JSF ajax requests, it is blocked by the browser.

以下问题描述了此行为: jquery window.open阻止ajax成功.

This behavior is described in the following question: jquery window.open in ajax success being blocked.

作为一种解决方法,您可以在JSF ajax请求之前打开一个窗口.如果是使用JSF HTML标签的命令按钮,则可以使用以下方法完成:

As a workaround you could open a window before the JSF ajax request. In case of a command button using the JSF HTML tags this can be done by using:

< h:commandButton ... onclick ="prepareWindow()"/>

onclick 将按原样呈现.但是,当您使用 PrimeFaces 时,您不能使用:

The onclick will be rendered as is. But, when you are using PrimeFaces, you cannot use:

< p:commandButton ... onclick ="prepareWindow()"/>

PrimeFaces包装 onclick 导致间接执行,因此弹出窗口被阻止.

PrimeFaces wraps the onclick resulting in indirect execution, so the pop-up is blocked.

无论如何,通过一些额外的技巧,您可以使用某种类似于PrimeFaces按钮的按钮来使用此按钮.但是黑客的数量越来越多.

Anyhow, with some extra hacks you could get this working with some sort of button which looks like a PrimeFaces button. But the number of hacks was getting too much.

我选择使用 p:dialog iframe .首先,如果您使用的是 p:layout ,请不要将对话框放置在任何布局单位中.

I opted to use a p:dialog with an iframe instead. To start of, if you are using p:layout, don't place the dialog in any of the layout units.

对话框:

<p:dialog header="Preview"
          widgetVar="previewDlg" modal="true" width="1000" height="600"
          dynamic="true">
    <iframe src="about:blank"
            class="previewIframe"
            style="position:absolute;top:0;left:0;right:0;bottom:0;width:100%;height:100%;border:0"></iframe>
</p:dialog>

按钮:

<p:commandButton value="Show"
                 ...
                 onclick="PF('previewDlg').show()"
                 action="#{myBean.showPreview('previewIframe')}"/>

动作:

public void showPreview(String iframeClass) {
    ...
    RequestContext.getCurrentInstance().execute(js);
}

JavaScript函数:

The JavaScript function:

function myFunction(iframeClass, url, selector) {
    var iframe = $("iframe[class=" + iframeClass + "]")[0];
    iframe.contentDocument.location = "about:blank";
    var req = new XMLHttpRequest();
    req.open("GET", url, true);
    req.onreadystatechange = function() {
        if (req.readyState === XMLHttpRequest.DONE) {
            iframe.contentDocument.open();
            iframe.contentDocument.write(req.responseText);
            iframe.contentDocument.close();
            iframe.contentDocument.addEventListener(
                "DOMContentLoaded",
                function() { /* Some code highlighting the selector */ },
                false
            );
        }
    }
    req.send();
}

这篇关于如何在不被浏览器阻止的情况下使用JSF打开弹出窗口的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
相关文章
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆