2009年04月04日 06:19

優れたナビゲーションを真似てみる

| http://www.kantenna.com/cgi-bin/mt/mt-tb.cgi/453

勉強のため優れたナビゲーションを再現してみる。もちろん完全再現ではない。 とりあえず今回はNavigation Menus: Trends and Examples | Design Showcase | Smashing Magazine で紹介されていたPlayground Blues。美しいですね。

現在の手持ちの武器は少々のJavascriptの知識と少々のjQueryの知識と少々のCSSの知識。 心許ないが仕方ない。

CSSとHTML

まずはHTMLとCSS。必要最小限で。


/* CSS */
body {
    margin: 0px;
    padding: 0px;
}

/* HTML */
<div id="SideMenu">
<ul>
    <li><a href="">リスト1</a></li>
    <li><a href="">リスト2</a></li>
    <li><a href="">リスト3</a></li>
    <li><a href="">リスト4</a></li>
    <li><a href="">リスト5</a></li>
</ul>
</div>

Javascript

まずはライブラリ利用せずに書く。 実行結果はこちら。

コード


onload = function() {
    sideMenu({id:"SideMenu", height:50, width:100, img:"menu.gif"});
}

var sideMenu = function(params)
{
    var erea = document.getElementById(params["id"]);
    var ul = erea.getElementsByTagName("ul")[0];
    var lis = erea.getElementsByTagName("li");
    var as = new Array();

    var default_height = params["height"] + "px";
    var default_width = params["width"] + "px";
    var default_bp = -params["width"];

    // ULの設定
    ul.style.height = params["height"] * lis.length;
    ul.style.width = default_width;
    ul.style.margin = "0px";
    ul.style.padding = "0px";
    ul.style.listStyle = "none";

    for (var i=0; i<lis.length; i++) {

        // 必要なら各LIにidをセット
        /*
        var li_id = document.createAttribute("id");
        li_id.value = params["id"] + "Li" + i;
        lis[i].setAttributeNode(li_id);
        */

        lis[i].style.height = default_height;
        lis[i].style.width = default_width;
        lis[i].style.margin = "0px";
        lis[i].style.padding = "0px";
        lis[i].style.listStyle = "none";
        lis[i].style.textIndent = "-9999em";

        // LI a の設定
        as[i] = lis[i].getElementsByTagName("a")[0];
        as[i].style.display = "block";
        as[i].style.height = default_height;
        as[i].style.width = default_width;

        var iheight = params["height"] * i;

        as[i].style.background = "url(" + params["img"] + ") no-repeat -" + default_width + " -" + iheight + "px";

        as[i].myHeight = -iheight + "px";

        as[i].myFunc = function()
        {
            var default_bp = -params["width"];
            var self = this;

            var over_timer = setInterval(function(){
                default_bp += 10;
                if (default_bp <= 0) {
                    self.style.background = "url(" + params["img"] + ") no-repeat " + default_bp + "px " + self.myHeight;
                } else {
                    clearInterval(over_timer);
                }
            }, 1);

            // マウスはなれたとき
            this.onmouseout = function()
            {
                clearInterval(over_timer);
                var out_timer = setInterval(function(){
                    default_bp -= 10;
                    if (default_bp >= -params["width"]) {
                        self.style.background = "url(" + params["img"] + ") no-repeat " + default_bp + "px " + self.myHeight;
                    } else {
                        clearInterval(out_timer);
                    }
                }, 1);
            }
        }

        /* マウスオーバーした時
         * 自分自身の関数実行
         */
        as[i].onmouseover = function() {
            this.myFunc();
        }
    }
}

firefox3、ie6、ie7にて動作確認。ie6で動いたのはうれしい誤算w ただ動きが等速直線運動で塩分高め。

paramsはget、set備えたclass作ったほうがよかった気がします。 とはいえメニューの項目が頻繁に変わるようでなければjavascriptではアニメーションだけをやって その他はCSSで静的に設定しておいた方が楽ですね。

jQuery

次はjQueryを利用して再現してみます。実行結果はこちら。


<script type="text/javascript" src="http://ajax.googleapis.com/ajax/libs/jquery/1.3.2/jquery.min.js"></script>
<script language="javascript">
$(function(){
    var params = {id:"SideMenu", height:50, width:20, img:"menu.gif"};
    var ul = $("#SideMenu ul");
    var lis = $("#SideMenu li");
    var as = $("#SideMenu a");

    ul.css({
        padding:"0px",
        margin:"0px",
        listStyle:"none"
    });

    lis.css({
        height:params["height"],
        width:params["width"],
        textIndent:"-9999em",
        padding:"0px",
        margin:"0px",
        listStyle:"none"
    });

    as.each(function(i){
        var h = "-" + params["height"] * i + "px";
        $(this).css({
            background:"url(" + params["img"] + ") no-repeat right " + h,
            display:"block",
            height:params["height"],
            width:params["width"]
        });

        $(this).hover(function(){
            $(this).animate({width:"100px"}, "fast", "swing");
            $(this).css({background:"url(" + params["img"] + ") no-repeat left " + h});
        },function(){
            $(this).animate({width:params["width"]}, "nomal", "swing");
            $(this).css({background:"url(" + params["img"] + ") no-repeat right " + h});
        });
    });
});
</script>

なんかカクカクしてますね。これは伸縮と同時にbackground-positionを変更してるからっぽい。 本家はmarginをアニメーションさせてるようです。

jQueryではイージングのプラグインjQuery Easing Pluginを 利用することで色々な動きができるようです。

javascriptだけのと違うのは当たり判定。小さくなってるんですがエリアは大きい方がいいですね。

Ajaxライブラリリファレンス

著者 : 古籏 一浩 / 金額 : ¥ 2,940

優れたナビゲーションを真似てみるタグ:

トラックバック

  • http://www.kantenna.com/cgi-bin/mt/mt-tb.cgi/453
コメント (0)
コメントを投稿

(いままで、ここでコメントしたことがないときは、コメントを表示する前にこのブログのオーナーの承認が必要になることがあります。承認されるまではコメントは表示されません。そのときはしばらく待ってください。)





この情報を登録しますか?


先月アクセスが多かったページ