日々のアンテナ

日々アンテナを貼って、いろんな情報をキャッチ、発信したいと思います。
2017年10月 ≪  123456789101112131415161718192021222324252627282930 ≫ 2017年12月
TOP ≫ CATEGORY ≫ javascript
CATEGORY ≫ javascript
      

検索中に「検索中」の文字を点滅させる

データ取得中に「取得中」だとか「検索中」の文字を点滅させたい場合の処理です。

function blink() {
  obj = document.getElementById("srchBlink");
  obj.innerHTML = "検索中";
  if("visible" == obj.style.visibility) {
    obj.style.visibility = "hidden";
  } else {
    obj.style.visibility = "visible";
  }
  setTimeout("blink()", 600);
}


点滅させたいところに<div id="srchBlink"></div>と空のブロックを作っておきます。
(空が嫌なときは空白スペースでも入れといてください。)

単純にstyleのvisibilityをhiddenとvisibleを繰り返すだけ。
setTimeoutの第二引数を小さい値にすればチカチカ度が増します^^

単純だけど、読み込み中とか結構使う場面が多い小技ですよね。

Windows Vista文字化け対策

Javascriptとは直接関係ありませんが、先日発売され話題のWindows Vista。 対応に追われている方も多いのではないのでしょうか? Windows Vista は、従来OS(Windows XP等)とはフォントデザインを変更し、JIS X 0213:2004の字形を採用しています。 字形の変更によって、様々な問題が生じる可能性があります。 Windows Vistaで入力した文字を従来のOS(XPなど)で表示させると、フォントデザインの変更だけでなく、文字化けする文字が出てきます。 字形が変更される文字には、姓名や地名によく使われている文字が多くあります。 なにも対策を施さないと、フォントデザインの違いや追加文字により、混乱が生じる恐れがあります。 Windows Vistaで採用されるJIS X 0213:2004 では、JIS X 0208:1990 にない文字が追加されています。(JIS第3・4水準文字セット) その追加された文字を、従来OS(Windows XP等)では認識できないため、文字化けを引き起こします。パソコンの画面上で表示されない、プリンタで印刷できない、などの問題が発生します。 また、サーバなどでも追加文字が認識されないため、想定外のシステムエラーが起こる可能性もあります。

form部品は数によって処理を分岐する

チェックボックスのチェックされている数を数えたり、テキストボックスの入力チェックをしたりとform elementの入力チェックではJavascriptを良く使います。 そして、JSPなどで行を自動生成するパターンだと、同名の部品数が可変になったりして、チェックはさらにややこしくなります。 たとえば、
あいうえお
こんな表があるとします。 でも
あいうえお
かきくけこ
になる可能性もあります。可変だからです。 <form name="myform"> <table> <tbody> <tr><td><input type="checkbox" name="check0">あいうえお</td></tr> <tr><td><input type="checkbox" name="check1">かきくけこ</td></tr> </tbody> </table> </form> チェックされている個数を調べるのに function checkCnt(){  var count = 0;  var obj = document.myform;  var len = obj.elements.length;  for(var i = 0; i < len; i++){   if(obj.elements["check" + i].checked){    count++;   }  } } なんてやりたくなりますよね? でもこれは使えません。なぜなら、form部品のlengthは1個のときは取得できないからです。 なので、今回はform.elements.lengthにしましたが、1個である場合と、それ以上ある場合の場合わけが必要になります。 上の例だと function checkCnt(){  var count = 0;  var obj = document.myform;  var len = obj.elements.length;  if(len > 1){   for(var i = 0; i < len; i++){    if(obj.elements["check" + i].checked){     count++;    }   }  }else{   if(obj.elements["check" + 0].checked){    count++;   }  } } こんな風にlengthが1より大きいかどうかで判断します。 (もしくはif(len){というように存在するかどうかで判断。) if(len== 1){ なんて風にはできません。 チェックボックスの名前がたとえばすべて同じだった場合も同様に場合わけが必要です。 function checkCnt(){  var count = 0;  var obj = document.myform;  var len = obj.check.length;  if(len > 1){   for(var i = 0; i < len; i++){    if(obj.elements["check"][i].checked){     count++;    }   }  }else{   if(obj.elements["check"].checked){    count++;   }  } } 同名のelementの場合 form名.element名[何番目]でアクセスできますが、これは2個以上ある場合のみで、1個の場合はform名.element名でしかアクセスできません。 一個でもform名.element名[0]ってついやりたくなっちゃいますよね~。

javascript デバッガ

javascriptのデバッグってどうしてますか? そんなに複雑なプログラムを組むわけじゃないのでalertでいちいち変数を表示するという方法でもあまり困らないと思うのですが、DOMだったりAjaxにtryし始めるとやっぱりデバッガがほしいなあと思います。 もともとFireFoxのプラグインである、Venkmanを使用していました。 Venkman早わかりを読めばたいていわかると思いますが、ステップ実行、変数の値をウォッチなど、たいていの機能が盛り込まれ、eclipseなどに慣れた方にはユーザーインターフェイスも使い勝手がよくできています。 homepageおよびダウンロード 新しく試してみたのが同じくFireFoxのプラグインであるFirebug。 機能はVenkmanとほぼ同じですが、シンプルなインターフェースでとても見やすいです。 こちらのほうがより直感的な気がします。DOMを扱うなら絶対これお勧めです。 homepageおよびダウンロード ぜひ試してみてくださいね。

IEでのgetAttribute,setAttributeのバグ

DOMでオブジェクトを特定したり、変更するのに使用するgetAttribute、setAttributeメソッドですが、一部IEにバグがあります。 以前散々悩んだので書いておきます。 たとえば、class名を取得したいとき、 element.getAttribute("class");だと、IEでは取得できません。 IEの場合には
element.getAttribute("className");
getAttribute("String")のStringには属性名がくるので、実際にはclassが正しいのですがIEのバグです・・・ また、同様に element.setAttribute("style", "color: #ffffff;");もIEではセットできないので、
element.style.cssText = "color: #ffffff;";
とする必要があります。 さらに、onclick属性に対しても element.setAttribute("onclick", "newHandler();");ではセットされずに、newHandler()が呼ばれません。
element.setAttribute("onclick",new Function("newHandler();"));
とする必要があります。 もう、これに気づくまでなかなか大変でした。 と思ったら、 http://nanto.asablo.jp/blog/2005/10/29/123294がとても参考になります。

Javascriptでtry-catchを使う

Javascriptでtry-catch構文が使えるって知らない人が多かったので書いてみました。 (最近じゃAjaxでほぼ必須だから認知度高いかもしれないけど。)
try{エラーをキャッチしたい処理内容}catch(e){エラーをキャッチしたら行う処理内容}
プログラミング言語に慣れている方はすんなり受け入れられると思いますが、どんなプログラムでもこの例外処理が大変重要です。 Javascriptではそんなに厳しく例外処理をする必要ないかもしれないけど、使ったら便利ってことがよくあります。 それは、ブラウザが返却するエラーをキャッチすることです。 IEではよくあるのですが、windowのリサイズや移動、またはファイルのアップロード時など、セキュリティ上の都合で、ブラウザからエラーが返されてしまいます。 そうするとその後の一切の処理ができなくなり大変都合が悪いです。 なので、このブラウザから返されるエラーをキャッチし、つぶすなり、他の処理に置き換えるなりする必要があります。 例:windowのリサイズや移動を行う。 リサイズ時にユーザーがウインドウを触ったりすると 「アクセスが拒否されました」のアラートが上がることがあります。 エラーの詳細はMicrosoftサポート情報 これは特に重要なエラーではないので、潰したいという場合。 try{   window.top.resizeTo(w,h);   window.top.moveTo(x,y); }catch(e){   //アクセスが拒否されましたのエラーが出たら何もしない。   if(e.number == 2147024891){     throw e;   } } 再度リサイズや移動を行うにはそれなりの処理が必要です。 アクセスが拒否されましたのエラーナンバーは上記の通りなので、 これ以外のエラーだった場合はエラーが返されますので安心です。 (全てを潰すのはセキュリティ上よくない。) このほか、ファイルのアップロードしたいときに、 相対パスや存在しないようなファイル名を入力してsubmitすると、無反応だったり「アクセスが拒否されました」となりその後の処理が不可能になることがあります。 詳細はMicrosoftサポート情報 エラー自体はセキュリティ上しょうがないとしても、リカバリできないのは困ります。 なのでこれもエラーをキャッチし、自分でエラーを返すことで処理の続行が可能となります。 try{   document.myform.submit(); } catch (e) {   alert('存在しないファイルが指定されました。'); } 他にもデバッグ代わりにつかったり、知っておくと便利なtry-catchでした。

form部品の初期値を取得する

たとえばテキストボックスの値を変更した場合のみ入力チェックを行うとか、初期値と比較して処理を行うことって多いと思います。 初期値を取得するには、default○○を使います。 Form部品の種類によって使えるプロパティが違います。
input type="text",textareaの場合 defaultValue optionの場合 defaultSelected input type="checkbox"の場合 defaultChecked
例:もしテキストボックスの初期値から変更があった場合はアラートを表示する。 var obj = document.myform.mytext; if(obj.value != obj.defaultValue){  alert("変更されました。"); } これ、一個や二個ならいいのですが、たとえばformのelements全てに対して初期値から変更があったかどうかをチェックするには、下のような方法が便利だと思います。 function initValue(target){  var childs = target.childNodes;  var flg = false;  if(childs.length != 0){   for(var i=0;i&lt;childs.length;i++){    if(childs(i).tagName == "INPUT" && childs(i).getAttribute("type") == "text"){     if(childs(i).value != childs(i).defaultValue){     flg = true;     }    }    if(childs(i).tagName == "TEXTAREA"){     if(childs(i).value != childs(i).defaultValue){     flg = true;     }    }    if(childs(i).tagName == "OPTION"){     if(childs(i).selected != childs(i).defaultSelected){     flg = true;     }    }    if(childs(i).tagName == "INPUT" && childs(i).getAttribute("type") == "checkbox"){     if(childs(i).checked != childs(i).defaultChecked){     flg = true;     }    }    var nextChilds = childs(i).childNodes;    if(nextChilds.length != 0){     initValue(childs(i));    }   }  } return flg; } 引数のtargetには対象となるformを指定します。 webアプリだとやたらと大量のform部品を生成することが良くあります。 この方法、初期値との比較以外にも全てのform部品にアクセスしたいときによく使っています。 もっと良い方法があれば教えてくださいね。

Javascriptでオーバーロードを実現する

JavaをやっていてJavascriptを触ったりすると非常にごちゃごちゃになります。 よくやるのが for(int i = 0;・・・ という風に、intなんて思わず使っちゃったり。 これは置いておいて、JavascriptではJavaでいうオーバーロード(引数の数や型が異なるメソッドを宣言すること)ができません。 fooというメソッドがあった場合、Javaなら foo(String str,int i)と foo(String str) foo(int i,int j)が宣言することができ、引数の型や数でメソッドが自動的に選択されます。 ところが、Javascriptにはそもそも変数の型がないし、メソッドはプロパティに関数オブジェクトが代入されているだけなので、同名のメソッドを作ることができないのです。 でも、プログラムを組んでいて、引数を増やしたくなることってありますよね? フラグをつけたいなあと思ったりすることってあります。 その場合にいままで書いた分全部に新たな引数を加えるなんてすごくイヤです。 というわけで、Javascriptでオーバーロードの真似事を実現するには、 argumentsオブジェクトのlengthによって場合分けをします。
arguments.length
argumentsオブジェクトは引数を表すオブジェクトです。 配列と同じようにlengthが取得できます。 例: function test(arg1,arg2){  switch (arguments.length) {  case 1: test1(arg1);  case 2: test2(arg1,arg2);  default

配列を数字順にソートする。

Array.sort()って、文字コード順に並び替えをします。 だから例えば myArray = new Array("1","2","11"); とすると、 myArray.sort(); 結果: 1,11,2になってしまいます。 これを数字順にするにはソートの引数に比較関数をセットします。
Array.sort(比較関数);
でも比較関数って何?って思いますよね。 比較関数とは2つの引数を持ち、 引数1が引数2より小さい場合は負の整数、 同じ場合は0、 引数1が引数2より大きい場合は正の整数を返します。 なので、この場合比較関数は function func(a,b){  return (b - a)

配列からある要素を削除する

JavascriptでArray.deleteって探してもないので、ちょっと途方にくれちゃうけど、 spliceを使えば簡単に配列から要素を削除できます。 (置換するメソッドを削除に使うなんて最初はなかなか気づきにくいですよね。)
Array.splice(開始番号,削除する要素数);
例: myArray = new Array("red", "green", "blue", "yellow"); myArray.splice(1,2); 結果: red,yellow 注意: インデックス番号は0からです。 応用: この中でgreenだけを削除したい場合
myArray = new Array("red", "green", "blue", "yellow");
for(i = 0; i < myArray.length; i++){
 if(myArray[i] == "green"){
  myArray.splice(i,1);
 }
}
で、結果はred,lue,yellowの配列になります。 2008/02/19追記: ただし上記の方法ですとgreenが二個あった場合に削除されずに残ってしまいます。 コメントでkenさんの記載してくださった方法を参照してくださいね。 http://javascript-memo.seesaa.net/article/24832361.html#comment