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