1 | # Bellhop [![Actions Status](https://github.com/SpringRoll/Bellhop/workflows/Node%20CI/badge.svg)](https://github.com/SpringRoll/Bellhop/actions) [![Dependency Status](https://david-dm.org/SpringRoll/Bellhop.svg?style=flat)](https://david-dm.org/SpringRoll/Bellhop)
|
2 |
|
3 | Bellhop is a simple event-based communication layer between the page DOM and an iframe. It doesn't require any additional dependencies. Super easy to use and setup.
|
4 |
|
5 | ## Installation
|
6 |
|
7 | ```bash
|
8 | npm install bellhop-iframe
|
9 | ```
|
10 |
|
11 | ## Importing Bellhop
|
12 |
|
13 | The Bellhop module contains support for ES6 modules, CommonJS and browser global definitions. To import with ES6,
|
14 |
|
15 | ```javascript
|
16 | import { Bellhop } from 'bellhop-iframe';
|
17 | ```
|
18 |
|
19 | To import with CommonJS, refer instead to the UMD build
|
20 |
|
21 | ```javascript
|
22 | const Bellhop = require('bellhop-iframe/dist/bellhop-umd.js');
|
23 | ```
|
24 |
|
25 | You can also import the UMD version by using import
|
26 |
|
27 | ```javascript
|
28 | import { Bellhop } from 'bellhop-iframe/dist/bellhop-umd.js'
|
29 | ```
|
30 |
|
31 | Lastly, the UMD module can also be directly included on an HTML page. This will declare Bellhop and attach it directly
|
32 | to `window`
|
33 |
|
34 | ```html
|
35 | <script src="node_modules/bellhop-iframe/dist/bellhop-umd.js"></script>
|
36 | ```
|
37 |
|
38 | ## Basic Usage
|
39 |
|
40 | Here's a very simple example to get started. We have two pages `index.html` and `child.html`. This is the minimum you need to get them talking to each other.
|
41 |
|
42 | ### Contents of `index.html`
|
43 |
|
44 | ```html
|
45 | <iframe src="child.html" id="page" width="200" height="200"></iframe>
|
46 | <script>
|
47 |
|
48 | // Create the bellhop object
|
49 | const bellhop = new Bellhop();
|
50 |
|
51 | // Pass in the iframe DOM object
|
52 | bellhop.connect(document.getElementById("page"));
|
53 |
|
54 | // Listen for the 'init' event from the iframe
|
55 | bellhop.on('init', function(event){
|
56 | // Handle the event here!
|
57 | });
|
58 |
|
59 | // Send data to the iframe
|
60 | bellhop.send('user', {
|
61 | "name" : "Dave Smith",
|
62 | "age" : 16,
|
63 | "city" : "Boston"
|
64 | });
|
65 | </script>
|
66 | ```
|
67 |
|
68 | ### Contents of `child.html`
|
69 |
|
70 | ```html
|
71 | <script>
|
72 |
|
73 | // Create the bellhop object
|
74 | const bellhop = new Bellhop();
|
75 | bellhop.connect();
|
76 |
|
77 | // An example event to sent to the parent
|
78 | bellhop.send('init');
|
79 |
|
80 | // Handle events from the parent
|
81 | bellhop.on('user', function(event){
|
82 | // Capture the data from the event
|
83 | const user = event.data;
|
84 | });
|
85 | </script>
|
86 | ```
|
87 |
|
88 | ## Available Methods
|
89 |
|
90 | ### `new Bellhop`
|
91 |
|
92 | The constructor creates a new `Bellhop` instance, taking an optional unique identifier for this instance. If no id is provided, a random one is selected
|
93 |
|
94 | ### `connect`
|
95 |
|
96 | Connects a `Bellhop` instance to an iframe, or it's containing window. For instance, given a `Bellhop` instance `bellhop`:
|
97 |
|
98 | ```javascript
|
99 | bellhop.connect();
|
100 | ```
|
101 |
|
102 | will connect a child iframe to it's parent, allowing it to emit messages _out_ of the iframe. However,
|
103 |
|
104 | ```javascript
|
105 | var iframe = document.querySelector('iframe');
|
106 | bellhop.connect(iframe);
|
107 | ```
|
108 |
|
109 | allows a containing page to connect with an interior iframe and emit message _into_ the iframe.
|
110 |
|
111 | ### `destroy`
|
112 |
|
113 | `disconnect` removes any listener for events from another frame, and stops listening for messages altogether
|
114 |
|
115 | ### `off`
|
116 |
|
117 | Removes an event listener previously added by the `.on()` method, or removes a given callback method from a listener. When deleting a callback, the function passed in is required to be the original function passed into the `.on()` method.
|
118 | ```javascript
|
119 | bellhop.off(‘init’); // removes the listener ‘init’ and all callbacks assigned to it
|
120 |
|
121 | bellhop.off(‘init’, callback) // removes the specific callback provided without removing the listener
|
122 | ```
|
123 |
|
124 | ### `send`
|
125 |
|
126 | Sends a named message to another iframe:
|
127 |
|
128 | ```javascript
|
129 | bellhop.send('newHighscore', { value: 100 });
|
130 | ```
|
131 |
|
132 | ### `fetch` and `respond`
|
133 |
|
134 | Convenience methods for automating response of values between the interior and exterior of frames. For instance:
|
135 |
|
136 | ```javascript
|
137 | // index.html
|
138 | var iframe = document.querySelector('iframe');
|
139 | var bellhop = new Bellhop(iframe);
|
140 | bellhop.connect();
|
141 | bellhop.respond('config', { difficulty: 'hard', theme: 'dark' });
|
142 |
|
143 |
|
144 | // child.html
|
145 | var bellhop = new Bellhop();
|
146 | bellhop.connect();
|
147 | bellhop.fetch('config', function(result) {
|
148 | console.log(result); // { difficulty: 'hard', theme: 'dark' }
|
149 | });
|
150 | ```
|
151 |
|
152 | Additionally, object passed to respond() can be a function, whose result will be returned in the callback of the fetch function.
|
153 |
|
154 | ```javascript
|
155 | // index.html
|
156 | var functionExample = function(){
|
157 | return "result of functionExample";
|
158 | };
|
159 | bellhop.respond('function', functionExample);
|
160 |
|
161 | // child.html
|
162 | bellhop.fetch('function', function(result) {
|
163 | console.log(result.data); //result of functionExample
|
164 | });
|
165 | ```
|
166 |
|
167 | Furthermore, respond() accepts a plain object, string, or number. If a function is passed, it will be called and the function's return-value sent. If a promise is passed in or returned from a function that was passed in, that promise will be await-ed before it's value returned.
|
168 |
|
169 | For example, the following all return `"data"` to `bellhop.fetch()`
|
170 |
|
171 | ```javascript
|
172 |
|
173 | //(example)
|
174 | bellhop.respond('example', "data");
|
175 |
|
176 | //OR (promise example)
|
177 | let promiseData = new Promise(function(resolve, reject) {
|
178 | resolve("data")
|
179 | });
|
180 | bellhop.respond('example', promiseData)
|
181 |
|
182 | //OR (function example)
|
183 | var functionExample = function(){
|
184 | return "data";
|
185 | };
|
186 | bellhop.respond('example', functionExample);
|
187 |
|
188 | //OR (function that returns a promise)
|
189 | var functionPromiseExample = function(){
|
190 | return new Promise(function(resolve, reject) {
|
191 | resolve("data")
|
192 | });
|
193 | };
|
194 | bellhop.respond('example', functionPromiseExample);
|
195 | ```
|
196 |
|
197 | ### `trigger`
|
198 |
|
199 | Triggers any event handlers for a given event type optionally passing data to other areas in the app that are listening for this event
|
200 |
|
201 | ``` javascript
|
202 | bellhop.trigger('eventType', {data: 'example'}); // triggers the event 'eventType' passing data to it's handlers
|
203 | ```
|
204 |
|
205 | ### `Debug Mode`
|
206 |
|
207 | Bellhop has a debug mode which enables additional logging when an instance sends or receives
|
208 | a message. It can be enabled by simply setting the `debug` flag to `true`:
|
209 |
|
210 | ```javascript
|
211 | bellhop.debug = true;
|
212 | ```
|
213 |
|
214 | By default (above method) it will print a message outlining whether the bellhop instance was a
|
215 | child or parent, whether the message was sent or received, and the contents of the message. If you require additional or custom logging you can also pass a function as the flag.
|
216 |
|
217 | ```javascript
|
218 | const log = () => {console.log('Hello World!');}
|
219 | bellhop.debug = log; // Hello World!
|
220 | ```
|
221 |
|
222 | If you pass a function to debug three parameters* are passed to help fill out the log statements if required:
|
223 |
|
224 | ```javascript
|
225 | const log = ({isChild, received, message}) => {
|
226 | console.log(isChild); // (boolean) whether the instance is a child or parent.
|
227 | console.log(received); // (boolean) whether the instance has received a message or sent one.
|
228 | console.log(message); // (object) the content of the message.
|
229 | }
|
230 | ```
|
231 |
|
232 | *Note: the names must be identical, but you are able to omit any or all if they're not required.
|
233 |
|
234 | ### `target`
|
235 |
|
236 | Property for retrieving the iframe element through which this `Bellhop` instance is communicating:
|
237 |
|
238 | ```javascript
|
239 | var iframe = document.querySelector('iframe');
|
240 | var bellhop = new Bellhop(iframe);
|
241 |
|
242 | console.log(bellhop.target === iframe.contentWindow); // true
|
243 | ```
|
244 |
|
245 | ## License
|
246 |
|
247 | Copyright (c) 2021 [Springroll](https://github.com/SpringRoll)
|
248 |
|
249 | Released under the MIT License.
|