Skip to content

Commit

Permalink
emit an event using the inner document's onreadystatechange event
Browse files Browse the repository at this point in the history
  • Loading branch information
officert committed Feb 10, 2019
1 parent 7473dda commit d12581a
Show file tree
Hide file tree
Showing 8 changed files with 77 additions and 30 deletions.
29 changes: 15 additions & 14 deletions dist/vue-friendly-iframe.js
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*!
* vue-friendly-iframe v0.11.0 (https://github.com/officert/vue-friendly-iframe)
* vue-friendly-iframe v0.12.0 (https://github.com/officert/vue-friendly-iframe)
* (c) 2019 Tim Officer
* Released under the MIT License.
*/
Expand Down Expand Up @@ -213,7 +213,8 @@ exports.default = {
data: function data() {
return {
iframeEl: null,
iframeLoadedMessage: 'LOADED_IFRAME_' + generateGuid()
iframeLoadedMessage: 'IFRAME_LOADED_' + generateGuid(),
iframeOnReadyStateChangeMessage: 'IFRAME_ON_READ_STATE_CHANGE_' + generateGuid()
};
},

Expand All @@ -230,14 +231,8 @@ exports.default = {
}
},
setIframeUrl: function setIframeUrl() {
var _this = this;

var iframeDoc = this.iframeEl.contentWindow.document;
iframeDoc.open().write('<body onload="window.location.href=\'' + this.src + '\'; parent.postMessage(\'' + this.iframeLoadedMessage + '\', \'*\')"></body>');

iframeDoc.onload = function (e) {
_this.$emit('load', e);
};
iframeDoc.open().write('\n <body onload="window.location.href=\'' + this.src + '\'; parent.postMessage(\'' + this.iframeLoadedMessage + '\', \'*\')"></body>\n <script>\n window.document.onreadystatechange = function () {\n if(window.document.readyState === \'complete\') {\n parent.postMessage(\'' + this.iframeOnReadyStateChangeMessage + '\', \'*\')\n }\n };\n </script>\n ');

iframeDoc.close();
},
Expand All @@ -251,24 +246,30 @@ exports.default = {
this.iframeEl.setAttribute('crossorigin', 'anonymous');
this.iframeEl.setAttribute('target', '_parent');
this.iframeEl.setAttribute('style', 'visibility: hidden; position: absolute; top: -99999px');

if (this.className) this.iframeEl.setAttribute('class', this.className);

this.$el.appendChild(this.iframeEl);

this.setIframeUrl();
},
listenForEvents: function listenForEvents() {
var _this2 = this;
var _this = this;

var eventMethod = window.addEventListener ? 'addEventListener' : 'attachEvent';
var eventer = window[eventMethod];
var messageEvent = eventMethod === 'attachEvent' ? 'onmessage' : 'message';

eventer(messageEvent, function (event) {
if (event.data === _this2.iframeLoadedMessage) {
_this2.$emit('load');
if (event.data === _this.iframeLoadedMessage) {
_this.$emit('iframe-load');

_this.iframeEl.setAttribute('style', 'visibility: visible;');
}

if (event.data === _this.iframeOnReadyStateChangeMessage) {
_this.$emit('document-load');

_this2.iframeEl.setAttribute('style', 'visibility: visible;');
_this.$emit('load');
}
}, false);
}
Expand Down
4 changes: 2 additions & 2 deletions dist/vue-friendly-iframe.min.js

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

11 changes: 10 additions & 1 deletion docs-src/components/Home/index.vue
Original file line number Diff line number Diff line change
Expand Up @@ -10,14 +10,23 @@ export default {
src: 'https://www.pexels.com/search',
searchTerm: 'tiger'
},
iframeLoading: true
iframeLoading: true,
documentLoading: true
}
},
methods: {
onLoad() {
console.log('iframe loaded');
this.iframeLoading = false;
},
onIframeLoad() {
console.log('iframe loaded');
},
onDocumentLoad() {
console.log('document loaded');
this.documentLoading = false;
}
}
};
Expand Down
25 changes: 23 additions & 2 deletions docs-src/components/Home/template.html
Original file line number Diff line number Diff line change
Expand Up @@ -46,9 +46,16 @@ <h2>Usage</h2>
2) In your HTML add the component:
</p>
<div class="highlight">
<pre class="highlight">&lt;vue-friendly-iframe :src="example1Form.src" @load="onLoad" &gt;&lt;/vue-friendly-iframe&gt;</pre>
<pre class="highlight">&lt;vue-friendly-iframe :src="example1Form.src" @load="onLoad" @document-load="onDocumentLoad"&gt;&lt;/vue-friendly-iframe&gt;</pre>
</div>
</div>
<h2>Events</h2>
<p>
Events are emitted from the component so you can hook into the iframe's load event and the inner document onreadystatechange event.
</p>
<div class="highlight">
<pre class="highlight">&lt;vue-friendly-iframe :src="example1Form.src" @load="onLoad" @document-load="onDocumentLoad"&gt;&lt;/vue-friendly-iframe&gt;</pre>
</div>
<h2>Example</h2>
<div class="example-1">
<form>
Expand All @@ -61,11 +68,25 @@ <h2>Example</h2>
<input class="form-control" :value="example1Form.src + '/' + example1Form.searchTerm" readonly="readonly">
</div>
</form>
<div class="loading-states">
<div v-if="iframeLoading">
Iframe loading...
</div>
<div v-if="!iframeLoading">
Iframe finished loading
</div>
<div v-if="documentLoading">
Inner document loading...
</div>
<div v-if="!documentLoading">
Inner document finished loading
</div>
</div>
<div class="iframe-wrapper">
<div class="iframe-loading" v-if="iframeLoading">
iframe loading...
</div>
<vue-friendly-iframe :style="{ 'display' : iframeLoading ? 'none' : 'block' }" :src="example1Form.src + '/' + example1Form.searchTerm" @load="onLoad"></vue-friendly-iframe>
<vue-friendly-iframe :style="{ 'display' : iframeLoading ? 'none' : 'block' }" :src="example1Form.src + '/' + example1Form.searchTerm" @load="onLoad" @iframe-load="onIframeLoad" @document-load="onDocumentLoad"></vue-friendly-iframe>
</div>
</div>
</section>
Expand Down
4 changes: 2 additions & 2 deletions docs/docs.js

Large diffs are not rendered by default.

1 change: 1 addition & 0 deletions docs/index.html
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@
<meta property="og:description" content="A Vue.js component for creating dynamic async iframes">
<link rel="stylesheet" href="https://fonts.googleapis.com/css?family=Open+Sans:400,700">
<link ref="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/highlight.js/9.12.0/styles/atom-one-dark.min.css" />
<link rel="stylesheet" href="http://code.ionicframework.com/ionicons/2.0.1/css/ionicons.min.css" />
<link rel="stylesheet" href="docs.css" />
</head>

Expand Down
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "vue-friendly-iframe",
"version": "0.11.0",
"version": "0.12.0",
"description": "Vue component for creating dynamic async iframes",
"main": "dist/vue-friendly-iframe.js",
"scripts": {
Expand Down
31 changes: 23 additions & 8 deletions src/components/FriendlyIframe/index.vue
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,8 @@ export default {
data() {
return {
iframeEl: null,
iframeLoadedMessage: `LOADED_IFRAME_${generateGuid()}`
iframeLoadedMessage: `IFRAME_LOADED_${generateGuid()}`,
iframeOnReadyStateChangeMessage: `IFRAME_ON_READ_STATE_CHANGE_${generateGuid()}`
};
},
computed: {},
Expand All @@ -44,11 +45,19 @@ export default {
},
setIframeUrl() {
const iframeDoc = this.iframeEl.contentWindow.document;
iframeDoc.open().write(`<body onload="window.location.href='${this.src}'; parent.postMessage('${this.iframeLoadedMessage}', '*')"></body>`);
iframeDoc.onload = (e) => {
this.$emit('load', e);
};
iframeDoc.open()
.write(
`
<body onload="window.location.href='${this.src}'; parent.postMessage('${this.iframeLoadedMessage}', '*')"></body>
<script>
window.document.onreadystatechange = function () {
if(window.document.readyState === 'complete') {
parent.postMessage('${this.iframeOnReadyStateChangeMessage}', '*')
}
};
<\/script>
`
);
iframeDoc.close(); //iframe onload event happens
},
Expand All @@ -61,8 +70,8 @@ export default {
this.iframeEl.setAttribute('crossorigin', 'anonymous');
this.iframeEl.setAttribute('target', '_parent');
this.iframeEl.setAttribute('style', 'visibility: hidden; position: absolute; top: -99999px');
if (this.className) this.iframeEl.setAttribute('class', this.className);
this.$el.appendChild(this.iframeEl);
this.setIframeUrl();
Expand All @@ -76,10 +85,16 @@ export default {
// Listen to message from child window
eventer(messageEvent, event => {
if (event.data === this.iframeLoadedMessage) {
this.$emit('load');
this.$emit('iframe-load');
this.iframeEl.setAttribute('style', 'visibility: visible;');
}
if (event.data === this.iframeOnReadyStateChangeMessage) {
this.$emit('document-load');
this.$emit('load');
}
}, false);
}
},
Expand Down

0 comments on commit d12581a

Please sign in to comment.