具有动态内容的动态附加 iframe 在内容元素上写入 jquery 事件句柄不起作用

Posted

技术标签:

【中文标题】具有动态内容的动态附加 iframe 在内容元素上写入 jquery 事件句柄不起作用【英文标题】:Dynamic appended iframe with dynamic content write jquery event handle on content elements not working 【发布时间】:2020-06-22 08:54:30 【问题描述】:

我已经通过 jquery 在准备好的文档上附加了动态 iframe。 `

$( document ).ready(function() 


 $("body").append(renderIframe());
  );

` 那么通过这个函数渲染的iframe

function renderIframe()


 return [

  '<div id="mydiv">',
     '<iframe id="frame" style="overflow:hidden;overflow-x:hidden;overflow-y:hidden;height:100%;width:100%;position:absolute;top:0px;left:0px;right:0px;bottom:0px;display:none"   >',
     '</iframe>',
 '</div>'
  ].join("")

  

关于 Ajax 调用写入 iframe 内容 `

 var iFrame = $('#frame');
      iFrame.contents().attr('target','_parent');

   var htmlDoc = (new DOMParser()).parseFromString(data, "text/html");

      var iFrameDoc = iFrame[0].contentDocument || iFrame[0].contentWindow.document;
   iFrameDoc.write( htmlDoc.documentElement.outerHTML);
   iFrameDoc.close();`

并试图处理像

这样的事件
 $('document').on('load','#frame', function()
    console.log("frame loaded")
    $(this).contents().find('body').on('click', '#btnClose', function(e)
        e.preventDefault(e);
        alert("link clicked!" );
    );
    );

【问题讨论】:

【参考方案1】:

这里有几个问题。

iFrame.contents().attr('target','_parent');target 属性添加到 DOM 中的每个元素。我不确定你想用它做什么,但这不是一个好主意。 此时 iframe 还是空的,所以什么都不会发生,并且可以删除该行。 renderIframe() 逻辑并不真正需要它自己的函数;它只返回一个字符串,不包含任何业务逻辑。 您无需创建DOMParser 实例即可从您的HTML 字符串生成DOM 结构。只需使用从 AJAX 请求中收到的字符串直接在 iframe 中设置innerHTML iframe 不会触发load 事件,因此代码块永远不会触发。更好的办法是在填充内容后在 AJAX 回调中附加事件处理程序。 如果您希望内容在页面中可见,则需要删除 CSS 中的 display: none 设置。 关于 CSS 的话题,不要把它放在 HTML 元素的内联 style 属性中。使用外部样式表。

说了这么多,试试这个:

$("body").append(renderIframe());

function renderIframe() 
  return '<div id="mydiv"><iframe id="frame"></iframe></div>';


// inside the AJAX callback:
var iFrame = $('#frame');
let data = '<p>Lorem ipsum</p><button id="btnClose">Close</button>'; // AJAX response
var iFrameDoc = iFrame[0].contentDocument || iFrame[0].contentWindow.document;
iFrameDoc.body.innerHTML = data;

$('#frame').contents().find('body').on('click', '#btnClose', function(e) 
  e.preventDefault(e);
  alert("link clicked!");
);

请注意,SO Snippets 不允许 iframe,所以这里有一个包含 working example 的 jsFiddle。

【讨论】:

非常感谢您提供如此详细的答案,实际上在 AJAX POST 上,我正在接收带有 HTML 页面形式的服务器端渲染的 Bootstrap Modal。好吧,我已经用 iframe innerhtml 替换了 DOMParser ,模态现在没有打开。 那么在这种情况下,您为什么要将 Bootstrap 模式放入 iframe 中?这没有意义 只是为了让它覆盖在整个屏幕上。否则你的权利没有意义。 顺便说一句,为什么 Modal 在这种情况下不起作用,您能详细说明一下吗? 如果没有看到相关代码,我真的不能说为什么它对你不起作用。然而,如果 HTML 是一个引导模式,你真的应该这样显示它,而不是随意修改它以显示在 iframe 中。这样做只会制造更多问题

以上是关于具有动态内容的动态附加 iframe 在内容元素上写入 jquery 事件句柄不起作用的主要内容,如果未能解决你的问题,请参考以下文章

如何根据 iframe 中的动态内容更改 iframe 的高度?

Web 浏览器何时请求动态创建的 iframe 的 src 内容?

如何根据元素高度动态调整 iframe 高度?

使用jQuery动态调整iframe高度,以及jQuery对dom元素的监听

具有动态内容的打字机效果

如何识别在 iframe 中动态创建的文档内容