gpt4 book ai didi

javascript - 如何使用 JSF 打开弹出窗口而不被浏览器阻止

转载 作者:行者123 更新时间:2023-11-30 15:54:42 24 4
gpt4 key购买 nike

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

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

我尝试以两种不同的方式这样做:

  1. 在我的操作中使用 RequestContext.getCurrentInstance().execute("myFunction(...)")(是的,我正在使用 PrimeFaces)。
  2. 在命令按钮上使用 oncomplete="#{myBean.myJsCall}"

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

The following pop-ups were blocked on this page

有没有办法在 JSF 或 PrimeFaces 中打开弹出窗口而不被阻止?

这不是真正相关的,但这是我的 JavaScript 函数的简化版本。

我使用纯 HTML 和 JS 开发了这个脚本。它在那里打开弹出窗口而没有拦截器干扰。此外,在运行 JSF 应用程序时将调用粘贴到控制台时,将打开弹出窗口。

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 请求后触发的回调中,例如,它会被浏览器阻止。

此行为在以下问题中有描述:jquery window.open in ajax success being blocked .

作为解决方法,您可以在 JSF ajax 请求之前打开一个窗口。在使用 JSF HTML 标记的命令按钮的情况下,这可以通过使用来完成:

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

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

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

PrimeFaces 包装 onclick导致间接执行,所以弹窗被屏蔽。

无论如何,通过一些额外的技巧,您可以使用某种看起来像 PrimeFaces 按钮的按钮来实现这一点。但是黑客的数量越来越多。

我选择使用 p:dialogiframe反而。首先,如果您使用的是 p:layout , 不要将对话框放在任何布局单元中。

对话框:

<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')}"/>

Action :

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

JavaScript 函数:

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

关于javascript - 如何使用 JSF 打开弹出窗口而不被浏览器阻止,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/38764090/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com