Iframe-resizer: Vue

Created on 21 Aug 2017  Â·  20Comments  Â·  Source: davidjbradshaw/iframe-resizer

Hi there,

I am trying to get your component to work inside of Vue 2
I was able to get the npm installed and my host page running.
I have the client script installed in the child iframe as well, but am getting this warning/error:

[iFrameSizer][Host page: oauth2relay737909339] IFrame has not responded within 10 seconds. Check iFrameResizer.contentWindow.js has been loaded in iFrame. This message can be ingored if everything is working, or you can set the warningTimeout option to a higher value or zero to suppress this warning.

I also setup the callbacks, but the messages that come back on resize and message are 'undefined'.

<template>
    <div class="row">
        <div class="col-lg-12">
            <div class="panel panel-flat">
                <!-- <iframe id="myIframe" :src="getTarget()" scrolling="no" ref="myIFrame" />  -->
                <iframe id="myIframe" src="https://www.trueatlas.com/vanilla.html" scrolling="no" ref="myIFrame">
                </iframe>


            </div>
        </div>
    </div>
</template>
<script lang="ts">
    import * as Vue from 'vue'
    import { NavigationService } from '../../shared/Utilities/Navigation';
    import * as resizer from 'iframe-resizer';
    import { Bus } from '../../main';
    export default {
        name: 'iFrameHolder',
        data() {
            return {
                NS: NavigationService,
                ifr: resizer,
            }
        },
        components: { resizer },
        methods:
        {
            msgCB: function () {
                console.log('got ready');
            },
            gotMessage: function (messageData) {
                console.log(messageData)
            },
            resizeIframe: function (height) {
                console.log(height);
                //document.getElementById('frame_name_here').height = parseInt(height)+60;
            },
            getiFrameWidth: function () {
                return this.$store.state.iframeWidth;
            },
            getiFrameHeight: function () {
                return this.$store.state.iframeHeight;
            },
            getTarget: function () {

                return this.$store.state.iframeTarget;
            }
        },

        updated: function () {
            this.ifr.iframeResizer({ log: true, warningTimeout: 10, checkOrigin: false, autoResize: true, resizeFrom: 'child', messageCallback: function (messageData) { console.log() }, readyCallback: this.msgCB() }, this.$refs.myIFrame);
        },
        created: function () {
            this.NS = new NavigationService();
            this.NS.router = this.$router;
            this.$store.state.Crumb = "";

            this.ifr.iframeResizer({ log: true, warningTimeout: 10000, checkOrigin: false, autoResize: true, resizeFrom: 'child', resizedCallback: this.gotMessage(), messageCallback: this.gotMessage(), readyCallback: this.msgCB() }, this.$refs.myIFrame);


        }
    }

</script>
<style>
    iframe {
        width: 100%
    }
</style>
Help wanted

Most helpful comment

Good idea,
this should work:

import Vue from 'vue'
import iFrameResize from 'iframe-resizer/js/iframeResizer'

Vue.directive('resize', {
  bind: function (el, {value = {}}) {
    el.addEventListener('load', () => iFrameResize(value, el))
  },
})

Now we can pass options like this:

<iframe v-resize="{ log: true }" width="100%" src="myiframe.html" frameborder="0"></iframe>

All 20 comments

Never used Vue, so not sure what is going on. If you put a simple test case online somewhere I'll take a quick look.

Did you find a solution @SmarterPhoneLabs ? I am trying to do implement iframeResizer with my vue app as well.

I did, but I ended up having to do some witchcraft on my asp.net
application to make it work

On Fri, Nov 10, 2017 at 8:07 AM, itafras notifications@github.com wrote:

Did you find a solution @SmarterPhoneLabs
https://github.com/smarterphonelabs ? I am trying to do implement
iframeResizer with my vue app as well.

—
You are receiving this because you were mentioned.
Reply to this email directly, view it on GitHub
https://github.com/davidjbradshaw/iframe-resizer/issues/513#issuecomment-343482378,
or mute the thread
https://github.com/notifications/unsubscribe-auth/ABIq5ScfHNYsfgAwjMrS3Hv0d2zomrHqks5s1FipgaJpZM4O9m4I
.

Care to share?

It was highly specific to our app, so I doubt it would be useful to you.

On Fri, Nov 10, 2017 at 11:41 AM, David J. Bradshaw <
[email protected]> wrote:

Care to share?

—
You are receiving this because you were mentioned.
Reply to this email directly, view it on GitHub
https://github.com/davidjbradshaw/iframe-resizer/issues/513#issuecomment-343538782,
or mute the thread
https://github.com/notifications/unsubscribe-auth/ABIq5bIaj2lLPzR0sztX7hqOR0zE4hHYks5s1IrGgaJpZM4O9m4I
.

Hi!
Try to move it into the mounted, maybe this solves your problem.

Hey there,

We got a fix in vuejs. You have to create a directive :
We installed the package from npm
TWIG :

<iframe src="{{ src }}" id="iframe" v-resize></iframe>

JS :


import Vue from 'vue';
import iFrameResize from 'iframe-resizer/js/iframeResizer'

Vue.directive('resize', {
    inserted: function (el) {

        iFrameResize({log:true}, '#'+el.id);
    }
});

Hope it helps.

While the directive approach works, I didn't want to have to include the iframeResizer JS in my entire application since I lazy load the components and only one component shows an iFrame. You actually don't _have_ to use a directive to use this in vue. Here's how I did it:

Template:

<iframe
  id="iframe"
  :src="source"
  style="min-width: 100%; border: none;"
  scrolling="no"
  @load="iframeLoaded"
/>

Script:

<script>
import iFrameResize from 'iframe-resizer/js/iframeResizer'

export default {
  name: 'component name',

  data () {
    return {
      source: ''
    }
  },

  methods: {
    iframeLoaded () {
      iFrameResize({log: true}, '#iframe')
    }
  }
}
</script>

That works fine for me and is a bit cleaner for my application! If you're doing this in multiple places then I'd still recommend @Dreimus solution above!

Hey,

Here is a different approach based on @Dreimus 's code:

import Vue from 'vue'
import iFrameResize from 'iframe-resizer/js/iframeResizer'

Vue.directive('resize', {
  bind: function (el) {
    el.addEventListener('load', () => iFrameResize({}, el))
  },
})

This way:

  • You don't need an id attribute
  • Only run iFrameResize when the iframe has loaded which will prevent an error

That looks nice and simple, would be great to be able to pass options to
iframe-resizer via the directive

Good idea,
this should work:

import Vue from 'vue'
import iFrameResize from 'iframe-resizer/js/iframeResizer'

Vue.directive('resize', {
  bind: function (el, {value = {}}) {
    el.addEventListener('load', () => iFrameResize(value, el))
  },
})

Now we can pass options like this:

<iframe v-resize="{ log: true }" width="100%" src="myiframe.html" frameborder="0"></iframe>

Why does my use in vue not work?

Thanks for sharing your experience with this!

The v-resize directive in https://github.com/davidjbradshaw/iframe-resizer/issues/513#issuecomment-538333854 fails with Vuetify because Vuetify handles the value as a callback. To disable this behavior, Vuetify has a quiet modifier (see the Vuetify docs for details).

So, the following directive works with Vuetify:

<iframe v-resize.quiet="{ log: true }" width="100%" src="myiframe.html" frameborder="0"></iframe>

While the directive approach works, I didn't want to have to include the iframeResizer JS in my entire application since I lazy load the components and only one component shows an iFrame.

You don't need to register a directive globally you can declare it just like any other component:

_component.vue_

<template>
     ...
     <iframe v-iframe-resize="{log:true}"></iframe>
     ...
</template>
<script>
import iframeResize from './v-iframe-resize.js';
export default {
    directive: {
        'v-iframe-resize': iframeResize,
    },
    // component impl.
}
</script>

Directive:
_v-iframe-resize.js_

import iFrameResize from 'iframe-resizer/js/iframeResizer'

export default {
  bind(el, binding) {
     iFrameResize(binding.value, el);
  },
};

its also good idea to handle properties changing, and unbinding.

The above code is wrong. "directives" instead of "directive". Name without "v-"

<template>
     ...
     <iframe v-iframe-resize="{log:true}"></iframe>
     ...
</template>
<script>
export default {
  directives: {
    'iframe-resize': {
      bind(el, binding) {
        iFrameResize(binding.value, el)
      }
    }
  }
 }
</script>

Creating plugin in Nuxt, it doesnt work!:(

@gaglage you might look at https://github.com/davidjbradshaw/iframe-resizer/issues/831 for experience with Nuxt.js

thanks! I'll check it

I have the same error message as @SmarterPhoneLabs, I think it might be an issue installing the script on the child page. Does anyone have an example of installing the contentWindow script on a VueJS child page?

Added this into my child page, and it seems to be working:

mounted() {
    const resizerScript = document.createElement('script')
    resizerScript.setAttribute('src', 'https://cdn.jsdelivr.net/npm/[email protected]/js/iframeResizer.contentWindow.min.js')
    document.head.appendChild(resizerScript)
    }

However I'm using Vuetify and have an issue specific to that framework which forces pages to be full-screen height, even if there are only a few lines of text: https://github.com/vuetifyjs/vuetify/issues/11452, so the iFrame resizes to fit the whole screen height everytime.

Was this page helpful?
0 / 5 - 0 ratings

Related issues

thomasbilk picture thomasbilk  Â·  4Comments

amangeot picture amangeot  Â·  8Comments

lukashanssondn picture lukashanssondn  Â·  7Comments

wei2go picture wei2go  Â·  3Comments

russellballestrini picture russellballestrini  Â·  4Comments