Skip to content

Commit 8b1c791

Browse files
committed
Add broadcast channel api demo.
1 parent 3964f30 commit 8b1c791

4 files changed

Lines changed: 213 additions & 0 deletions

File tree

README.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@ with.
1010

1111
## My JavaScript Demos - I Love JavaScript!
1212

13+
* [Sending Messages Across Documents With The Broadcast Channel API](https://bennadel.github.io/JavaScript-Demos/demos/broadcast-api)
1314
* [Animating DOM Rectangles Over Focused Elements In JavaScript](https://bennadel.github.io/JavaScript-Demos/demos/focus-box)
1415
* [Linking To A Disclosure (Details) Element](https://bennadel.github.io/JavaScript-Demos/demos/scroll-to-details)
1516
* [Opening The Dialog Element As A Fly-out Sidebar](https://bennadel.github.io/JavaScript-Demos/demos/dialog-element-sidebar)

demos/broadcast-api/frame.htm

Lines changed: 75 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,75 @@
1+
<!doctype html>
2+
<html lang="en">
3+
<head>
4+
<meta charset="utf-8" />
5+
<title>
6+
Broadcast Channel API Frame
7+
</title>
8+
<link rel="stylesheet" type="text/css" href="./main.css" />
9+
</head>
10+
<body class="frame-body">
11+
12+
<!--
13+
I'll follow the mouse location within each frame. Or I'll move according to the
14+
Broadcast API messages sent from frame-to-frame.
15+
-->
16+
<mark class="laser">
17+
<!-- Pew pew pew! -->
18+
</mark>
19+
20+
<script type="text/javascript">
21+
22+
var laser = document.querySelector( ".laser" );
23+
24+
// Create a named channel that all the frames can bind-to for sending and
25+
// receiving messages.
26+
var channel = new BroadcastChannel( "pewpew" );
27+
28+
// As the mouse moves, broadcast {x,y} coordinates to other frames for mirroring.
29+
window.addEventListener( "mousemove", ( event ) => {
30+
31+
// Note: the message is automatically serialized using the structured clone
32+
// algorithm. As such, we can pass complex messages (within reason) and not
33+
// have to worry about serializing the data. Winning!
34+
channel.postMessage({
35+
type: "lasermove",
36+
clientX: event.clientX,
37+
clientY: event.clientY,
38+
});
39+
40+
// Note: a broadcast context subscriber will NOT RECIEVE ITS OWN messages.
41+
// As such, we don't have to worry about adding logic to ignore reflected
42+
// messages. But it means that we also have to update the laser position
43+
// locally to the broadcasting window.
44+
moveLaser( event.clientX, event.clientY );
45+
46+
});
47+
48+
// Listen for broadcast message events.
49+
channel.addEventListener( "message", ( event ) => {
50+
51+
// The broadcast message data is transparently deserialized using structured
52+
// clone algorithm and is presented in its original format. That said, we
53+
// might receive any number of messages (even on a named channel). As such,
54+
// I'm including a differentiator (type) to focus on relevant messages. This
55+
// is merely a convention, not a requirement.
56+
if ( event.data.type === "lasermove" ) {
57+
58+
moveLaser( event.data.clientX, event.data.clientY );
59+
60+
}
61+
62+
});
63+
64+
// I move the laser point to the given location.
65+
function moveLaser( left, top ) {
66+
67+
laser.style.left = `${ left }px`;
68+
laser.style.top = `${ top }px`;
69+
70+
}
71+
72+
</script>
73+
74+
</body>
75+
</html>

demos/broadcast-api/index.htm

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
<!doctype html>
2+
<html lang="en">
3+
<head>
4+
<meta charset="utf-8" />
5+
<title>
6+
Sending Messages Across Documents With The Broadcast Channel API
7+
</title>
8+
<link rel="stylesheet" type="text/css" href="./main.css" />
9+
</head>
10+
<body>
11+
12+
<h1>
13+
Sending Messages Across Documents With The Broadcast Channel API
14+
</h1>
15+
16+
<p>
17+
These are all <code>&lt;iframe&gt;</code> elements to the same URL:
18+
</p>
19+
20+
<div class="frame-list">
21+
<iframe src="./frame.htm"></iframe>
22+
<iframe src="./frame.htm"></iframe>
23+
<iframe src="./frame.htm"></iframe>
24+
<iframe src="./frame.htm"></iframe>
25+
<iframe src="./frame.htm"></iframe>
26+
<iframe src="./frame.htm"></iframe>
27+
</div>
28+
29+
</body>
30+
</html>

demos/broadcast-api/main.css

Lines changed: 107 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,107 @@
1+
2+
:where( html ) {
3+
box-sizing: border-box ;
4+
5+
& *,
6+
& *:before,
7+
& *:after {
8+
box-sizing: inherit ;
9+
}
10+
}
11+
12+
:where( * ) {
13+
&:focus,
14+
&:focus-visible {
15+
animation-duration: 200ms ;
16+
animation-fill-mode: forwards ;
17+
animation-iteration-count: 1 ;
18+
animation-name: outlineEnter ;
19+
animation-timing-function: ease-out ;
20+
outline-color: hotpink ;
21+
outline-offset: 4px ;
22+
outline-width: 2px ;
23+
}
24+
}
25+
26+
@keyframes outlineEnter {
27+
from {
28+
outline-offset: 8px ;
29+
}
30+
to {
31+
outline-offset: 4px ;
32+
}
33+
}
34+
35+
.textBlock * {
36+
&:focus,
37+
&:focus-visible {
38+
animation-name: none ;
39+
outline: none ;
40+
}
41+
}
42+
43+
44+
body {
45+
font-family: Avenir, Montserrat, Corbel, URW Gothic, source-sans-pro, sans-serif ;
46+
font-size: 18px ;
47+
line-height: 1.4 ;
48+
}
49+
50+
button,
51+
input:where([type="text"]),
52+
select,
53+
textarea {
54+
color: inherit ;
55+
font-family: inherit ;
56+
font-size: 20px ;
57+
line-height: inherit ;
58+
padding: 5px 10px ;
59+
}
60+
61+
button {
62+
padding: 5px 15px ;
63+
}
64+
65+
a {
66+
color: red ;
67+
}
68+
69+
.frame-list {
70+
display: flex ;
71+
gap: 10px ;
72+
flex-wrap: wrap ;
73+
74+
& iframe {
75+
border: 1px solid #333333 ;
76+
flex: 0 0 auto ;
77+
height: 200px ;
78+
width: 220px ;
79+
}
80+
}
81+
82+
.frame-body {
83+
margin: 0 ;
84+
min-height: 100vh ;
85+
86+
&:hover .laser {
87+
--color: 0, 155, 0 ;
88+
--size: 20px ;
89+
}
90+
}
91+
92+
.laser {
93+
--color: 255, 0, 0 ;
94+
--size: 8px ;
95+
position: fixed ;
96+
97+
&:before {
98+
background: rgb( var( --color ) ) ;
99+
border-radius: 100% ;
100+
box-shadow: 0 0 8px 0 rgba( var( --color ), 0.8 ) ;
101+
content: "" ;
102+
height: var( --size ) ;
103+
position: absolute ;
104+
translate: -50% -50% ;
105+
width: var( --size ) ;
106+
}
107+
}

0 commit comments

Comments
 (0)