When I think of web components, I normally think of creating new UI elements. But I think one of the more intriguing things that is possible with them is the ability to create UI-less features that simply serve as a convenient way to get access to streams of information. Instead of creating JavaScript objects that receive AJAX responses, create a Polymer element that does and then bubbles events in the document like an HTML element.
To explore the idea, I am going to try to create a JavaScript Polymer element that listens for click events on a web page. I start with the usual
<script>
setup and a custom <click-sink>
element in the body:<!DOCTYPE html> <html lang="en"> <head> <title>Test</title> <meta content="text/html; charset=UTF-8" http-equiv="content-type"> <!-- 1. Load Polymer before any code that touches the DOM. --> <script src="scripts/polymer.min.js"></script> <!-- 2. Load component(s) --> <link rel="import" href="scripts/click-sink.html"> </head> <body> <click-sink></click-sink> </body> </html>The backing element can then be nothing but a Polymer script that listens for events on the main document:
<polymer-element name="click-sink"> <script> Polymer('click-sink', { enteredView: function() { this.ownerDocument.addEventListener('click', function(e){ console.log('click'); }); } }); </script> </polymer-element>And that works. When I click the page, I see "click" logged to the JavaScript console. It is of little use unless I transform that in some way. For tonight, I am content to transform that into a message that contains the X-Y coordinate at which the element was clicked. So I change the
enteredView()
method to: enteredView: function() {
var that = this;
this.ownerDocument.addEventListener('click', function(e){
var xy = '' + e.clientX + ',' + e.clientY;
that.fire('clicked', {msg: 'I got clicked at: ' + xy});
});
}
With that, I should be able to listen in my main document for the custom "clicked" event:<!DOCTYPE html> <html lang="en"> <head><!-- load polymer stuff --></head> <body> <click-sink></click-sink> </body> <script> document.addEventListener('clicked', function(e){ console.log(e.detail.msg); }); </script> </html>Now, when I click on the page I get:
I got clicked at: 286,273 I got clicked at: 455,266 I got clicked at: 223,274Nice.
I am especially interested in extending this idea to web services and sockets. If the trouble of setting those up can be hidden behind a web component, leaving only streams of events, I think there can be some really fun possibilities. Which I will start to explore tomorrow.
Day #949
No comments:
Post a Comment