Hatena::ブログ(Diary)

四角革命前夜

2014年01月18日(土)

History API

適当にhistory#pushStateとhistory#replaceStateとonpopstateイベントを試した。

しばらく使ってなかったけど、generator-prototyping便利かも。


を何回か読み直したらだいたい理解出来た気がする。

どうせ自分でSPAのページ作るなり、実践しないと覚えられないし理解できないんだし、とりあえず今は何となく理解できた感じで良しとしておくのが一番なのかな。

2013年01月15日(火)

Server-Sent Eventsを試してみたよ

以前から気になっていたServer-Sent Eventsを試してみました。


index.js

var http = require('http'),
    router = require('http-router'),
    routes = new router;

routes
  .get('/', function(req, res, next) {
    res.writeHead(200, {
      'Content-Type': 'text/html; charset=utf-8'
    });
    res.end([
      '<!DOCTYPE html>',
      '<meta charset="utf-8">',
      '<title>Server-Sent Events</title>',
      '<script>',
      'document.addEventListener("DOMContentLoaded", function() {',
      '  var EventSource = window.EventSource || window.MozEventSource,',
      '      es = new EventSource("/event");',
      '',
      '  es.onmessage = function(event) {',
      '    document.write("<p>" + event.data + "</p>");',
      '    (event.data === "end") && event.target.close();',
      '  };',
      '}, false);',
      '</script>'
    ].join('\n'));
  })
  .get('/event', function(req, res, next) {
    res.writeHead(200, {
      'Content-Type': 'text/event-stream',
      'Cache-Control': 'no-cache',
      'Connection': 'keep-alive'
    });
    writeData();

    function writeData() {
      var count;

      writeData.count || (writeData.count = 0);
      count = writeData.count;

      if (count > 10) {
        res.write('data: end\n\n');
        return;
      }
      console.log(count);
      res.write('data: ' + String(count++) + '\n\n');
      writeData.count = count;
      setTimeout(writeData, 1000);
    }
  });

http.createServer(function(req, res) {
  if (!routes.route(req, res)) {
    res.writeHead(500);
    res.end();
  }
}).listen(80);

setup

$ npm install http-router
$ sudo `which node` index.js

試してみる

Firefox 18.0でがんばって試してたのですが、どうやらまともに動作しない模様。

Google Chrome 25.0 (dev channel)だと思った通りに動作してくれたのでChromeで確認しました。

確認と言ってもhttp://localhost/にアクセスすると1秒置きに数字が書かれていくだけなのですが。


でもまあ、疑似AJAXらしいのでWebSocket使った方がよいのかと……

でもこれはこれで使い道がありそうな感じではありますなー。


参考:

Server-Sent Eventsの利用(1/5):JavaScriptによるHTML5プログラミング入門 - libro

Node.jsでServer-Sent Eventsを使ってみた : swdyh

2012年01月04日(水)

初めてのWebWorkers

新年のやる気のあるうちにやっておこうと思い、WebWorkersを試してみたのです。

jsdo.itでファイルアップロード機能があったので、そこでやろうかと思ったら画像とか

マルチメディア系のファイルでないとアップロードできないみたいで……

仕方なしにローカル環境で試したのでした。

環境:MacOS 10.7.2 64bit / Google Chrome 17.0.963.12 dev


mongoose httpd

お手軽httpdであるmongooseをダウンロードしてきます。

Google Code Archive - Long-term storage for Google Code Project Hosting.

Windowsだとexeをダウンロードするだけなのでコンパイル作業は必要なく、これまたラクチンです。

今回はMacなのでmongoose-3.0.tgzをダウンロードしてきます。

その後は展開、コンパイルを以下の要領でします。

$ mv ~/Downloads/mongoose-3.0.tgz {作業フォルダ}
$ cd {作業フォルダ}
$ tar xvfz mongoose-3.0.tgz
$ cd mongoose/
$ make mac

ついでにhttpdの実行を。

$ ./mongoose -d no -i index.html -r ../

index.html / worker.js

作業フォルダにindex.htmlという名前で以下を保存します。

<!DOCTYPE html>
<html lang="ja">
<head>
  <meta charset="utf-8">
  <title>初めてのWebWorkers</title>
</head>
<body>
  <script>
    (function(){
      var MAX_SIN = 30,
          w = new Worker('worker.js');
      // w.onmessage = function(event) { ... };
      w.addEventListener('message', function(event){
        document.write(
          // event.data === result
          JSON.parse(event.data).join('<br>')
        );
      }, false);
      w.postMessage(MAX_SIN);
    }());
  </script>
</body>
</html>

同じく作業フォルダにworker.jsという名前で以下を保存します。

onmessage = function(event) {
  // event.data === MAX_SIN
  var i,
      result = [];
  for (i = event.data; i >= 0; i -= 1) {
    result[i] = Math.sin(i);
  }
  postMessage(JSON.stringify(result));
};

あとはWebWorkersに対応しているブラウザでhttp://localhost:8080/を見ると、

sin(0..30)までが表示されているはず。


postMessageするときにJSONにしていますが、確か最近のブラウザだとオブジェクトとかも渡せるとかなんとか。

なのでわざわざJSONにする必要もないかと思います。……初期?は文字列だけ、って制約が確かあったような。


でもこれだとWebWorkersが動作しているらしい、ということはわかっても

CPU負荷が分散されてるかどうかわからない……

なのでもうちょっとコードを変更する必要があります。が、それは次回にでも……(次回があるのか?)

あとSharedWorkerも使ってみないと……

WebWorkersでエラー表示

最近のブラウザだとワーカ内でエラーが起こった場合、コンソールに表示してくれるけど、

ちょっと古いブラウザだと表示も何もしてくれないとか…… というわけでエラーの表示を。

上の記事にちょっと手を加えたものを以下に。

環境:MacOS 10.7.2 64bit / Google Chrome 17.0.963.12 dev


--- index.html  2012-01-04 23:13:02.000000000 +0900
+++ diff.html 2012-01-04 23:07:26.000000000 +0900
@@ -16,17 +16,6 @@
           JSON.parse(event.data).join('<br>')
         );
       }, false);
-
-      // w.onerror = function(event) { ... };
-      w.addEventListener('error', function(event){
-        var messages = [
-          'filename: ' + event.filename,
-          'lineno: ' + event.lineno,
-          'message: ' + event.message
-        ];
-        document.write(messages.join('<br>'));
-      }, true);
-
       w.postMessage(MAX_SIN);
     }());
   </script>
--- worker.js	2012-01-04 23:11:435669325112 +0900
+++ diff.js	2012-01-04 23:12:20.909898919 +0900
@@ -2,6 +2,7 @@
   // event.data === MAX_SIN
   var i,
       result = [];
+  document;
   for (i = event.data; i >= 0; i -= 1) {
     result[i] = Math.sin(i);
   }

と編集して、http://localhost:8080/にアクセスすると

filename: http://localhost:8080/worker.js
lineno: 4
message: Uncaught ReferenceError: document is not defined

と表示される。ブラウザはほぼ最新なので、JavaScriptコンソールにも表示されてた。


var messages = [
  'filename: ' + event.filename,
  'lineno: ' + event.lineno,
  'message: ' + event.message
];
document.write(messages.join('<br>'));

でなくても

document.write([
  'filename: ' + event.filename,
  'lineno: ' + event.lineno,
  'message: ' + event.message
].join('<br>'));

でよかったかも。

2011年08月07日(日)

Canvasで7セグメントLED

7セグメントLED - jsdo.it - share JavaScript, HTML5 and CSS


作るのが大変だった割にはそんなに面白い訳でもなく。

16セグメントLEDも作りたかったけど無理!

2011年07月31日(日)

Canvasでオシロスコープ

後輩に「Canvas教えてください!」と言われたのでCanvasの練習を兼ねて作ってみました。

教えてくださいと言われて教えない訳にいかないし、でもCanvasいじったこと全然ないし、という状態で。

Canvas Oscilloscope - jsdo.it - share JavaScript, HTML5 and CSS


結構大変だった……

でもやればなんとかなるもんですね。


全然本格的じゃないし、単位もついてないし目盛りもついてないけど……

その上、用語も間違ってそうな気が。まあいいか。


オシロスコープなんて……最後に触ったのいつだろう。3年くらい前?