ラベル jQuery の投稿を表示しています。 すべての投稿を表示
ラベル jQuery の投稿を表示しています。 すべての投稿を表示

2011/07/01

jQuery Mobile Alpha版でのバグ起票

jQuery Mobileに起票してみました。


Beta -> Alpha版にしたら、同じname属性を持つチェックボックスが排他になっていた。
https://github.com/jquery/jquery-mobile/issues/1944#issuecomment-1540245

2011/05/04

jQuery1.6 attrとpropについて

今日、jQuery1.6出ましたね。

jQueryはバージョンが変わるたびに微妙に仕様が変わますね!
話はそれますが、先日も業務で$.ajaxを使っていたところ、1.4からserializeメソッドの挙動が変わったらしく、ものすごーくハマりました(別起票で書きます)。

話はそれましたが…1.6からattrの挙動が変わり、新しくpropメソッドが追加されました。
詳しくは本家にありますので、そちらもご参照ください。

※attrでの属性書き換えは、1.6.1になってから後方互換になりました。
なので、1.6.1を使えば問題は起きなさそうです。

・1.6からattrメソッドの戻り値が変わる
こんなhtmlがあった場合
<input type="checkbox" id="hoge1" checked="checked"/>

1.6より前
var hoge = $("#hoge1").attr("checked");
// 戻り値は、ブール値「true」
hoge === true;

1.6以降
var hoge = $("#hoge1").attr("checked");
// 戻り値は、文字列「"checked"」
hoge === "checked";

ただし、htmlにchecked属性が書かれていない場合(後から画面上でチェックを付けたりしても)
戻り値は、undefinedとなる!
<input type="checkbox" id="hoge1" />
var hoge = $("#hoge1").attr("checked");
// 戻り値は、文字列「undefined」
hoge === void(0);




・attrの代わりに、propメソッドを使うと…
propメソッドを使うと、戻り値がブール値で返ってきます。

チェックされてる場合
var hoge = $("#hoge1").prop("checked");
// 戻り値は、ブール値
hoge === true;

チェックされてない場合
var hoge = $("#hoge1").prop("checked");
// 戻り値は、ブール値
hoge === false;
チェック/非チェックの書き換えも簡単にできます
// チェックを付ける
$("#hoge1").prop("checked", true);
$("#hoge1").prop({checked:true});

// チェックを外す
$("#hoge1").prop("checked", false);
$("#hoge1").prop({checked:false});


・その他注意すること
1.セレクタで複数要素取得した場合、each等使い一個一個処理をする!
propメソッドは、「セレクタで複数要素を取得した場合、最初にマッチした要素しか処理しないよ!」とあるので、複数要素を処理したい場合は$.eachとかを使うようにする。
<form method="GET">
 <input type="checkbox" id="hoge1" />
 <input type="checkbox" id="hoge2" checked="checked"/>
 <input type="checkbox" id="hoge3" />
</form>
$.each($("input"), function() {
    $(this).prop("checked", true);
});

2.IE9より前のバージョンだと、使い方によってメモリーリークが起きるかも問題
詳しくは、ここを参照してください。
DOM要素がdocumentから削除されるより前に、対象のプロパティーが削除(.removeProp()とか使って)されてない場合、DOM要素のプロパティをプリミティブ型(数値、文字列、ブール値)以外にセットするのに.propメソッドを使うとメモリーリークが起きるっぽい
(Macだから試せないけど。誰かWindows使ってる人試してください)。
IEでメモリーリークを引き起こしたくなかったら、dataメソッド(DOM要素にメタデータを持たせるアレです)を使うと安全みたいです。

2011/03/06

Flickrから画像を取得してくるSampleを書いた

Flickrから画像を取得して、表示するモジュールを書いた。

・キーワードを省略するとデフォルト「js」で検索されます。
・件数には整数値を入力してください。
 数値チェックはめんどくさいのでやってません。
 件数は100くらいがよいと思います(画像問い合わせが重いので)

demo:
http://shinya-api.appspot.com/sandbox/flickr/flickr.html


html:

     <div id="hoge">
      <img id="loading_img" src="img/loadinfo.gif" />
     </div>
        <div>キーワード : <input type="text" class="in" id="keyword" name="keyword" value="" /></div>
        <div>件数 : <input type="text" class="in" id="size" name="size" value="" /></div>
  <div><button onclick="flickr.exec();">exec</button></div>
  <hr />
  <div id="target"></div>
  <script type="text/javascript" src="js/flickr.js"></script>
  <script type="text/javascript" src="http://ajax.googleapis.com/ajax/libs/jquery/1.5/jquery.js"></script>
  <script type="text/javascript" src="/js/shinya/jquery.toggleInputMsg.js"></script>
  <script>
   // id指定・オプション指定の場合
   //$('#keyword').toggleInputMsg({'value':'ほげ','color':'red','inputColor': 'blue'});
   // class指定、オプション無しの場合
   $('.in').toggleInputMsg();
  </script>



css:

body {
    background-color:#000000;
    color:#00ff00;
    margin:0;
    padding:0;
   }
   #hoge {
    width:200px;
    height:100px;
    background-color:#6F6F6F;
    opacity:0.8;
    position:absolute;
    display:none;
   }


js:

/**
  * JSONPでflickr APIへアクセス
  */
var flickr = (function() {
 var B = document.body,
  t = document.getElementById('target');
  hoge = document.getElementById("hoge") || alert("要素がないよ"),
     hst = hoge.style,
     limg = document.getElementById("loading_img") || alert("要素がないよ");
     limgs = limg.style,
     d = document.documentElement;;
 return {
  /** APIを呼び出す */
  exec : function() {
      var script = document.createElement('script');
      script.src = imageCreator.getApiURL();
      B.appendChild(script);
   hst.display = "inline";
   hst.height = window.innerHeight;
   hst.width = window.innerWidth;
   limgs.position='absolute';
   limgs.top = d.clientHeight / 2 -12;
   limgs.left = d.clientWidth/ 2 -12;
  },
  /** APIのcallback */
  callBackFuncForJson : function(data) {
   var i,
    photo,
    photos = data.photos;
   hst.display = "none";

   for (i = 0; photo = photos.photo[i]; i++) {
    var img = document.createElement('img');
    img.src = imageCreator.getImageURL(photo);
    t.appendChild(img);
   }
   if (i === 0) { alert('no much!');}
  }
 }
})();

/**
  *creator
  */
var imageCreator = function() {
 return {
  getImageURL : function (photo) {
    return "http://farm" + photo.farm +
        ".static.flickr.com/" + photo.server +
        "/" + photo.id +
        "_" + photo.secret +
        "_s.jpg";
  },
  getApiURL : function () {
   return "http://api.flickr.com/services/rest/?method=flickr.photos.search&api_key=d4009274a471c6b5448e87debe7d38bd"
    + "&format=json&jsoncallback=flickr.callBackFuncForJson&safe_search=1&content_type=1&sort=relevance"
    + "&text=" + (document.getElementById("keyword").value || "js")
    + "&per_page=" + (document.getElementById("size").value || "50");
  }
 };
}();

flickr.defaultMsgKeyword = "キーワードを入力してください";
flickr.defaultMsgNumber = "取得件数を入力してください";
(function() {
 
})


せっかくなのでinputフォームにデフォルト文字列を埋め込むモジュールを
jQuery plugin形式にしてみました。

/**
 * テキストエリアのデフォルトメッセージを設定する。
 * @author shinya
 */
var defaultMsg = "何か入れてください";
(function($) {
 $.fn.toggleInputMsg = function(opt) {
  var defaults = {
   'value' : '入力してください',
   'color' : '#696969',
   'defaultColor' : '#000000'
  }
  
  var setting = $.extend(defaults, opt);

  for (var i = 0, len = this.length; i < len; i++) {
   this[i].style.color = setting.color;
   this[i].value = setting.value;
   
   this[i].addEventListener("focus", function() {
    if (this.value == setting.value) {
     this.style.color = setting.defaultColor;
     this.value="";
    }
   });
   this[i].addEventListener("blur", function() {
    if (this.value == "") {
     this.style.color =  setting.color;
     this.value=setting.value;
    } 
   });
  }

  return this;
 };
})(jQuery);

2011/02/24

jQueryのclckでみる、bindとliveの違い

jQueryを使っていると似たような動きをするメソッドを見かけます。
今回はクリックイベントで呼ばれるbindとliveの違いをメモ。

jQuery1.3からliveが追加されました。
今まではjQueryのafterを使って動的に作られた要素に対してハンドラはバインドされませんでした。liveを使うことで動的に作った要素に対してもハンドラを呼び出すことができます。

HTML

<ul id="hoge1">bind("click", ハンドラ)
 <li>ここは一回だけ押す</li>
</ul>
<ul id="hoge2">live("click", ハンドラ)
 <li>ここは一回だけ押す</li>
</ul>
<ul id="hoge3">click(ハンドラ)
 <li>ここは一回だけ押す</li>
</ul>

スクリプト

// イベントハンドラ。動的にli要素を追加する。
var handler = function() {
 $(this).after('<li class="nc">ここをクリックして</li>');
}
$(function() {
 $("li", "#hoge1").bind("click", handler);
 $("li", "#hoge2").live("click", handler);
 $("li", "#hoge3").click(handler);
});

demo :

    bind("click", ハンドラ)
  • ここは一回だけ押す
    live("click", ハンドラ)
  • ここは一回だけ押す
    click(ハンドラ)
  • ここは一回だけ押す




liveを使うことで、動的に追加されたli要素に対して、自動的にイベントハンドラを
バインドしてくれます。
ちなみに、click()はbindのショートカットなので、bind('click', ハンドラ)と同じ動きをします。

2011/02/23

テキストボックスのデフォルト値を付けたり/消したりする(jQuery)

以前、テキストボックスのデフォルト値を付けたり/消したりするというネタを書きましたが、実装が雑だった(イベントのバインド方法とか)ので、jQueryで書き直してみました。

demo :


以前に比べるとjQueryっぽいソースになった気がします。
(今回はフラグをみないで、ただバインド/アンバインドをしているので、ロジックは少し変わっています。)

こんな感じのHTMLを用意しておいて…

<input type="text" name="input2" id="input2" value="" />


こんな感じのスクリプトを書いてやります。

// jQuery版
var defaultMsg = "何か入れてください";
$(function() {
 $("#input2").val(defaultMsg)
  .focus(function() {
   ($(this).val() == defaultMsg) && $(this).css("css", "#000000").val("");
  })
  .blur(function() {
   ($(this).val() == "") && $(this).css("css", "#696969").val(defaultMsg); 
  })
});

やっぱりjQueryで書くとスッキリしますね!

2011/01/23

世界の車窓から.js

昨日、世界の車窓からを見てて、かなり良い曲が流れていた。
The Shores of the Swilly』 by.Phil Coulterって曲です。


世界の車窓からっていつも良い曲を使ってる気がしたので、そんな曲をすぐに調べれるように
「世界の車窓から」を見ながら一覧表を作りました。


Demo:
http://shinya-api.appspot.com/sandbox/shasou.html

shasou.js:
/**
  * created_atの日付がよくわからんことになってるので、
  * とりあえずこれはつかわない。
  */
//   function makeEtc(e) {
//    var date = e.created_at.split(" ");
//    console.dir(date);
//    return date[2] + "日 " + date[3];
//   }
/**
  * その他項目を作る
  */
function getMusicNm(al) {
 var i;
 var buffer = "";
 for (i = 4; i < al.length; i++) {
  buffer += al[i];
 }
 return buffer;
}

/**
  * テーブルに表示する内容
  * いつも決まったフォーマットで呟かれないのが難点
  */
function shasouParser(elem) {
 var al = elem.text.split(" ");
 if (al.length < 5) {
  //return makeEtc(elem);
  return "----";
 } else {
  return "
" + al[0] + " "+ al[1] + "放送" + al[2] + "" + al[3] + "" + getMusicNm(al) + "";
 }
}

/**
  * JSON取得
  */
$(function() {
  $.getJSON("http://api.twitter.com/1/statuses/user_timeline/Sekai_no_Shasou.json?callback=?", function(d) {
   var i;
   var appendStr = "";   var table = document.getElementById("ta");   for (i = 0; i < d.length; i++) {
    var elem = d[i];
      appendStr += shasouParser(elem);
   }
   appendStr += "
"; table.innerHTML =appendStr; }, "json"); });
こんな感じのスクリプトを、以下のようなHMTLで呼んでやる。 hoge.html:

<script type="text/javascript" src="http://ajax.googleapis.com/ajax/libs/jquery/1.4.4/jquery.js"></script>
<style>
 body {
  background-color: #696969;
 }
 table { 
  width: 100%;
  border-collapse: collapse;
 } 
 table td { 
  border: 1px #4cdd09 solid;
 } 
</style>
<h1>世界の車窓から</h1>
<table>
 <thead>
  <tr>
   <td>放送</td>
   <td>シリーズ名</td>
   <td>タイトル</td>
   <td>その他</td>
  </tr>
 </thead>
 <tbody id="ta">
 </tbody>
</table>
<script type="text/javascript" src="shasou.js"></script>


やぱjQueryだと作業効率良い良い(^ω^)
車窓、いいよ車窓♪

2011/01/14

jQueryプラグインの中に出てくるセミコロン「;」

jQueryプラグイン
jQueryプラグインのソースを読んでいると、無名関数の先頭にセミコロン「;」を付けているのを見かけたりします。
たとえば、fancyboxとかがそうです。

;(function($){
      ..etc
    })(jQuery);

jQueryの$関数みたいなものかな?と思いつつ、JSLintとかで文法チェックするとエラーになりますよ。
ただ、なんとなく予想はついていたので、ググってみると英語のフォーラムに書いてありました。
http://markmail.org/message/3gppon7hfmw7jqr7

ざっくり書くと、「セミコロンが先頭にあるプラグインを読み込む前に、セミコロンがちゃんと書かれていないコードがあるとバグッちゃうからつけといたよ!」ということですね。

jsでのセミコロン
jsではセミコロンの自動補完という謎の機能があるため、こんな感じの残念なソースがあります。
var hoge = "hoge";
    console.log(hoge)
この例だと、logメソッドの末尾にセミコロンがありません。
イミフwwwうはwwwwおkwwww
ただ、自動でセミコロンが補完されるので「動くことは動きます」。
var hoge = "hoge";
    console.log(hoge)
    var moge = "moge";
    console.log(moge);

ただし、こんな場合はエラーになります。

圧縮ツールとかにかけた場合
var hoge = "hoge";console.log(hoge)var moge = "moge";console.log(moge);
改行が削除されてエラーになります。

無名関数の場合
var hoge = "hoge";
console.log(hoge)
(function() {
var moge = "moge";
console.log(moge);
})();
とかそんな感じ。


なぜ文頭にセミコロンをつけるのか
文末にセミコロンをつけないソースの後ろにコピペしたpluginのソースを貼った場合(もしくはソースをYUI Compressorとかのツールで圧縮した場合)は、無駄な改行が消されて、一行のソースになったりします。
こういう場合に、直前の文でセミコロンがなくても、問題が起きないように文頭にセミコロンを付けています。
var hoge = "hoge";console.log(hoge);;(function() {var moge = "moge";console.log(moge);})();


文末にセミコロンはちゃんと付けましょう。ってことですね。

2010/09/15

jQueryのfilterとfindの違い

jQueryで要素を対象要素を絞ろうと思ったときに限って、idで抜き出すのが難しかったりする。
そんなとき便利なのが、findメソッドとfilterメソッド。
けど、この2つは一見非常に良く似ている。ここに違いをメモしておく。

次のようなHTMLがあったとします。

<div>hgoe1</div>

<div>hgoe2</div>

<div>hgoe3</div>

<div class="hoge">hgoe4</div>

<div>
    <span class="hoge">hgoe5</span>
</div>



そこからfilterメソッドとfindメソッドでそれぞれ要素を抽出し、
抽出された要素からclass="hoge"のものを抜き出して処理を行います。

$(function() {
    // filterメソッド
    $('div').filter(function (index) {
        return $(this).hasClass('hoge');
    })
    .css("background-color", "blue");

    // findメソッド。
    $('div').find('.hoge').css("background-color", "red");
});


上記のjsを適用すると次のようになる。

・青枠の要素が、$('div').filterメソッドで絞り込んだ要素。
div要素の中からclass="hoge"の要素を返す。

・緑枠の要素が、$('div').findメソッドで絞り込んだ要素。
divの子要素からclass="hoge"の要素を返す。

<div>hgoe1</div>
<div>hgoe2</div>
<div>hgoe3</div>
<div class="hoge">hgoe4</div>
<div><span class="hoge">hgoe5</span></div>


ちなみに、jQueryオブジェクトはDOM要素の集合をスタックで持っています。
多くのjQueryメソッドは、呼び出し時の状態をスタックに保存した上でDOM操作を行います。

使いどころさえ間違わなければ、とても便利に使えそうだ。