iframe-resizer
iframe-resizer copied to clipboard
Vue
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>
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 [email protected] 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: {
'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.
Anyone succeeded to use this with Vue3?
I've tried doing this but my frame isn't resized...
<template>
<div>
<iframe
v-iframe-resize="{ log: true }"
src="myURL"
></iframe>
</div>
</template>
<script>
import iFrameResize from 'iframe-resizer/js/iframeResizer'
export default {
name: 'Selector',
directives: {
'iframe-resize': {
bind(el, binding) {
iFrameResize(binding.value, el)
}
}
}
}
</script>
<style scoped lang="scss">
iframe {
width: 1px;
min-width: 100%;
}
</style>
OK, solved it:
<script>
import iFrameResize from 'iframe-resizer/js/iframeResizer'
export default {
name: 'Selector',
directives: {
'iframe-resize': {
beforeMount(el, binding) {
iFrameResize(binding.value, el)
}
}
}
}
</script>
A Vue 3 example using script setup
:
<script lang="ts" setup>
import iframeResize from 'iframe-resizer/js/iframeResizer';
const vResize = {
mounted: (el, { value = {} }) => {
el.addEventListener('load', () => iframeResize(value, el));
},
unmounted: (el) => {
el.iFrameResizer.removeListeners();
},
};
如果你用的是vue+vuetify,指令不要用v-resize,vuetify自身有这个指令
can I also see your template region of the iframe? @drewm
For anyone struggling with this who is using Vuetify, I finally solved it. Vuetify already has it's own v-resize directive which causes a conflict. So you need to choose a different name.
<iframe
v-resizer="{ log: false }"
width="100%"
style="width: 1px; min-width: 100%; height: 2000px"
src="https://"
frameborder="0"
></iframe>
directives: {
resizer: {
bind(el, { value = {} }) {
el.addEventListener('load', () => iframeResize(value, el))
},
},
},
Hi @catskull the solution (https://github.com/davidjbradshaw/iframe-resizer/issues/513#issuecomment-979048597) returns the following warning.
[iFrameSizer][Host page: iframe] Ignored iFrame, already setup.
@drewm, @picks44, @JCFerrerG, @MeStrak, @victornpb
I'm currently working on a large v5 update (#1212) to iframe-resizer and I would like to includes an @iframe-resizer/vue
component that ideally works with Vue, Vueify and Nuxt. Having never used any of these platforms before, I'm after a bit of help with this. The new version splits the NPM module into @iframe-resizer/parent and @iframe-resizer/child.
I have just published an alpha build of version 5 on NPM and have create a draft documentation site https://iframe-resizer.github.io/docs/
This includes an upgrade guide https://iframe-resizer.github.io/docs/upgrade/
and a guide for creating Framework components https://iframe-resizer.github.io/docs/frameworks/api/
Would any of you be able to help create a small Vue wrapper component?
As a starting point, this is roughly how I think the Vue3 example would need to be updated,
Vue Directive
import { Directive, DirectiveBinding } from "vue";
import connectResizer from "@iframe-resizer/core";
interface ResizableHTMLElement extends HTMLElement {
iframeResizer?: {
close: () => void;
disconnect: () => void;
moveToAnchor: (string) => void;
resize: () => void;
sendMessage: () => void;
};
}
const iframeResizer: Directive = {
mounted(el: HTMLElement, binding: DirectiveBinding) {
const options = binding.value || {};
const connectWithOptions = connectResizer(options);
el.addEventListener("load", () => connectWithOptions(el));
},
unmounted(el: HTMLElement) {
const resizableEl = el as ResizableHTMLElement;
resizableEl?.iframeResizer.disconnect();
},
};
export default resize;
Register the directive
const app = createApp(App)
...
app.directive('iframeResizer', connectResizer)
...
app.mount('#app')
Page
<iframe
v-iframeResizer
width="100%"
src="myiframe.html"
frameborder="0"
></iframe>