如何阻止空 iframe 在注入时触发加载事件?

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

使用空框架来处理伪异步表单提交。对于那些不熟悉该技术的人来说,其想法是在表单的

name
属性中引用框架的
target
属性,以便表单的
action
的 URI 在框架中解析,并且用户体验不会受到影响。没被打断。

为了向用户反馈,我需要使用脚本来侦听表单上的

load
error
事件,并且因为这有效地使整个 UX 脚本依赖,所以我只注入框架并添加表单的通过脚本进行目标引用。

问题是框架一旦注入页面就会触发加载事件:默认行为

我可以使用 jQuery 的

one
方法和
e.stopImmediatePropagation()
这里)来缓解这个问题,或者我可以注入框架并then绑定事件(这里)。但这两个选项确实违反直觉——代码当然需要注释以避免看起来像一个错误。

TL;DR:有什么方法可以修改或限定 iframe 来阻止它在注入时触发错误的加载事件?

我尝试过的事情

  1. src
    属性
  2. src
    设置为
    about:blank
    (上面是隐含的)
  3. src
    设置为
    #
  4. src
    设置为
    javascript:void 0
  5. src
    设置为空数据-URI
    data:text/plain;base64,;
  6. srcdoc
    设置为空或接近空的字符串
javascript html jquery dom jquery-events
3个回答
0
投票

这是不可能的,正如您所说,默认

src
设置为
about:blank
,任何其他值都会触发
load
事件或
error
一个。

因此,最干净的解决方案可能是仅在触发表单的提交事件时才开始侦听这些事件:

const frame = document.createElement("iframe");
frame.name = "frame";
document.body.append(frame);

const form = document.querySelector("form");
form.addEventListener("submit", (evt) => {
  const controller = new AbortController();
  const { signal } = controller;
  const handler = (evt) => {
    console.log("Request", evt.type === "error" ? "failure" : "success");
    controller.abort(); // kill us and the other listener
  };
  frame.addEventListener("load", handler, { signal });
  frame.addEventListener("error", handler, { signal });
});
<form
  target=frame
  method=post
  action="https://stacksnippets.net/js">
<button>post it</button>
<textarea name=html>Some content</textarea>
</form>

但是应该注意的是,要触发 error 事件,您需要有一个浏览器无法在 iframe 中打开的响应,而浏览器可以在 iframe 中打开很多内容,而且,大多数服务器在遇到错误时确实会发送正确的 HTML 页面。因此,在大多数情况下,这不会让您知道请求失败,即使 404 错误也会触发 iframe 的 load 事件。

因此,如果您处于同源情况,最好的方法可能是使用 AJAX 来发出请求。从那里您可以检查响应的状态代码,甚至可以让服务器为您提供有用的信息,例如作为 JSON 响应。 然后,您可以使用作为文本使用的响应来填充 iframe 的

srcdoc
。 (外部小提琴,因为 StackSnippet 的空源帧无法发出同源请求)。


0
投票

先将iframe放入文档中,然后注册监听器:

var e = $('<iframe>');
e.appendTo('body');
e.on('load', function(){
  alert('Loaded!')
});

0
投票

在 JavaScript 中,“空白”IFRAME 的 URL 与包含窗口的 URL 相同。 因此必须验证以下条件:

function do_Onload(node) {
   if (node.src == window.location.href) {
      //this is the load event for the blank iframe
   }
}

在 IFRAME 上:

<iframe onload="do_Onload(this)"></iframe>
© www.soinside.com 2019 - 2024. All rights reserved.