2009年8月17日月曜日

NodeListとHTMLCollection

HTMLDocumentには、document.imagesとかdocument.formsとか、DOM Treeからある要素のみを返すアクセッサがあります。

それとは別に DOM Coreには getElementsByTagName() というメソッドがあります。

これらは同じものだと勘違いしていたのですが、document.xxx はHTMLCollection, getElementsByTagName() は NodeListを返します。


で、HTMLCollection は NodeListを継承しているわけではないのです。

ま、HTMLCollection は NodeListと同じ属性とメソッドを持っているので、JavaScriptから見れば同じとみなしていいのかもしれませんが、どうも違和感が。。。

2009年8月16日日曜日

モジュール性



ちょっと調べたいことがあって
メイヤーの『オブジェクト指向入門』を読んでいたら、モジュール性の5つの基準が書いてあった。
以下抜粋。
  • 分解しやすさ
  • 組み合わせやすさ
  • わかりやすさ
  • 連続性
  • 保護性

お、こんなの知らなかったぞ(汗

で、分解しやすさの説明に(抜粋)
  • 依存関係は最小限に抑えなければならない。そうしなければ、個々のサブシステムの開発がほかのサブシステムの作業の進み具合によって限定される可能性がある。

うぅ、なんだか耳が痛い話。

ほかにも再利用性とか、いろいろためになる&&できていないはなしがちらほら。

分厚い本なので、調べモン程度にしか使わなかったけど、こりゃ一回通読しておいたほうがよさそうだな。

2009年8月15日土曜日

event handler content attributes

onXXXといったイベントハンドラを書ける属性がありますが、

HTML4.01のときは、この属性がかける要素が決まっていました。
HTML4.01のIntrinsic events
これが、HTML5だと、Global attributesとして定義されているので、すべての要素に書けます。

ということは、そのイベントハンドラが呼ばれるかどうかは、その要素にイベントを発火させられるかどうかということになります。

だから、「この要素にこのイベントハンドラを書けるのか」という質問されると、「この要素はフォーカスが当たるからonfocus/onblurが書ける」とか、そういった説明をしなければいけません。
これが、HTML5の要素はかなりあるので、意外と面倒くさいです。

ちなみに、実はHTML4.01では<img>要素にonload属性は書けませんでした。
(書いてあるコンテンツは結構あるみたいですが。)

でも、HTML5では、どの要素にもonload属性が書けるようになったので、リソースをロードする<img>要素ではloadイベントが発火するので、onloadイベントハンドラは呼ばれるのは正しい仕様です。

<img>要素の例を考えると、HTML5の考え方のほうが自然なのかもしれませんね。

2009年8月3日月曜日

はじめてのObjective-C

意味はないけどムシャクシャするので、
Objective-Cでコードを書いてみた。
いや、別にムシャクシャはしていないけど。

ということで、helloWorldを。

hello.m
#import 
#import 

@interface TestClass : Object
  - (void) getMessage;
@end
hello.m

#import "hello.h"

@implementation TestClass
  - (void) getMessage {
  printf("Hello Objective-C World\n");
}
@end

int main(int argc, char *argv[])
{
  id obj = [ TestClass alloc ];
  [ obj getMessage ];

  return 0;
}

Ojbective-Cは @interface で、クラスの定義を行い、@implementationでクラスの実装を行う。

サンプルでは、- (void) getMessage;というメソッドを@interfaceで定義し、@implementationで実装している。 "-"はインスタンスメソッドと言う意味。

一応C言語なので、Cの標準ライブラリをimportすれば使用できる。

で、メソッドの呼び出しは[]で行う。

Objective-Cはsamlltalkと同じメッセージ形式なので、[obj getMessage]は、objに対してgetMessageというメッセージを送信しています。
allocはNewと同じ。

Linuxでのコンパイルは
$gcc -v -Wall -Os -o hello  hello.m -lobjc
とする。-lobjcというのが必要なんですな。

しかし、Objective-Cとかいっても、これじゃどう見てもC言語には見えませんな。

2009年7月24日金曜日

rubyとCの可変長引数

rubyに可変長引数が書けることを知らなかったので、覚書。

*を使えば可変長引数を配列として受け取れるようだ。

引数の1つ前に*を入れれば、その位置の引数を配列として受け取れる。

def max(first, *rest)
  max = first
  rest.each {|x| max = x if x > max }
  max
end
と書いて、

max(1,2,3)

と書けば、first1, rest[2,3]になるようだ。

ちなみに、C言語での可変長引数は以下のようになる。

以下は第1引数で渡す数字の個数を、残りの引数をデバッグプリントとする関数です。

#include 
#include   /* 可変長引数に必要な変数 */

void foo(int i, ...)
{
  int j;
  va_list ap;

  va_start(ap, i);  /* ポインタ引数apを引数iの次の位置に持っていく */
  for (j = 0; j < i; j++) {
    printf("%d\n", va_arg(ap, int));  /* 型を指定してapから、値をとりだす*/
  }
  va_end(ap);
}

int main(void)
{
  foo(3, 1, 2, 3);
  return 0;
}
でも可変長引数って基本使いませんよね。
だから忘れちゃうんですよね;

2009年7月23日木曜日

1日1ハック

最近全然更新していませんでしたm(_ _)m


さいきんちょっと仕事で疲れてプライベートでコードを書いていませんでした。


Rubyのまつもとゆきひろさんは1日1ハックを必ず行うと

前に聞きに行った講演会で言ってましたが、
これを守るのはかなり大変だなと実感しています。

でも、どんなに疲れていても自分の技術は磨いていかないと、
衰えていく一方なので、今日から頑張ろうと思います!!

2009年5月19日火曜日

開発プロセス

今あるプロジェクトで後悔していることが一つ。
  • きちんと疎結合になるように設計すること
  • テスト容易性を考えること

を徹底するようにもっと強く言うべきだった。。。。
若手の私は、どうしても強く言われると議論に負けてしまう。。。


もちろん、書籍で読んだ知識は理想論で、
経験を多くすることにより、現実的なところの落とし所を見つけられるようになると思うんだけど、
なんだか、開発プロセスとかを武器にして、自分の都合がいいように理論武装をしている人が
多いような気がする。。。

もっと勉強せねば!

もっと強くならねば!

2009年3月28日土曜日

ヘルプ

本日から、あるプロジェクトのヘルプに行くことになりました。
プロジェクトに人を投入すると減速することをブルックス先生がだいぶ昔に証明してくれましたが、
まあそんなことは棚に上げて、こういう機会にプロジェクトのまわし方を勉強していきたいと思います。
ということで、休日出勤がんばるぞ!

2009年3月26日木曜日

YouTube JavaScript Player API で一つの動画を繰り返し再生させてみる

YouTube JavaScript Player API で一つの動画を繰り返し再生させてみました。

swfobject をつかって、swfを埋め込み、playVideo() で再生させます。

onYouTubePlayerReady() は プレーヤーが完全に読み込まれたときに呼び出される特殊な関数です。この関数の中でplayVideo()を呼び出しています。

また、プレーヤーの状態が変化したときは、onStateChangeイベントが発火するので、addEventListenerでイベントハンドラを登録し、動画再生が終わった時点(stateは0)でplayVideo()を読んで、再度再生するようにしています。


<html>
<head>
<script type="text/javascript" src="swfobject.js"></script>
<script type="text/javascript">
function func() {
var params = {allowScriptAccess: "always" };
var atts = {id: "myytplayer" };
swfobject.embedSWF("http://www.youtube.com/v/VIDEO_ID&enablejsapi=1&playerapiid=ytplayer",
"ytapiplayer", "425", "356", "8", null, null, params, atts);
}

function onYouTubePlayerReady(playerId) {
var ytplayer = document.getElementById("myytplayer");
ytplayer.addEventListener("onStateChange", "onytplayerStateChange");
ytplayer.playVideo();
}

function onytplayerStateChange(newState) {
if (newState == 0) {
var ytplayer = document.getElementById("myytplayer");
ytplayer.playVideo();
}
}
</script>
</head>
<body onload="func()">
<div id="ytapiplayer">
Flash.
</div>
</body>
</html>


YouTube JavaScript Player API の詳細は、YouTube JavaScript Player API リファレンスを参照してください。

2009年3月24日火曜日

Google Data API

Google Data APIを勉強しています。
Google Data APIとは、Googleのサービスをブラウザを使わずに、APIを叩くことによって利用するもので、
簡単にいえば、HTTPのコマンド(GET/POST/PUT/DELETE)でATOM/RSSのやり取りを行います。

youtubeとかPicassaとかでも使えるので、いろいろ面白いことを試したいなと思っています。

2009年3月21日土曜日

即席でスライドショウをつくってみた。

せっかく画像をダウンロードしたので、スライドショウをつくってみた。

まず、ディレクトリにあるファイルすべてを img 要素にするスクリプトをかく。

#!/usr/bin/perl

open OUT, "> display.html"
or warn "fail";
opendir DH, ".";
print OUT "<html>\n";
print OUT "<head>\n";
print OUT "<script type=\"text/javascript\" src=\"./slideshow.js\"></script>\n";
print OUT "<link rel=\"stylesheet\" href=\"./slideshow.css\" type=\"text/css\"></link>";
print OUT "</head>\n";
print OUT "<body>\n";
foreach $file (readdir DH) {
if ($file =~ /jpg$/) {
print OUT "<img src=\"";
print OUT "$file";
print OUT "\">\n";
}
}
print OUT "</body>\n</html>\n";


スライドショウのために、slideshow.css と slidesyou.js を用意。


まず、slideshow.css

body {
background-color:black;
}

img {
display : none;
margin-left : auto;
margin-right : auto;
}


つぎに、slideshow.js

var img_list;
var i = 0;

function slide() {
if (i == 0) {
img_list[img_list.length-1].style.display = "none";
} else {
img_list[i-1].style.display = "none";
}
img_list[i].style.display = "block";
if (i == img_list.length-1) { i = 0; } else { i++;}
}

function show(e) {
img_list = document.getElementsByTagName("img");
img_list[img_list.length-1].style.display = "block";
window.setInterval(slide, 10000);
}

window.addEventListener("load", show, false);


まあ、即席で作ったので、だいぶ汚いコードですが・・・。

本当はopacityとか使ってトランジッションとかを派手にしたいんですけど、
今日はここまで。

2009年3月19日木曜日

Webページの画像を保存するPerlスクリプト

Webページにある画像を保存するスクリプトを書いてみました。

#!/usr/bin/perl

use LWP::UserAgent;
use HTML::DOM;
use Digest::MD5 qw(md5_hex);
use Path::Class qw(file);

my $ua = LWP::UserAgent->new;
my $referer = "http://example.com/";
my $url = "http://example.com/";

my $req = new HTTP::Request('GET', $url);
my $res = $ua->request($req);

my $dom_tree = new HTML::DOM;
$dom_tree->write($res->content);
@img = $dom_tree->getElementsByTagName("img");
my $ua2 = LWP::UserAgent->new;
foreach (@img) {
my $filename = Digest::MD5::md5_hex($_->src);
my $filepath = file('./temp', $filename);
unless(-f $filepath->stringify . ".jpg" ) {
$ua2->get( $_->src, ":content_file" => $filepath->stringify . ".jpg", "referer" => $referer);
}
}


LWP::UserAgent は HTTPのリクエストやレスポンスを行うためのモジュールです。
Webページを取得して、それをDOMツリーにして、img要素のsrc属性に記述してある画像ファイルを保存するスクリプトです。

ちょっとはまったのが、はじめに HTML::DOM ではなく、XML::DOM をつかってしまったこと。

もちろん閉じタグがない要素があるので、パースエラーになってしまうのですが、エラーになかなか気づきませんでした。(ちゃんとエラーメッセージ見ろ!って思うけど)

後は、referer を設定しないと アクセスが拒否されるかもしれません。

2009年3月12日木曜日

Perlの勉強

Perlの勉強を始めました。

業務では組み込み系のため、C言語しか使わず、
スクリプト言語はRubyぐらい(しかも、必要最低限しか使わず。。。)
しか使わないので、実はPerlには苦手意識がありました。

でもJavaScriptを勉強しているうちに、
正規表現がいまいち苦手だということがわかり、
「正規表現ならPerlだろ!」という勝手な思い込みから、
勉強を始めることにしました。


で、いざ書いてみると
なかなか癖がある言語だなとおもいました。
サブルーチンの書き方なんかは

sub hello {
my($a, $b) = @_;
print $a+$b
}
hello(1,2);

みたいに、ルーチン名の後に(引数...)の形ではなく、
@_ に引数が格納されて、それを利用するのです。
なんだか、C言語の関数になれていると、すごく気持ち悪く感じるなぁ。。。

2009年3月9日月曜日

Yahoo!ウィジェット

Yahoo!ウィジェット - 開発ツール

Yahoo!ウィジェットを試しに作ってみたんですけど、
なかなか面倒くさかったです。

というのも、Yahoo!ウィジェット用のXMLやDOMを覚えなくてはならないからです。

widgetタグやwindowタグやtextタグとかいろいろ覚えなくてはいけないので、
それが面倒。
OperaとかはHTMLのレンダリングエンジンそのものなので、
そのまま HTML+CSS+JavaScript(+SVG)といったWEB標準の知識で
ウィジェットを作れるので、非常に便利だなと思いました。

ただ、Yahoo!ウィジェットで何ができるかはまだわかっていないので、
もう少し調べようかなと思います。

2009年3月1日日曜日

Google、JavaScript APIを手軽に試せる「AJAX API Playground」を公開

Google、JavaScript APIを手軽に試せる「AJAX API Playground」を公開

こういうのがあると気軽にGoogle APIを勉強ができてうれしい。

JSON feed

feedを JSON形式で返す "JSON Feed"なるものがあるらしいです。
http://delicious.com/help/json/

BloggerからJSON形式でfeedを受け取るAPIを叩いてみるサンプルを書いてみました。
仕様とかはどこに書いてあるかどうかわからないので、
Googleのサンプルを見よう見まねで書いてみました。


<html>
<head>
<script type="text/javascript">
var str = "";
function myfunc(json) {
str += json.feed.title.$t;
str += "<BR>";
for (var i = 0; i <json.feed.entry.length; i++) {
var entry = json.feed.entry[i];
str += entry.title.$t;
str += "<BR>";
}
}

function result() {
document.getElementById("ret").innerHTML = str;
}
</script>
<script type="text/javascript" src="http://sassylog.blogspot.com/feeds/posts/default?alt=json-in-script&callback=myfunc"></script>
</head>
<body onload="result()">
<div id="ret">test</div>
</body>
</html>

JSON

JSONというのは、まあ一言でいえばデータをJavaScriptのオブジェクトリテラルや配列リテラルで表現したもののことです。
データをJavaScriptのオブジェクトで表現して、JavaScript処理系で eval()すれば、あとはJavaScriptのオブジェクトとして処理できる優れものです。

たとえば、XMLで

<person>
<name>Sassy</name>
<age>27</age>
</person>

と書くのを、

{
name : "Sassy",
age : " 27",
}

と書くことができます。
JSON形式はテキストなのでeval()をして捜査します。
以下が例です。

function func() {
var json_txt = '({name : "Sassy", age : "27"})';
var json_obj = eval(json_txt);
document.getElementById("result").innerHTML = json_obj["name"] + ":" + json_obj["age"];
}

XMLHTTPRequestにおいて、Content-Typeが "text/json" だったりしたら、requestText に対してeval()をしてデータを処理するわけです。

昔誰かに「JavaScriptはJSONに対応しているのか?」という問い合わせがあり、
サポートしているも何も、eval()ができるんだからあたりまえじゃないと思ったものです。
こういった新しい情報に対しては常にアンテナを張っておかないといかんなと思う今日頃です。

2009年2月27日金曜日

Argumentsオブジェクト

JavaScriptの関数は、引数の数が固定ではありません。
だから、

function test1(a, b, c) {
/*コード*/
}

とか書いても、

test1("test1");

と呼び出すことができます。
引数が少なかった場合は、残りの引数はundefinedになります。
じゃあ、多かった場合はどうするの?ってことになりますが、
それは Argumentsオブジェクトを利用して取得することができます。
下記はArgumentsオブジェクト(argments)を使って引数を取り出しています。

function argument_test() {
str = "";
for (var i = 0;i <= arguments.length;i++) {
   str += arguments[i];
}
document.getElementById("result").innerHTML = str;
}

function load_func() {
argument_test("test1", "test2", "test3");
}

上記は、test1test2test3が出力されます。

引数にオブジェクトを渡して for/in文で取り出すなんかもできます。

function argument_object_test() {
str = "";
for (var i = 0; i < arguments.length; i++) {
var target = arguments[i];
for (var name in target) {
str += target[name] + " ";
}
}
document.getElementById("result").innerHTML = str;
}

function func1() {
argument_object_test({
aibu: "saki",
horikita: "maki",
ueto: "aya",
});
}


これはJQuerryなんかでも使われていて、

jQuery.extend = jQuery.fn.extend = function() {
// copy reference to target object
var target = arguments[0] || {}, i = 1, length = arguments.length, deep = false, options;

のようにArgumentsオブジェクトを利用しています。
で利用する側は

jQuery.fn.extend({
show: function(speed,callback){
....
});

のようにオブジェクトを渡したりしています。

DHTMLのコンテンツばかり書いていると、
このようなコアJavaScriptについてついつい忘れてしまうものです。
もっと勉強しないとね。


2009年2月25日水曜日

2009年2月22日日曜日

OperaウィジェットでSVGのデジタル時計


ブラウザベンダがFlashやSilverlightのようなリッチコンテンツに対抗するには、標準仕様のSVGをサポートするのが一番であり、OperaはSVGのサポートをガンガン増やしています。
Opera ウィジェットはレンダリングエンジンがブラウザそのものなので、SVGが使用できます。
Operaが入っている環境ならばWindowsだろうがMac OSXだろうがLinuxだろうが、もちろんWiiだろうがSVGを利用したウィジェットを楽しむことができます。



Opera のウィジェットで
SVG を使って画像にあるようなデジタル時計を作成してみました。

config.xml
<?xml version="1.0"?>
<widget>
<widgetname>SVG Clock</widgetname>
<width>350</width>
<height>350</height>
</widget>

index.html
<html>
<head>
<script type="text/javascript" src="script/clock.js"></script>
</head>
<body>
<object id="svgdoc" type="image/xml+svg" data="clock.svg" width="350" height="350" />
</body>
</html>

clock.svg
<svg xmlns="http://www.w3.org/2000/svg">
<g>
<circle cx="150" cy="150" r="140" fill="#FFFFFF" stroke="#0000FF" stroke-width="10" />
<g>
<text x="130" y="50" font-size="30pt">12</text>
<text x="250" y="160" font-size="30pt">3</text>
<text x="135" y="280" font-size="30pt">6</text>
<text x="30" y="160" font-size="30pt">9</text>
</g>
<line xml:id="h_line" x1="150" y1="150" x2="150" y2="0"
stroke="#000000" stroke-width="5" />
<line xml:id="m_line" x1="150" y1="150" x2="150" y2="0"
stroke="#000000" stroke-width="5" />
<line xml:id="s_line" x1="150" y1="150" x2="150" y2="0"
stroke="#FF0000" stroke-width="5" />
</g>
</svg>

clock.js
function clock() {
var svgdocument = document.getElementById('svgdoc').getSVGDocument();
var svgNS = "http://www.w3.org/2000/svg";

var cx = 150;
var cy = 150;
var r = 140;

var now = new Date();
var hou = now.getHours();
var min = now.getMinutes();
var sec = now.getSeconds();
var h_line = svgdocument.getElementById('h_line');
var m_line = svgdocument.getElementById('m_line');
var s_line = svgdocument.getElementById('s_line');

h_rad = 2 * Math.PI * (hou/12);
h_line.x2.baseVal.value = cx + 0.8 * r * Math.sin(h_rad);
h_line.y2.baseVal.value = cy - 0.8 * r * Math.cos(h_rad);

m_rad = 2 * Math.PI * (min/60);
m_line.x2.baseVal.value = cx + r * Math.sin(m_rad);
m_line.y2.baseVal.value = cy - r * Math.cos(m_rad);

s_rad = 2 * Math.PI * (sec/60);
s_line.x2.baseVal.value = cx + r * Math.sin(s_rad);
s_line.y2.baseVal.value = cy - r * Math.cos(s_rad);

setTimeout(clock, 1000);
}

window.addEventListener('load',
function(e){ clock();},
false);

2009年2月19日木曜日

GM_setValue / GM_getValue

覚書。

GM_setValue はFirefoxを終了させたとしても消えないデータを作成する事ができる。
GM_setValue(name, value)で設定できる。

GM_getValue は GM_setValue で設定した値を取得できる。
GM_getValue(name)で取得できる。
GM_getValue(name, default) でデフォルト値を設定して、値が取れなかった時も対応できる。

これを利用すれば、prototype.js を GreaseMonkey で簡単に使えるようになるようです。
prototype.js を GM_setValue() で設定して、利用するときは GM_getValue() で取得してevalすればできるようです。
Greasemonkeyで永続的に外部スクリプトを利用する

2009年2月18日水曜日

グリモンでXPath

XPathって何に使われているかいまいちよくわからなかったけど、
ユーザスクリプトでwebページを加工するのに便利そう。

練習で、yahooの要素を目立たせるスクリプトを書いてみた。


// ==UserScript==
// @name xpath_test
// @namespace sassy
// @description xpath test
// @include http://www.yahoo.co.jp/
// ==/UserScript==

(function(){
var xp = document.evaluate("//span", document, null, XPathResult.ORDERED_NODE_SNAPSHOT_TYPE, null);
for (var i = 0; i <>
xp.snapshotItem(i).style.background = "#FF0000";
}
})()


Document.evaluate() でXPathで指定した要素を探し、 XPathResult.snapshotItem()で検索結果の要素を参照しています。
XPathについては下記が参考になると思います。
https://developer.mozilla.org/ja/Introduction_to_using_XPath_in_JavaScript

2009年2月16日月曜日

絶滅危惧種


現在、社内で唯一のSVG担当者となってしまっているため、SVGに関する質問はほぼ100%僕のところに来ます。
ちょっと前まで、「俺に任せろ!」と胸を張っていたわけですが、ここのところずっとSVGに関してはご無沙汰であるため、たまに質問がくるとうまく答えられないことがあります。
今日もに関して質問されて、即答できませんでした。。。

これではいかん。SVGの仕様書をもう一度読みなすつもりです。
http://www.w3.org/TR/SVGTiny12/

はじめてのグリモンスクリプト

とりあえず、練習で書いてみた。

アメブロの文章のbackgroundColorを水色にして、フォントをboldにしてみました。


// ==UserScript==
// @name BlogWatch
// @namespace sassy
// @description blogを観るScript
// @include http://ameblo.jp/*
// ==/UserScript==

(function(){
var title = document.getElementsByTagName("div");
var div = document.getElementsByTagName("div");
for (var i = 0; i <>
if (div[i].className == "subContents") {
div[i].style.backgroundColor = "#99FFFF";
div[i].style.fontWeight = "bold";
}
}
})()


どうだ!(ほんとうに簡単なスクリプトだから自慢する意味がないんだけど。)

しかし、以前友人が JavaScript でクラス名でノードが取れないのは不便だ!っといっていましたが、たしかに不便ですね。CSSのためにめちゃめちゃclass使っているコンテンツもあるわけだし。

たぶん、DOM的にはclassなんていう概念は存在しないのだろうけど、(Nodeを特定するのはidなわけだし)でも現実的にはあった方が便利そうだな。

2009年2月15日日曜日

Greasemonkey

自宅のFireFoxにGreasemonkeyを導入しました!!
仕事では、テストのためにJavaScriptをちょこちょこ書いていますが、実はかなり自信がないため、
「自分のブラウジング生活が向上し、JavaScriptのスキルも向上し一石二鳥やん!素敵やん!」
と思い、入れていました。(会社のFireFoxには入れているけど、全く使ってなかったなぁ。。。。)

とりあえず、貪欲にいろいろ書いてみよっと!

2009年2月14日土曜日

モンスターハンター

最近、もっぱらモンスターハンターにはまっております。だいたい、毎日1時間ほどプレイしており、もうかれこれ、半月くらいたちました。

現在、ティガレックスが倒せず、伸び悩み中。片手剣じゃ限界なのかな。。。