0

I have an html document with an iframe in it. The parent document and the document in the iframe (a wordpress blog) are in the same domain. The iframe auto-adjusts its height on load event to fit its content like this:

<iframe width="100%" height="100%" id="parent-iframe" name="parent-iframe" src="/blog" scrolling="no" onload="this.height=this.contentWindow.document.body.scrollHeight"></iframe>

It works fine. But now, the blog which is mostly one page with a facebook feed, has been updated with a "load-more" button to limit the number of posts displayed. Much like an infinite scroll but with a button.

What I want is to be able to resize the parent iframe on the "load-more" button click. Since the facebook feed is provided by a wordpress plugin and it gets updates every now and then, I'd rather not mess with its files directly. Also the javascript code is minified so it looks like jibberish to me.

Fortunately, it also provides a backoffice textbox to include custom code. Since jQuery is already loaded, I tried this:

jQuery(document).ready(function () {
    jQuery("load-more").click(function () {
        var frame = $('#parent-iframe', window.parent.document);
        var height = jQuery('body').height();
        frame.height(height);
    });
});

It works as expected but with one caveat. Whenever the click event is triggered, the function is executed before the new post gets loaded therefore the body height is always one step behind. I could add a fixed amount of pixels to compensate but some posts are significantly larger than others.

I don't do this kind of work very often so I need help. I was looking at the jQuery deferred objects but quite honestly I'm a bit lost. Can somebody briefly explain to me how does it work and how to fix it?

Guillem
  • 41
  • 1
  • 5
  • I'm not sure what you want here...you want the above working code to execute, but with a delay? – mjw Jun 19 '17 at 18:15
  • 1
    I don't know if this helps, but this does exist already: https://github.com/davidjbradshaw/iframe-resizer – Matt Jun 19 '17 at 18:16
  • @mjw Not a delay per se but rather sequentially after the "load-more" button functions are completed. – Guillem Jun 19 '17 at 18:55
  • @mkaatman thanks I'll have a look at it. But I'd like to also know if and how it can be done with jQuery alone – Guillem Jun 19 '17 at 19:01
  • No problem. For what it's worth I've used that plugin in the past and it did a mind-boggling awesome job. – Matt Jun 19 '17 at 19:02
  • 1
    You need to know when the code from the `load-more` button has finished with it's work. Since this isn't an initial load of content, it must be some sort of Ajax call. If it does not expose anything that tells you when that ajax call is done, then there really isn't much you can do other than poll the content to see when it has been changed (which is an ugly hack). Can you show us the regular code that processes the `load-more` button? – jfriend00 Jun 19 '17 at 23:27
  • thanks @jfriend00 but the javascript file with the ajax call is minified and very hard to make any sense of. But I think I've found a solution thanks to your suggestion. – Guillem Jun 20 '17 at 09:42

1 Answers1

0

Thanks to @jfriend00 suggestion, I think I've found a somehow working solution. Since the plugins javascript file is minified and I'm not used to javascript debugging, I couldn't find the end of the load-more ajax call. All I needed then was to wait until all ajax requests were finished. So I found this post jquery.ajaxStop() and tried this:

jQuery(document).ready(function () {
    jQuery("load-more").click(function () {
            $(document).ajaxStop(function () {
            var frame = $('#parent-iframe', window.parent.document);
            var height = jQuery('body').height();
            frame.height(height);
            $(document).unbind("ajaxStop");
       });
   });
});

Now it works. Please excuse me if I haven't been able to explain myself better. As I said I'm not used to this so I'm lacking in proper terminology and concepts. If you have any suggestions regarding the post title, details or tags in order to make it useful to others I'd be glad to edit it accordingly.

It also works and looks cleaner like this:

<iframe width="100%" height="100%" id="parent-iframe" name="parent-iframe" src="/blog" scrolling="no" onload="this.height=this.contentWindow.document.body.scrollHeight" onresize="this.height=this.contentWindow.document.body.scrollHeight"></iframe>

parent iframe

$(document).ready(function () {
        $("#load-more").click(function () {
                $(document).one("ajaxStop", function () {
                       window.parent.$("#parent-iframe").trigger('resize');
                });
        });
});

child document jquery

Guillem
  • 41
  • 1
  • 5
  • 1
    One problem with this is that you will be registering a new `.ajaxStop()` handler every time the button is clicked and they will accumulate. – jfriend00 Jun 20 '17 at 13:44
  • thanks again @jfriend00 `$(document).unbind("ajaxStop");` that should do it right? – Guillem Jun 20 '17 at 22:24