iframe 加载事件触发两次
Iframe load event fires twice
绑定到 (@load="myFunction"
) 的函数在创建 iframe 时触发一次,在实际加载时触发一次。
为什么创建 iframe 时会触发,如何避免?
<template>
<transition name="modal">
<div v-if="webviewOpen">
<transition name="content" appear>
<div v-if="webviewOpen">
<transition name="iframe">
<iframe
v-show="showIframe"
:src="webviewUrl"
@load="iframeIsLoaded"
/>
</transition>
</div>
</transition>
</div>
</transition>
</template>
<script>
import { mapState } from 'vuex'
export default {
data () {
return {
showIframe: false
}
},
computed: {
...mapState({
webviewOpen: state => state.webview.open,
webviewUrl: state => state.webview.url
})
},
watch: {
webviewOpen () {
setTimeout(() => {
this.showIframe = true
}, 1000)
}
},
methods: {
iframeIsLoaded () {
console.log('iframe loaded')
}
}
}
</script>
这似乎是一个网络工具包问题,触发两次 ( safari/chrome ),因为它在添加到 DOM 时触发(v-if 在父级上)并且在加载内容时触发。将 .once 修饰符添加到 @load.once="myFunction()"
可能会有所帮助
我们从您的 linked answer that Chrome shows this issue unless you attach the listener after the iframe
is appended to the DOM. To do this, we could take advantage of Vue's lifecycle hooks 那里得知。我们希望它发生在 iframe
添加到 DOM 之后,但在它有机会加载之前,所以我们将使用 updated
钩子。
我在我的任何浏览器中都没有遇到这个问题,所以遗憾的是我无法真正为您测试。自己测试一下,看看是否有类似这样的方法可以解决问题:
<template>
<label for="show">Show iFrame</label>
<input id="show" type="checkbox" v-model="webviewOpen">
<div v-if="webviewOpen">
<iframe
src="https://motherfuckingwebsite.com/"
@load="iframeLoadHelper"
frameborder="0"
></iframe>
</div>
</template>
<script>
export default {
name: 'App',
data() {
return {
webviewOpen: false,
iframeReady: false
};
},
methods: {
// Helper method, just to keep 'if' outside of the logic of your potentially
// complex @load method
iframeLoadHelper() {
if (this.iframeReady) return this.iframeLoaded();
else return; // do nothing
},
// The real load method
iframeLoaded() {
console.log('iframe loaded');
}
},
updated() {
console.log('changing ready-state');
this.iframeReady = this.webviewOpen;
}
};
</script>
<style>
:root { font-family: sans-serif; }
</style>
正如@tao 所建议的那样,其他东西正在干扰,即 Nuxt Lazy Load 包。因此,如果有人使用这个包并发现 iframe onload 事件神秘地触发了两次并找到了这个线程:
在 modules
部分中导入包时,在 nuxt.config.js
中添加 iframes: false
。问题已解决!
绑定到 (@load="myFunction"
) 的函数在创建 iframe 时触发一次,在实际加载时触发一次。
为什么创建 iframe 时会触发,如何避免?
<template>
<transition name="modal">
<div v-if="webviewOpen">
<transition name="content" appear>
<div v-if="webviewOpen">
<transition name="iframe">
<iframe
v-show="showIframe"
:src="webviewUrl"
@load="iframeIsLoaded"
/>
</transition>
</div>
</transition>
</div>
</transition>
</template>
<script>
import { mapState } from 'vuex'
export default {
data () {
return {
showIframe: false
}
},
computed: {
...mapState({
webviewOpen: state => state.webview.open,
webviewUrl: state => state.webview.url
})
},
watch: {
webviewOpen () {
setTimeout(() => {
this.showIframe = true
}, 1000)
}
},
methods: {
iframeIsLoaded () {
console.log('iframe loaded')
}
}
}
</script>
这似乎是一个网络工具包问题,触发两次 ( safari/chrome ),因为它在添加到 DOM 时触发(v-if 在父级上)并且在加载内容时触发。将 .once 修饰符添加到 @load.once="myFunction()"
可能会有所帮助我们从您的 linked answer that Chrome shows this issue unless you attach the listener after the iframe
is appended to the DOM. To do this, we could take advantage of Vue's lifecycle hooks 那里得知。我们希望它发生在 iframe
添加到 DOM 之后,但在它有机会加载之前,所以我们将使用 updated
钩子。
我在我的任何浏览器中都没有遇到这个问题,所以遗憾的是我无法真正为您测试。自己测试一下,看看是否有类似这样的方法可以解决问题:
<template>
<label for="show">Show iFrame</label>
<input id="show" type="checkbox" v-model="webviewOpen">
<div v-if="webviewOpen">
<iframe
src="https://motherfuckingwebsite.com/"
@load="iframeLoadHelper"
frameborder="0"
></iframe>
</div>
</template>
<script>
export default {
name: 'App',
data() {
return {
webviewOpen: false,
iframeReady: false
};
},
methods: {
// Helper method, just to keep 'if' outside of the logic of your potentially
// complex @load method
iframeLoadHelper() {
if (this.iframeReady) return this.iframeLoaded();
else return; // do nothing
},
// The real load method
iframeLoaded() {
console.log('iframe loaded');
}
},
updated() {
console.log('changing ready-state');
this.iframeReady = this.webviewOpen;
}
};
</script>
<style>
:root { font-family: sans-serif; }
</style>
正如@tao 所建议的那样,其他东西正在干扰,即 Nuxt Lazy Load 包。因此,如果有人使用这个包并发现 iframe onload 事件神秘地触发了两次并找到了这个线程:
在 modules
部分中导入包时,在 nuxt.config.js
中添加 iframes: false
。问题已解决!