Blog

※ブログ移転しました。 → hamashun.me

2009年12月Archives

2009年12月05日

JS習作:Lightbox風の物を作ってみる

概要

ちょっと遅れましたが、11月4週目のJavaScriptです。やりたかった事は以下。

  • いわゆるLightbox的なアレを作ってみたい
  • サムネイルをクリックするとリンク先の画像を読み込んでサイズを取得、それに合わせてポラロイド風の枠線を付ける
  • できるだけ使いまわしやすく・かつカオスにならないようにする

ソースコード

jQueryを使用しています。 IEは naturalWidth が効かないので、まだ対応できてません。


$(function () {
  var thumbnail = $('#thumbnail li a');                               // このセレクタを変えれば使いまわし可能
  
  thumbnail.click(function(event){
    event.preventDefault();                                           // リンクの遷移を止める
    var clickHref = $(this).attr('href');                             // 以下、クリックしたサムネのリンク先を取得して表示
    $('<img>').attr('src', clickHref).bind('load', function(){        // 内部でDOM生成。続きは画像のロードが終わってから進む
      var htmlElement = $('html');                                    // ブラウザの表示領域(高さ)を取得
      var htmlHeight = htmlElement.height();                          // ブラウザの表示領域(高さ)を取得
      htmlElement.css('height', htmlHeight + 'px');                   // 背景が見切れないようにheightを指定
      var originalImageSize = this.naturalWidth;                      // リンク先の画像サイズ取得
      $('body').append('<div id="hmsnBox"><div id="hmsnBoxOuter" style="height: ' + htmlHeight + 'px;"></div><p id="hmsnBoxInner" style="width: ' + originalImageSize + 'px"><img src="' + clickHref + '" alt="" /><span id="hmsnBoxClose">Close</span></p></div>');  
      $('#hmsnBoxClose').click(function(){                            // 閉じる
        $('#hmsnBox').remove();
      });
    });
  });
});

学んだ事や雑感

ブラウザの表示領域

$("body")で高さを取得したら、縦marginの影響でズレてしまったので、$("html")で取得したら思い通りになった。

$(this)と$("this")の違い

なんか違うらしい。

生成したDOMの中で変数を展開する

  • src="' + clickHref + '"
  • style="height: ' + htmlHeight + 'px;"

こんな感じ。

処理を入れ子にしていく

これまで他の人が書いたコードを見て「なんでこんなにたくさん入れ子になりまくるんだろう」と思っていたのだけど、なんとなくわかったような気がしないでもない。

画像のロードを待つ

jQueryは、単に $('<img>').attr('src', 'hoge.jpg') などとすると、表示はせずに内部で生成してくれる。 で、その画像のサイズを取得する処理が画像自体のロード完了より先に動いてしまうので、上手くいかなかった。

会社の人に聞いて、ロード完了後に取得するようにして解決。 ありがとうございます><

改良したい点

2009年12月08日

JS習作:チェックボックスの一括チェック・解除

概要

12月1週目のJavaScriptです。仕事で似たような物を使う機会があったので、それをまとめてみました。 やりたかった事は以下です。

  • チェックボックスのチェックを、まとめてオンオフしたい
  • オンオフはそれぞれに専用のボタンがあるんじゃなくて、一つにしたい

ソースコード

jQueryを使用しています。

$(function () {
  var checkBoxs = $('input.checkbox');
  $('#allCheck').click(function(){
    if(this.checked) {
      checkBoxs.attr('checked', 'checked');
    } else {
      checkBoxs.removeAttr('checked');
    }
  });
});

学んだ事や雑感

仕様決めの時点的な事

最初は、ボタンでトグルするようにオンオフをしようと思っていたのだけど、それだとオンになるのかオフになるのかがわかりづらいし、オンオフが混在している場合にはどういう動作になるかが微妙だった。

ので、「全てチェック用のチェックボックス」を用意してそれに合わせる事にした。

2009年12月19日

JS習作:Twitter Search的な何か

概要

12月2週目のJSです。 ごくごく簡単なTwitter APIを練習してみました。 やりたかった事は以下です。

  • APIなる物をさわってAjaxなる物をやってみたい
  • Twitterネタで何かやりたい

ソースコード

jQueryを使用しています。

$(function () {
  function twitterSearch(searchWord) {
    $.ajax({
    url: 'http://search.twitter.com/search.json',
    data: {
      'q': searchWord,
      'rpp': 10,
      'lang': 'ja'
    },
    type: 'get',
    dataType: 'jsonp',
    success: function(data){
      $.each(data.results, function(i, itm) {
        $('#twitterSearch').append('<li><a href="http://twitter.com/'+itm.from_user+'/" class="searchResultUser"><img src="' + itm.profile_image_url + '" alt="" width="48" /><span>'+itm.from_user+'</span></a><p class="searchResultText">'+itm.text+'<a href="http://twitter.com/'+itm.from_user+'/status/'+itm.id+'">Status page</a></p></li>');
        });
      }
    });
  }
  $('#searchTwitter').click(function(){
    $('#twitterSearch').empty();
    var searchWord = $('#searchWord').val();
    twitterSearch(searchWord);
  });
});

学んだ事や雑感

Ajaxって何だか難しそう、と思っていた時代が僕にもありました

jQueryを使うと、なんとか理解できるくらいにはなりました。
忘れないようにと復習も兼ねて今回のコードで解説すると、まず一行目の

 $('#searchTwitterForm').after('<ul id="twitterSearch"></ul>');

は、検索結果を出力する場所を作っています。

$.ajax({
    url: 'http://search.twitter.com/search.json',
    data: {
      'q': searchWord,
      'rpp': 10,
      'lang': 'ja'
    },
    type: 'get',
    dataType: 'jsonp',

ここまでが前半で、Twitter に欲しい内容を伝えるための部分。 なんとなくCSSっぽい書式で親しみ深いです。

success: function(data){
      $.each(data.results, function(i, itm) {
        $('#twitterSearch').append('<li><a href="http://twitter.com/'+itm.from_user+'/" class="searchResultUser"><img src="' + itm.profile_image_url + '" alt="" width="48" /><span>'+itm.from_user+'</span></a><p class="searchResultText">'+itm.text+'<a href="http://twitter.com/'+itm.from_user+'/status/'+itm.id+'">Status page</a></p></li>');

        });

これが、通信が成功した後に取ってきたデータをどう処理するのか、という部分。
ここまでの流れが、jQueryでAjax開発をする時の基本的な部分かなと。

$('#searchTwitter').click(function(){
    $('#twitterSearch').empty();
    var searchWord = $('#searchWord').val();
    twitterSearch(searchWord);
  });

ここは、フォームに入力したテキストを上記の処理に渡すための部分です。

APIとクロスドメインの問題

セキュリティの関係上、JavaScriptではドメインの異なるファイルは取得できません。 それをバックエンドに頼らず簡単に解決してくれるのが今回も使ったjsonpなのです。 …が、ちょっとまだ理解しきれてないと言うか。 いや、ソースとして取得するっていうのは解ったんですが、言葉でなく心で理解するまでには至ってないと言うか。 まあ、なじんでないだけかも。

改善した事など

  • 検索結果をURLに持たせたい(少し調べたらいけそう)
  • ページングを出したい

※IE8では動作が確認できたんですが、IE Testerだと6,7,8でダメでした。 時間と環境が取れたら純正IE6,7環境でも試してみます。

2009年12月27日

JS習作:clearfixジェネレータ

概要

12月3週目のJavaScriptです。 適用したいセレクタを入力してclearfixのコードを吐き出す何かを作ってみました。 出力のセレクタ部分はカンマで改行することもできます。

単純に文字列を取得して定型文に組み込んでいるだけなんですが、組み込む場所がまちまちだったりして書いてる内に混乱してきました。 シンプルにできる事を複雑にしてしまってる気がする。。。

ソースコード

jQueryを使用しています。

$(function () {
  $('#clearfixGeneration').click(function(){
    $(this).empty();
    var new_line_switch = $('#newLineOn').attr('checked');
    var selecter_val = $('#selecterInput').val();
    var comma_length = selecter_val.split(',').length;
    var selecter_text = selecter_val.split('\n');

    for(i=0; i<comma_length; i++) {
      var selecter_ie6 = '* html ' + selecter_text[i];
      var selecters_ie6 = selecter_ie6.replace('\n', '');
      if (ie6) {
        ie6 = ie6 + selecters_ie6;
        if(new_line_switch) {ie6 = ie6.replace(',*', ',\n*');}
      } else {
        var ie6 = selecters_ie6;
        if(new_line_switch) {ie6 = ie6.replace(',*', ',\n*');}
      };
      var selecter_ie7 = '*:first-child+html ' + selecter_text[i];
      var selecters_ie7 = selecter_ie7.replace('\n', '');
      if (ie7) {
        ie7 = ie7 + selecters_ie7;
        if(new_line_switch) ie7 = ie7.replace(',*', ',\n*');
      } else {
        var ie7 = selecters_ie7;
        if(new_line_switch) ie7 = ie7.replace(',*', ',\n*');
      };
      var selecter_modernbrowser = selecter_text[i] + ':after';
      var selecter_modernbrowser_substitution = selecter_modernbrowser.replace(',:after',':after,');
      var selecters_modernbrowser = selecter_modernbrowser_substitution.replace('\n', '');
      if (modernbrowser) {
        if(new_line_switch) {
          modernbrowser = modernbrowser + selecters_modernbrowser.replace(':after,', ':after,\n');
        } else {
          modernbrowser = modernbrowser + selecters_modernbrowser;
        }
      } else {
        if(new_line_switch) {
          var modernbrowser = selecters_modernbrowser.replace(':after,', ':after,\n');
        } else {
          var modernbrowser = selecters_modernbrowser;
        }
      };
      $('#clearfixDone').val(''+ ie6 +' {\n\tzoom: 1;\n}\n\n'+ ie7 +' {\n\tzoom: 1;\n}\n\n'+ modernbrowser +' {\n\tcontent: ".";\n\tdisplay: block;\n\tclear: both;\n\theight: 0;\n\tvisibility: hidden;\n}');
    }
  });
});

改良したい点

  • なんかもっと短くまとめて書けると思う。 ブラウザごとに似た処理を3回やってるので、そこを関数にすればいいんだろうか。 でもそうなると引数が多くなるような気がするけどそこは気にしないでいいのかなーとか。 もにょもにょ。
  • 入力するセレクタは改行くぎりでないと思った通りにならないので(split()を\nでやってるので)、カンマ区切りにも対応したい