Webtech Walker

JooseでロールオーバーのJavascript書いてみた

takazudoさんのJavascriptのオブジェクト指向の記事、わかりやすくていいですねー。僕も便乗してJavascriptのオブジェクト指向について書いてみます。

今回はJooseでロールオーバーのスクリプト書いてみました。Jooseというのはperlのオブジェクト指向システムのMooseをJavascript版に移植したライブラリです。

joose-js - Google Code

設計する

まずどういう機能を持たせたいかを決めます。

  1. マウスオーバーしとたとき指定した接尾語を後ろに付けた画像のパスに切り替わる
  2. マウスアウトしたとき元画像のパスに切り替わる
  3. ロールオーバーしたい要素を渡すと1、2のイベントを付加する
  4. 付加したイベントを削除できる
  5. ロールオーバー画像をプリロードできる
  6. 初期化したときにしたときに1と4を実行する

ここからロールオーバークラスに必要そうな属性(プロパティ)と動作(メソッド)を洗い出します。上の機能から名詞になるものをプロパティ、動詞になるものをメソッドにする感じです。

プロパティ

  1. ロールオーバーしたい要素
  2. 接尾語
  3. 元画像のパス
  4. ロールー画像のパス

メソッド

  1. マウスオーバーで画像切り替える
  2. マウスアウトで画像に切り替える
  3. 1と2のイベントを付加する
  4. 3のイベントを削除する
  5. プリロードする

まず普通に書く

Joose初めてなので、まず普通に書いてそれをJooseで書いてみることにします。

var Rollover = function(elem, suffix) {
    // 初期化する
    this.namespace = "Rollover";               // 名前空間
    this.elem      = elem;                     // ロールオーバーしたい要素
    this.suffix    = suffix || "_o";           // 接尾語
    this.baseSrc   = elem.getAttribute("src"); // 元画像のパス
    this.overSrc   = this.baseSrc.replace(/\.\w+$/, this.suffix + "$&"); // ロールオーバー後の画像
    this.addEvent();
    this.preLoad();
};

Rollover.prototype = {
    // マウスオーバーで画像切り替える
    changeToOver: function() {
        this.elem.src = this.overSrc;
    },

    // マウスアウトで画像切り替える
    changeToNormal: function() {
        this.elem.src = this.baseSrc;
    },

    // イベントを付加する
    addEvent: function() {
        var self = this;
        $(this.elem)
            .bind("mouseover." + this.namespace, function() { self.changeToOver();})
            .bind("mouseout."  + this.namespace, function() { self.changeToNormal() })
        ;
    },

     // イベントを削除する
    removeEvent: function() {
        $(this.elem)
            .unbind("mouseover." + this.namespace)
            .unbind("mouseout."  + this.namespace)
        ;
    },

     // プリロードする
    preLoad: function() {
        var img = new Image();
        img.src = this.overSrc;
    }
};

// 実行
$(function() {
    var elem = document.getElementById("rollover");
    var rollover = new Rollover(elem, "_over");

    // イベント削除したり
    rollover.removeEvent();

    // 再度つけたりできるよ。
    rollover.addEvent();
});

こんな感じ。イベントの周りだけ面倒なのでjqueryでやってます。あと、イベント削除するために名前空間つかってイベントを付加/削除しています。まあその辺の細かい実装は気にしない感じで。

Jooseで書いてみる

Class("Rollover", {
    // プロパティの設定
    has: {
        namespace: {
            is: "ro",
            init: "Rollover"
        },
        elem: {
            is: "rw"
        },
        suffix: {
            is: "rw",
            init: "_o"
        },
        baseSrc: {
            is: "rw",
            init: function() { return this.elem.getAttribute("src") }
        },
        overSrc: {
            is: "rw",
            init: function() { return this.elem.getAttribute("src").replace(/\.\w+$/, this.suffix + "$&") }
        }
    },

    // コンストラクタ
    after: {
        initialize: function() {
            this.addEvent();
            this.preLoad();
        },
    },

    // メソッド
    methods: {
        changeToOver: function() {
            this.elem.src = this.getOverSrc();
        },

        changeToNormal: function() {
            this.elem.src = this.getBaseSrc();
        },

        addEvent: function() {
            var self = this;
            $(this.elem)
                .bind("mouseover." + this.namespace, function() { self.changeToOver() })
                .bind("mouseout."  + this.namespace, function() { self.changeToNormal() })
            ;
        },

        removeEvent: function() {
            $(this.elem)
                .unbind("mouseover." + this.namespace)
                .unbind("mouseout."  + this.namespace)
            ;
        },

        preLoad: function() {
            var img = new Image();
            img.src = this.getOverSrc;
        }
    }
});

$(function() {
    var elem = document.getElementById("rollover");
    var rollover = new Rollover({elem: elem, suffix: "_over"});
});

こんな感じになります。hasで設定したプロパティに対して自動でsetterとgetterをつくってくれて、リードオンリーなどの設定もできます。型指定とかプライベートなメソッドとかも設定できるといいなー。詳しく調べてないからできるのかもしれないけど。

このくらいの規模だとJoose使ってるメリットがあまり感じられないですけど、Roleとか継承などの機能が豊富みたいなんでコードの見通しはよくなりそうだし大規模な開発には便利かなー。

このエントリーをはてなブックマークに追加