Dynamic appended iframe with dynamic content write jquery event handle on content elements not working

Zeeshan Ahmed :

I have appended dynamic iframe on document ready through jquery. `

$( document ).ready(function() {


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

` Well iframe rendered through this function

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"  height="120%" width="120%">',
     '</iframe>',
 '</div>'
  ].join("")

  }

On Ajax call writing iframe content `

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

And trying to handle event like

 $('document').on('load','#frame', function(){
    console.log("frame loaded")
    $(this).contents().find('body').on('click', '#btnClose', function(e){
        e.preventDefault(e);
        alert("link clicked!" );
    });
    });
Rory McCrossan :

There's several issues here.

  • iFrame.contents().attr('target','_parent'); will add the target attribute to every element in the DOM. I'm not sure what you're trying to do with that but it's not a good idea.
  • The iframe is empty at that point anyway, so nothing will happen and the line can be removed.
  • the renderIframe() logic doesn't really need it's own function; it only ever returns a single string, and contains no business logic.
  • You don't need to create a DOMParser instance to generate a DOM structure from your HTML string. Just set the innerHTML within the iframe directly using the string you receive from the AJAX request
  • iframes don't fire a load event, so that code block will never fire. A better idea is to just attach the event handler within the AJAX callback after the content is populated.
  • If you're expecting the content to be visible in the page you need to remove the display: none setting in the CSS.
  • On the topic of CSS, do not put it the inline style attribute of the HTML element. Use a external stylesheet.

With all that said, try this:

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

Note that SO Snippets disallow iframes, so here's a jsFiddle containing a working example.

Guess you like

Origin http://43.154.161.224:23101/article/api/json?id=346882&siteId=1