ウェブインコ

インコの技術メモ

JavaScript, jQuery

■オブジェクト(連想配列も)の参照が不安定な時
オブジェクトは参照渡し、文字等は値渡し、という特徴から、いったん JSON にす。
function hoge(){
    ~何かしらの処理~
    return JSON.stringify(obj);
}
var funa = JSON.parse(hoge());

■連想配列 ← JSON
var obj = JSON.parse(jsontext);

■JSON ← 連想配列
var jsontext = JSON.stringify(obj);

■数字に
parseInt(hoge, 10);
hoge - 0
(下は続けて計算するときにしくるときがあるような)

■配列←→csv
hoge_array = hoge.split(",");
hoge = hoge_array.join(',')

■ループ
for(var i = 0 ; i < hoge_array.length ; i++ ){hoge_array[i]}
for(var i in hoge_array){hoge_array[i]}
for(var key in hoge_hash){hoge_hash[key]}

■配列に値が含まれているか
あれば、添え字(0 ~)が返ってきます。
無い場合は false ではなく -1 が返ってくるので注意。
var isNew = ['Brand New', 'New', 'New with box', 'New with tags'];
var condition = 'New';
if(isNew.indexOf(condition) >= 0){
    console.log("---- あり ----"); // この場合こちら (= 1)
}else{
    console.log("---- なし ----");
}

■連想配列のキーの階層を動的に増やしたい
代入したい左辺の場合は文字列作って eval() で評価です。
  var obj_001 = {"skills":[99,"149"]};
  var keys = ['skills', 1];
  var str2 = '';
  for(k in keys){
    str2 += "['" + keys[k] + "']";
  }
  str2 = 'obj_001' + str2;
  eval(str2 + "='ヘ(-。-)ノ'");

取得する場合は自分自身に代入するだけ。
  var obj_002 = obj_001;
  for(k in keys){
    obj_002 = obj_002[keys[k]];
  }
  console.log(obj_002);

■動的なものを中央に表示する一例。
画面内の要素を計ってからセットし直すという発想。
  $(document).ready(function(){
    $('#hena').css('width', ($('#funa').width() + 1)); // +1 線幅や隙間があればその分をプラス
  })
  </head><body>
    <div id="hena" style="margin: 0 auto;">
      <span id="funa">ヘ(-。-)ノ</span>
    </div>

■ハッシュの要素数
Object.keys(hoge_hash).length

■ハッシュをキーでソートする関数(ハッシュの配列ではない)
{"hoge":"warosu","hage":"warota","fuga":"warorisshu"} ← こっち
[{"hoge":"warosu"},{"hage":"warota"},{"fuga":"warorisshu"}] ← x
function sortHash(hash){
  var keys=[]; for(var k in hash){keys.push(k);}
  keys.sort();
  var res={}; for(var k in keys){res[keys[k]] = hash[keys[k]];}
  return res;
}
hogeHash = sortHash(hogeHash );

■ 配列を統合して重複があるか
var screen_ids=data.no_allauth.concat();
_.forEach(data.html, function(row){screen_ids.push(row.id);});
var overlap = screen_ids.filter(function(x, i, self){return self.indexOf(x) !== self.lastIndexOf(x);});
if(overlap.length){?}

■カンマを付ける
var ssss= 1234;
var cccc = String(ssss).replace(/(\d)(?=(\d\d\d)+(?!\d))/g,'$1,');

■カンマを取る
var ccc = '1,234';
var sss= ccc.split(",").join("");
無駄なスペースも取って数字に
var sss= parseInt(ccc.split(',').join('').trim(),10);
var sss= strPcccrice.split(',').join('').trim()-0;

■セレクタ
タグで指定
$('div')

idで指定。1番メジャー。
$('#idname')

classで指定。2番目にメジャー。
$('.classname')

input タグの name で指定。
$('input[name="data[User][id]"]')

絞り込み。だいたいCSSと同じ。
$('#idname .classname')

■イベントトリガー
クリック
$('#hoge').click(function(){
});
値が変わった
$('#hoge').bind("change",function(){
});

■後から追加したものにも反応させたい
$(document).on('click', '#blocA', function(){
alert('AAAAA');
});
document のところは親セレクタでも良いです。
親セレクタの中の子供は後から追加されても反応することができます。
親セレクタを document にしていれば全部なめます。
要素が多くなければ document で良いです。
解除は以下です。使うことはあまりないです。
$(document).off('click', '#blocA');

■イベント時に引数を渡すことができます。
$(document).on('click', '#blocA', [{wwww1:'wwww1', wwww2:'wwww2'},{eeee1:'eeee1'}],function(event){
console.log(event.data[0].wwww2);
});
◆分けて書くときの方が使い道が多そうですね
function myHandler(event) {
console.log(event.data[0].wwww2);
}
$(document).on('click', '#blocA', [{wwww1:'wwww1', wwww2:'wwww2'},{eeee1:'eeee1'}],myHandler);
■子共を指定していなくて引数の数が足りなくてもよしなに判断してくれます。(下の場合はどこをクリックしても反応します)
$(document).on('click', [{wwww1:'wwww1', wwww2:'wwww2'},{eeee1:'eeee1'}],function(event){
console.log(event.data[0].wwww2);
});


■選択されている値。
ラジオ、チェックボックスの単体、セレクトボックス。
セレクトボックス複数の場合は配列。
var www = $('[name="UserId"]').val();

チェックボックス複数はセレクトボックスみたいに配列で返すことは無いから以下。配列。
var www = $('[name="UserId"]:checked').map(function(index, checkbox) {
return $(this).val();
});

■選択させる。ex.1を選択させる。
ラジオ、チェックボックス、セレクトボックス複数。配列。
$('[name="UserId"]').val(['1']);
セレクトボックス単体。
$('[name="UserId"]').val('1');

■クリックしたときのイベント
<input type="button" value="戻る" onclick="history.back()">

■リンクを無効
<a href="javascript:void(0)">LINK</a>

■宣言
HTML5
<script>
$(function(){
});
</script>
それ以前
<script type="text/javascript">//<![CDATA[
$(function(){
});
//]]></script>

■CakePHPのフォーム内容をjqueryのajax用に加工する例
var formdata = {};
$('input').each(function(){
  var thisName = $(this).attr('name');
  if((thisName)&&(thisName.match(/data/))){
    if($(this).attr('type')=='radio'){
      formdata[thisName] = $("[name='"+thisName+"']:checked").val();
    }else{
      formdata[thisName] = $(this).val();
    }
  }
});
$.ajax({
  type: "POST",
  url: "/hoge/",
  data: formdata,
?

■配列→文字列
function a2s(a){
  var result = "(";
  if (a instanceof Array){
    for (var k=0; k<a.length; k++){
      if( typeof a[k] == 'object' ){
        result = result + a2s(a[k])+" ";
      }else{
        result = result + "\""+a[k]+"\" ";
      }
    }
  }else{
    for (var k in a){
      if( typeof a[k] == 'object' ){
        result = result + ":"+k+" "+a2s(a[k])+" ";
      }else{
        result = result + ":"+k+" \""+a[k]+"\" ";
      }
    }
  }
  result = result + ")";
  return result;
}
ちぢめるとこんな感じ。
function a2s(a){var result="(";if(a instanceof Array){for(var k=0; k<a.length; k++){if(typeof a[k]=='object'){result=result+a2s(a[k])+" ";}else{result=result+"\""+a[k]+"\" ";}}}else{for(var k in a){if(typeof a[k]=='object'){result=result+":"+k+" "+a2s(a[k])+" ";}else{result=result+":"+k+" \""+a[k]+"\" ";}}}result=result+")";return result;}
使い方
alert(a2s(arrayhoge));

■チェックされたチェックボックスの値を取る
var checks=[];
$("[name='data[fav]']:checked").each(function(){
  checks.push(this.value);
});

■チェックボックス全部オフオンで2回目以降動かなくなる
例)
attr ではなく prop を使う。
.js
  // オーダーのチェックボックス
  $("#fav_toggle").click(function() {
    if(this.checked){
      $('.fav').prop('checked', true);
    } else {
      $('.fav').prop('checked', false);
    }
  });
.hmtl
<div class="input checkbox"><input name="data[fav]" id="fav_000143_" value="0" type="hidden"><input name="data[fav]" value="000143" id="fav_000143" class="fav" type="checkbox"></div>
<div class="input checkbox"><input name="data[fav]" id="fav_000142_" value="0" type="hidden"><input name="data[fav]" value="000142" id="fav_000142" class="fav" type="checkbox"></div>
<input id="fav_toggle" type="checkbox"><label for="fav_toggle" style="font-size: 12px;">すべてチェック</label>

■メニューをロールアウトさせない例
.js
$(function(){
  var nav = $('.globalMenu');
  //navの位置  
  var navTop = nav.offset().top;
  //スクロールするたびに実行
  $(window).scroll(function () {
    var winTop = $(this).scrollTop();
    //スクロール位置がnavの位置より下だったらクラスfixedを追加
    if (winTop >= navTop) {
      nav.addClass('fixed')
    } else if (winTop <= navTop) {
      nav.removeClass('fixed')
    }
  });
});
.css
.fixed {
    position: fixed;
    top: 0;
    left: 20px;
    width: 100%;
}

■ハッシュが空かどうか
if(Object.keys(hashArray).length > 0){ほにゃらら}

■配列が空かどうか
if(Array.length > 0){ほにゃらら}

■IEでajaxをキャッシュしてしまう
以下を $.ajax({ の前に書き足してください。
$.ajaxSetup({ cache: false });

■aタグ href をpostで送信したいとき
<script type='text/javascript'>
$(document).ready(function(){
  $('#hoge a').click(function(){
    var form = $('<form></form>',{action:$(this).attr('href'),method:'POST'}).hide();
    var body = $('body');
    body.append(form);
    form.append($('<input>',{type:'hidden',name:'hogeid',value:'1'}));
    form.submit();
    return false;
  });
});
別ウインドウにしたいときにはこれ。
var form = $('<form></form>',{action:$(this).attr('href'),target:'receiver',method:'POST'}).hide();

■formがネストしてしまいたいときなどにも
1つ上のソースと同じです。idをaタグに書くかsubmit他に書くかぐらい。
<script type='text/javascript'>
$(document).ready(function(){
  $('#hoge').click(function(){
    var form = $('<form></form>',{action:'/url/hoge.php',method:'POST'}).hide();
    var body = $('body');
    body.append(form);
    form.append($('<input>',{type:'hidden',name:'hogeid',value:'1'}));
    form.submit();
    return false;
  });
});

■PHPで動的に画像を出力するタグをJavaScriptで動的に出力
ツボにハマッた。
imsに埋め込んだPHPに入力内容を引数にして渡してQRコードを返してもらうというもの。
何故だかIE6で画像が表示されないというのでツボにハマりました。
現象
 ・imgタグをJavaScriptで書き換えたがIE6で表示されない。
 ・右クリックして「画像を表示」とすると表示される。
解決方法
 ・ボタンをaタグからinputのimageに変える。
マウスオーバー等を他のところと共通で使いたかったので、aタグをトリガーにしていたのだけれど、それがダメだった見たい。imputタグのボタンや画像にしたら表示されました。原因は不明。

■jQuery
とても便利だと思うんだ。
jQuery日本語リファレンス
http://semooh.jp/jquery/
jQueryの魔法
http://allabout.co.jp/internet/javascript/closeup/CU20071020A/

■画面中央の座標
var cgw=300; //表示したいCG等の横幅
var cgh=400; //表示したいCG等の高さ
s_width = document.body.clientWidth || document.documentElement.clientWidth; // 横幅
s_nowHeight = document.documentElement.clientHeight; // 現在表示している画面の高さ
s_height = document.body.clientHeight || document.body.scrollHeight; // 画面の高さ
s_x = document.body.scrollLeft || document.documentElement.scrollLeft; // 横の移動量
s_y = document.body.scrollTop || document.documentElement.scrollTop; // 縦の移動量
var gostLeft = (s_width/2) - cgw/2; // 画面中央のx軸
var gostHeight = (s_nowHeight/2 + s_y) - cgh/2; // 画面中央のy軸
if (gostLeft < 0){gostLeft =0;}
if (gostHeight < 0){gostHeight=0;}

■JavaScriptを使ってaタグからformの送信
CSSで組んだaタグの効果を生かしたいときなどに。
<form action="account.cgi" method="post" name="inputform">
?
<input type="submit" value="確  認">

<a href="#" onclick="document.inputform.submit()">確  認</a>
</form>
document.と.submit()の間にformのnameを入れる。

■ 実行されるタイミング。
◆ HTML が読み込まれる前に実行してしまい幅が取得できない。
<script>
    console.log($('div').width());
</script>
</head>
<body>
  <span>ヘ(-。-)ノ</span>
</body>
</html>

null

◆ HTML が読み終わってから実行するよう明示されているので幅が取得できる。
<script>
$(document).ready(function(){
    console.log($('div').width());
});
</script>
</head>
<body>
  <span>ヘ(-。-)ノ</span>
</body>
</html>

47

◆ 取得対象の HTML の後に書かれているので取得できる。
<body>
  <span>ヘ(-。-)ノ</span>
  <script>
      console.log($('div').width());
  </script>
</body>
</html>

47

というわけで、jQuery のトリガーは $(document).ready(function(){ ほにゃらら }); の中に書くこと。
画像まで全部読み終わってから実行したいときには $(window).load(function(){ ほにゃらら }); です。